Nuxt.js
This guide walks you through setting up, running, and understanding how AB Tasty’s Flagship SDK integrates into a modern ecommerce experience built with Nuxt and Vue.
You’ll learn how server-side and client-side feature evaluation work together to deliver a fast, flicker-free experience. Each section includes code examples and explanations to help you understand the logic behind the implementation.
Features Overview
This demo shows you how to use Flagship feature flags pre-rendered on the server and synchronised on the client.
Getting Started
Follow these steps to install and run the project locally.
Start the development server
Launch your local server using:
npm run devOnce started, open http://localhost:3000 in your browser.
Environment Setup
Before running the project, create a local .env file.
This file is ignored by Git and should include your Flagship environment credentials.
NUXT_FLAGSHIP_ENV_ID=your-flagship-environment-id
NUXT_FLAGSHIP_API_KEY=your-flagship-api-keyIntegrating AB Tasty’s Feature Flagging
In this section, you’ll integrate AB Tasty’s Flagship SDK to control the “Apple Pay” quick checkout button on product pages. This flag will let you toggle the Apple Pay feature on or off dynamically, without code redeployment.
The process is divided into two layers: server-side evaluation and client-side confirmation.
Server-Side Evaluation (SSR)
On the server, Nuxt renders pages using data fetched from the /api/features/apple-pay endpoint.
Here’s what happens:
The endpoint starts the Flagship SDK.
It derives a visitor ID from cookies (or creates one if needed).
It fetches the
paymentFeature1Clickflag.It returns
{ enabled: boolean }which Nuxt uses during SSR.
Because this happens before the response is sent, your rendered HTML already reflects the correct Apple Pay state. There’s no UI flash or delay.
Client-Side Confirmation
Once the page is hydrated on the client:
The browser reinitialises the Flagship SDK using
initializeFlagshipfromutils/flagship/index.ts.It uses the same visitor context and fetches the latest flag values.
If a flag changes mid-session, the reactive state updates automatically. Otherwise, it stays in sync with the SSR-rendered version.
This dual-phase approach ensures consistency between server and client and avoids flickering or misaligned states.
How the SSR and Client Helpers Work Together
server/utils/flagship/index.ts
Starts the Flagship SDK on the server, manages credentials, and fetches flags.
utils/flagship/index.ts
Handles the client-side SDK initialisation and revalidation.
pages/products/[slug].vue
Fetches the flag via SSR and revalidates it on the client.
Server Flagship Bootstrap (server/utils/flagship/index.ts)
server/utils/flagship/index.ts)This file initialises the Flagship SDK for the server. Review the full implementation below:
import { Flagship, LogLevel, Visitor } from '@flagship.io/js-sdk'
import { useRuntimeConfig } from '#imports'
import { createError } from 'h3'
import { flagshipLogManager } from '@/utils/flagship/logManager'
import { flagshipLogStore } from '@/utils/flagship/logStore'
type InitializeFlagshipOptions = {
visitorId: string
context?: Record<string, string | number | boolean>
authenticated?: boolean
}
let flagshipStarted = false
const ensureFlagshipStarted = () => {
if (flagshipStarted) return
const config = useRuntimeConfig()
const flagshipConfig = (config.flagship ?? {}) as { envId?: string; apiKey?: string }
const publicFlagship = (config.public?.flagship ?? {}) as { envId?: string; apiKey?: string }
const envId = flagshipConfig.envId || publicFlagship.envId
const apiKey = flagshipConfig.apiKey || publicFlagship.apiKey
if (!envId || !apiKey) {
throw createError({
statusCode: 500,
statusMessage: 'Flagship credentials are missing. Please configure runtimeConfig.flagship.'
})
}
Flagship.start(envId, apiKey, {
fetchNow: false,
logManager: flagshipLogManager,
logLevel: LogLevel.ALL
})
flagshipStarted = true
}
export const initializeFlagship = async ({
visitorId,
context = {},
authenticated = false
}: InitializeFlagshipOptions): Promise<Visitor> => {
if (!visitorId) {
throw createError({ statusCode: 400, statusMessage: 'A visitorId is required to initialize Flagship.' })
}
ensureFlagshipStarted()
const visitor = Flagship.newVisitor({
visitorId,
hasConsented: true,
context,
isAuthenticated: authenticated
})
await visitor.fetchFlags()
return visitor
}
export { flagshipLogStore }If credentials are missing, this setup throws a createError(500) with a clear message so Nuxt surfaces a proper error.
Using the Helper on the Product Page (pages/products/[slug].vue)
pages/products/[slug].vue)Next, use the helper in your product page to evaluate and react to feature flags.
import { initializeFlagship } from '@/utils/flagship'
import { flagshipLogStore } from '@/utils/flagship/logStore'
// SSR hands us the initial decision via /api/features/apple-pay.
const applePayEnabled = ref(Boolean(applePayFeature.value?.enabled))
const runFlagship = async () => {
const visitor = await initializeFlagship({
visitorId: route.params.slug ? `visitor-${route.params.slug}` : 'guest',
context: { status: 'returning' }
})
const flag = visitor.getFlag('paymentFeature1Click')
const rawValue = flag.getValue('false')
const enabled =
typeof rawValue === 'string' ? rawValue.trim().toLowerCase() === 'true' : Boolean(rawValue)
applePayEnabled.value = enabled
flagshipLogStore.addLog({
timestamp: new Date().toISOString(),
level: 'INFO',
tag: 'flagship-client',
message: `paymentFeature1Click evaluated to ${enabled}`,
visitorId: visitor.visitorId,
rawValue,
enabled
})
}Project Structure
├── app.vue
├── assets/
├── components/
├── composables/
├── data/
├── layouts/
├── pages/
├── public/
├── server/
├── types/
└── nuxt.config.tsNext Steps
Last updated
Was this helpful?

