See which channel brings your Astro buyers

One integration bundles the tracker into your own build, and an endpoint reports the orders that paid.

Package @mirafive/sdk-astro

Set up in 5 steps

  1. Install the packages

    Add the integration and the browser SDK it bundles. It works with Astro 7 and Node.js 22.12 or later.

    Code for step 1 of the Astro setup: Install the packages. npm install @mirafive/sdk-astro @mirafive/sdk-browser

  2. Add the integration

    Put the website key of your website source from Data → Sources in PUBLIC_MIRAFIVE_KEY in .env, then add the integration, or run npx astro add @mirafive/sdk-astro. Pageviews are sent on load and on every <ClientRouter /> navigation.

    Code for step 2 of the Astro setup: Add the integration. import mirafive from '@mirafive/sdk-astro' import { defineConfig } from 'astro/config' export default defineConfig({ integrations: [mirafive()], })

  3. Record what matters

    Import mirafive from the client entry in any script or island and call a verb. A call made before the client starts is queued and runs once it does.

    Code for step 3 of the Astro setup: Record what matters. <button id="add-to-cart">Add to cart</button> <script> import { mirafive } from '@mirafive/sdk-astro/client' document.getElementById('add-to-cart')?.addEventListener('click', () => { mirafive('track', 'added_to_cart', { product: 'merino-crew' }) }) </script>

  4. Send the paid order from an endpoint

    The integration sends nothing from the server, so install @mirafive/sdk-server and use the secret key of a server source, read through astro:env/server. The endpoint renders on demand (export const prerender = false) and flushes before it returns.

    Code for step 4 of the Astro setup: Send the paid order from an endpoint. import { Mira } from '@mirafive/sdk-server' import { getSecret } from 'astro:env/server' const mira = new Mira({ key: getSecret('MIRAFIVE_SECRET_KEY'), host: getSecret('MIRAFIVE_HOST') }) // In the endpoint that confirms the payment mira.track('order_paid', { userId: order.customerId, properties: { revenue: 328, currency: 'EUR' }, }) await mira.flush()

  5. Check the live view

    Deploy, open a page on your site and watch Data → Live, which refreshes every 5 seconds. astro dev sends nothing unless you pass dev: true, so test on the deployed site.

MIRA FIVE is analytics built around the person, and the Astro integration is the quickest way in: one line in astro.config, and every page of the site is counted, including client-side navigation. An endpoint adds the paid orders, so you see which channel brings the people who buy.

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 page 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.

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 endpoint 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. The guide to setting up a purchase goal walks through it.

Switch the website source to Full under Data → Sources. Then set mode: 'full', and the integration adds the identity code to the bundle:

export default defineConfig({
  integrations: [mirafive({ mode: 'full' })],
})

Then pass your banner’s answer and the signed-in user through the client entry:

import { mirafive } from '@mirafive/sdk-astro/client'

// From your consent banner
mirafive('consent', true) // statistics only
mirafive('consent', { statistics: true, experiments: true, targeting: false }) // by scope
mirafive('consent', false) // forgets what is stored on the device

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

// After sign-out
mirafive('reset')

Before an answer, full mode stores and sends nothing. Ids live in localStorage, never in cookies. The Astro SDK docs show how to answer before the bundle loads.

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 mira.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. Add features: ['flags'] to the integration and read feature flags inside the flags listener, which runs when they load or change:

mirafive('flags', () => {
  const newCheckout = mirafive('flag', 'new-checkout', false)
  document.body.classList.toggle('new-checkout', newCheckout === true)
})

On pages rendered on demand, miraFlagsFor() from @mirafive/sdk-astro/server answers them before the first paint. A code A/B test is a flag read the same way.

Other setups

The same numbers, whichever way your site is built.

Questions and answers

What does the default setup collect?
Visits, pages, channels, campaigns, countries, devices and events. It sets no cookie, stores nothing on the device and sends no identifier. IP addresses are used to look up country and region and are never stored with your analytics data.
Does the integration load a script from another domain?
No. It bundles the code into your own build, so the page loads it from your own origin. Events go to the MIRA FIVE collector at events.mirafive.io.
Does it work with the ClientRouter?
Yes. The integration follows every ClientRouter navigation, holds the pageview until the new page has loaded, and sends it with that page's title and the right referrer.

See which channel brings buyers

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