Getting started
Integrations
Vitrus is one script tag, so there is no plugin to install anywhere. What changes between platforms is only where the tag goes. Below are the exact places for the common ones.
SITE_ID with it.React & Next.js
App Router — put it in app/layout.tsx so it loads on every route. The
tracker handles client-side navigation on its own; you do not need to fire pageviews manually.
// app/layout.tsx import Script from "next/script"; export default function RootLayout({ children }) { return ( <html> <body> {children} <Script defer src="https://app.vitrus.dev/v.js" data-site="SITE_ID" strategy="afterInteractive" /> </body> </html> ); }
Pages Router: the same block in pages/_document.tsx or
pages/_app.tsx. Plain React (Vite, CRA): the tag goes in
index.html.
Vue & Nuxt
// nuxt.config.ts export default defineNuxtConfig({ app: { head: { script: [{ src: "https://app.vitrus.dev/v.js", defer: true, "data-site": "SITE_ID" }] } } });
Plain Vue: index.html, inside <head>.
SvelteKit
src/app.html, just before </head>:
<script defer data-site="SITE_ID" src="https://app.vitrus.dev/v.js"></script>
Astro
In your layout component's <head>. Astro does not touch the tag,
so this works for both static and server output.
<!-- src/layouts/Layout.astro --> <head> <script defer data-site="SITE_ID" src="https://app.vitrus.dev/v.js"></script> </head>
WordPress
Without a plugin, add it to your theme's functions.php — this survives
theme updates if you are using a child theme:
add_action('wp_head', function () { echo '<script defer data-site="SITE_ID" src="https://app.vitrus.dev/v.js"></script>'; });
Or paste the plain tag into any "header scripts" box your theme or an SEO plugin provides.
Shopify
Online Store → Themes → Edit code → layout/theme.liquid, just
before </head>. Add the same tag to
checkout.liquid if your plan allows it, otherwise checkout steps are
measured through custom events from the thank-you page.
<script defer data-site="SITE_ID" src="https://app.vitrus.dev/v.js"></script>
Webflow, Framer, Squarespace, Wix
| Platform | Where |
|---|---|
| Webflow | Project settings → Custom code → Head code |
| Framer | Site settings → General → Custom code → Head start |
| Squarespace | Settings → Advanced → Code injection → Header |
| Wix | Settings → Custom code → Add code to Head, all pages |
| Ghost | Settings → Code injection → Site header |
| Docusaurus | scripts array in docusaurus.config.js |
Google Tag Manager
New tag → Custom HTML → paste the script tag → trigger on All Pages.
Server-rendered frameworks
Rails (app/views/layouts/application.html.erb), Django
(base.html), Laravel
(resources/views/layouts/app.blade.php) — in each case the tag goes in the
shared layout's <head>. Nothing framework-specific is needed.
Single-page apps in general
The tracker patches pushState and
replaceState and listens for popstate, so
client-side route changes are counted automatically. Navigating to the same path twice does not
produce a second pageview. If you would rather drive it yourself, set
data-auto="false" and call
vitrus("pageview") where you want it.
Verifying
Open your site, then watch the live visitor counter in the dashboard header. If nothing shows up, work through troubleshooting.