See which channel brings your Nuxt customers

One module counts every route, and your server routes report the orders that paid.

Package @mirafive/sdk-nuxt

Set up in 5 steps

  1. Install the packages

    The module builds on the Vue, browser and server SDKs, which are its peer dependencies. It works with Nuxt 4 and Node.js 20 or later, and the server SDK is never bundled for the browser.

    Code for step 1 of the Nuxt setup: Install the packages. npm install @mirafive/sdk-nuxt @mirafive/sdk-vue @mirafive/sdk-browser @mirafive/sdk-server

  2. Add the module

    Pageviews need no code, because the module follows the Nuxt router. features lists what the bundle carries besides pageviews; here, feature flags.

    Code for step 2 of the Nuxt setup: Add the module. export default defineNuxtConfig({ modules: ['@mirafive/sdk-nuxt'], mirafive: { features: ['flags'], }, })

  3. Set the two keys

    The website key of your website source is public and reaches the browser through runtime config. The secret key of a server source stays in private runtime config, never in runtimeConfig.public or client code.

    Code for step 3 of the Nuxt setup: Set the two keys. NUXT_PUBLIC_MIRAFIVE_KEY=mf_… MIRAFIVE_SECRET_KEY=mf_…

  4. Record what matters

    useMira() is auto-imported. Call track in a handler; during the server render it does nothing, so the same component renders on both sides.

    Code for step 4 of the Nuxt setup: Record what matters. <script setup lang="ts"> const mira = useMira() </script> <template> <button @click="mira.track('added_to_cart', { product: 'merino-crew' })">Add to cart</button> </template>

  5. Send the paid order from a server route

    useServerMira(event) is auto-imported in server/. It is one server client per process, on the secret key, and the module sends the request's events after the response.

    Code for step 5 of the Nuxt setup: Send the paid order from a server route. // In the server route that confirms the payment useServerMira(event).track('order_paid', { userId: order.customerId, properties: { revenue: 328, currency: 'EUR' }, })

MIRA FIVE is analytics built around the person. In a Nuxt app one module covers both sides: auto-imported composables in your components, and server utils that send paid orders from server/.

What will I see after installing?

The first three questions the dashboard answers, from the default setup:

  1. Which channels send visitors? Acquisition › Channels splits visits into nine channels, from organic search and paid social to email and AI assistants. In the sample shop, Direct sent 525 visits, Organic search 438 and Paid social 277 over 30 days.
  2. Which pages do they land on? Journeys › Pages lists every route with pageviews, entries, bounce rate, exits and time on page. Sort by entries to see your landing pages.
  3. Which goals do they reach? Goals counts every conversion of the events you send, such as a sign-up or a paid order.

The default setup sets no cookies, stores nothing on the device and sends no identifier.

How does a paid order reach its channel?

Through the person who paid. With their consent, the browser keeps an id for the visitor, and identify ties it to your own user id when they sign in. The server route sends the order with the same user id, so MIRA FIVE puts the purchase on that person, next to their first visit and the channel that brought them.

Create a purchase goal for order_paid, and Acquisition shows buyers and revenue per channel and campaign. With Google Ads connected, it adds cost per buyer for each campaign.

Switch the website source to Full under Data → Sources. Then set mode: 'full' in nuxt.config.ts, and the module adds the identity code to the bundle:

export default defineNuxtConfig({
  modules: ['@mirafive/sdk-nuxt'],
  mirafive: {
    mode: 'full',
    features: ['flags'],
  },
})

Then pass your banner’s answer and the signed-in user through useMira():

const mira = useMira()

// From your consent banner
mira.consent({ statistics: true, experiments: true, targeting: false })

// After sign-in, with your own user id
mira.identify(user.id, { plan: user.plan })

// After sign-out
mira.reset()

Before an answer, full mode stores and sends nothing, and consent(false) forgets what is stored on the device. Ids live in localStorage, never in cookies. The consent guide explains the three scopes.

How do I make a webhook count once?

Payment providers sometimes deliver a webhook twice. send delivers at once and takes an idempotency key, so a repeat is stored once:

await useServerMira(event).send(
  [{ name: 'order_paid', userId: order.customerId, properties: { revenue: 328, currency: 'EUR' } }],
  { idempotencyKey: `order-${order.id}` },
)

The server-side guide covers retries and idempotency.

Can I read feature flags?

Yes. With 'flags' in features, useFlag and useFlagConfig return read-only refs:

<script setup lang="ts">
const newCheckout = useFlag('new-checkout', false)
</script>

<template>
  <button>{{ newCheckout === true ? 'Buy now' : 'Checkout' }}</button>
</template>

Server routes read feature flags with miraFlagsFor(event, { userId }). A code A/B test is a flag read the same way. The Nuxt SDK docs cover the flag bootstrap and cached routes.

Other setups

The same numbers, whichever way your site is built.

Questions and answers

Why does nothing arrive from localhost?
On localhost the browser SDK sends nothing and logs a hint in the console. Deploy, or run the production build on another host, and look for the batch in the network tab.
Do feature flags flicker on the first paint?
No. With flags and a secret key, each server render reads the visitor's flags and writes them into the head, so hydration matches. Cached and prerendered routes load flags in the browser instead.
I use Vue without Nuxt. Which package fits?
@mirafive/sdk-vue, the Vue 3 SDK the module builds on. It brings the same composables for events and flags.

See which channel brings buyers

Free for 25,000 events a month. No card needed.