Frameworks
Frameworks
One component per framework loads the tracker once and gives you typed event helpers. Anything without a package takes the script tag.
What the packages do
Every framework package is a thin layer over @seentics/browser, which loads the same tracker file as the script tag. They exist to handle the parts that are awkward to do by hand:
- The script is added once, even when a component mounts twice (React strict mode, hot reload, a layout that remounts).
- Nothing runs on the server.
track()called while rendering on the server is ignored: there is no visitor yet. - Events sent before the tracker has loaded are queued and replayed in order, up to 200. If the tracker never arrives (an ad blocker), they are dropped quietly and never throw.
- A website ID that is not a UUID is refused with a console warning, instead of sending nothing silently.
Get the website ID from Settings → Tracking in Seentics. All options are on the tracker reference; each is a prop of the component: websiteId (required), src, apiHost, autoTrack, consent, consentBanner, privacyUrl, captureConsole, captureNetwork, rrwebSrc and nonce.
Page changes are tracked for you
history.pushState, replaceState and popstate, so client-side route changes in a single-page app produce a pageview without any router code. A navigation counts only when the path changes: a change to the query string or #hash alone does not. For a router that fakes pages with hashes, set autoTrack: false and call page() yourself.Next.js
npm i @seentics/nextApp Router: put the component in the root layout. It works in a server component.
import { Seentics } from '@seentics/next';
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<body>
<Seentics websiteId="YOUR_WEBSITE_ID" />
{children}
</body>
</html>
);
}Pages Router: the same component in pages/_app.tsx.
import type { AppProps } from 'next/app';
import { Seentics } from '@seentics/next';
export default function App({ Component, pageProps }: AppProps) {
return (
<>
<Seentics websiteId="YOUR_WEBSITE_ID" />
<Component {...pageProps} />
</>
);
}Send events from a client component or an event handler:
'use client';
import { track } from '@seentics/next';
export function BuyButton() {
return <button onClick={() => track('add_to_cart', { sku: 'TEE-1', value: 29 })}>Add to cart</button>;
}To serve the tracker from your own domain, see Serve Seentics from your own domain.
React (Vite, Create React App)
npm i @seentics/reactimport { Seentics } from '@seentics/react';
root.render(
<>
<Seentics websiteId="YOUR_WEBSITE_ID" />
<App />
</>,
);import { useSeentics } from '@seentics/react';
export function Checkout({ order }: { order: { id: string; total: number } }) {
const seentics = useSeentics();
const onPaid = () => seentics.trackPurchase({ value: order.total, currency: 'USD', order_id: order.id });
return <button onClick={onPaid}>Pay</button>;
}Vue
npm i @seentics/vueimport { createApp } from 'vue';
import { SeenticsPlugin } from '@seentics/vue';
import App from './App.vue';
createApp(App).use(SeenticsPlugin, { websiteId: 'YOUR_WEBSITE_ID' }).mount('#app');import { track } from '@seentics/vue';
track('signup', { plan: 'pro' });Nuxt
npm i @seentics/nuxtexport default defineNuxtConfig({
modules: ['@seentics/nuxt'],
seentics: { websiteId: 'YOUR_WEBSITE_ID' },
});For events, import track from @seentics/browser, the package every other one is built on.
Astro
npm i @seentics/astroEither the integration, which adds the tracker to every page:
import { defineConfig } from 'astro/config';
import seentics from '@seentics/astro';
export default defineConfig({ integrations: [seentics({ websiteId: 'YOUR_WEBSITE_ID' })] });or the component, in your layout's <head>:
---
import Seentics from '@seentics/astro/Seentics.astro';
---
<head>
<Seentics websiteId="YOUR_WEBSITE_ID" />
</head>Astro's view transitions swap pages with the History API, which the tracker follows. Send events from a client script with track from @seentics/browser.
SvelteKit and Svelte
npm i @seentics/svelte<script>
import { Seentics } from '@seentics/svelte';
</script>
<Seentics websiteId="YOUR_WEBSITE_ID" />
<slot />import { track } from '@seentics/browser';
track('newsletter_signup');Remix, Gatsby, Angular and anything else
Without a package, put the tag in the one file that renders the document's <head>. Replace YOUR_WEBSITE_ID:
<script defer data-website-id="YOUR_WEBSITE_ID" src="https://seentics.com/trackers/seentics.min.js"></script>- Remix:
app/root.tsx, inside<head>of the document component. - Gatsby:
gatsby-ssr.js,onRenderBody, passed tosetHeadComponentsas a<script defer … />element. - Angular:
src/index.html. - Eleventy, Hugo, Jekyll, plain HTML: the base layout.
The tracker is deferred, so call seentics.track() only once it has loaded (from a click handler, say), or use @seentics/browser to queue calls for you: import { track } from '@seentics/browser'.
If nothing shows up
- Search the page source (or the DOM) for
seentics-js. Missing: the component is not rendered, or the website ID was refused. Look for[Seentics] websiteId is missingin the console. - Present, but no pageview: check the Network tab for
/api/v1/tracker/collect. A blocked request is an ad blocker or a content-security policy; add the tracker host toscript-srcandconnect-src. - A
403from collect: the website's URL in Seentics does not match the host you are browsing. Seentics Cloud checks this in production, solocalhostis refused there; test on your real domain or a staging domain registered as a website.
Other platforms: website builders, Google Tag Manager, e-commerce platforms.