Skip to main content
Add Bily through one client component in each route tree. The same setup supports App Router, Pages Router, and hybrid applications. Do not use next/script or add a raw script tag alongside the SDK. init() loads the script for you.

Install Bily

Keep the tracking URL exact

Copy the complete tracking URL from Bily > Settings > Apps > More settings > Install tracking into your app’s public build-time settings. The URL is public installation data, not a private token. For local development, add it to .env.local. This file is normally not committed.
.env.local
In dotenv files, keep the double quotes so # cannot begin a comment. If the exact URL contains a literal dollar sign, escape only that character as \$ so Next.js preserves it. Set the same variable in every preview and production build environment before running next build. In a deployment settings field, enter the raw URL without dotenv quotes or escapes. Next.js inlines NEXT_PUBLIC_ values into the browser bundle at build time. Rebuild and redeploy whenever the value changes. If your production build reads .env.production, .env.production.local, or another .env* file, use the quoted dotenv form shown above. Keep the rest of the URL unchanged, including its query string. After changing .env.local, restart the local development server.

Track Next.js navigation

The browser script records the initial page view automatically. This component remembers that URL and tracks only later client-side Next.js transitions. Create components/bily-tracking.tsx beside your app/ or pages/ directory. If your project uses both routers, the same component serves both. If your routes live under src/, place it at src/components/bily-tracking.tsx instead.
components/bily-tracking.tsx
The null-safe search value supports App Router, Pages Router, and applications that use both. Comparing URLs prevents route notifications from duplicating the initial page view.

Mount it once in App Router

Add the component to the root layout. Wrap it in Suspense because it reads the current search parameters. If app/layout.tsx already exists, add only the Bily mount. Keep its metadata exports, fonts, providers, global CSS, data hooks, error boundaries, and existing document markup. Use this complete example only when your application does not already have a root layout.
app/layout.tsx

Cover Pages Router routes

The App Router root layout does not wrap routes in pages/. If your application uses Pages Router alone or alongside App Router, mount the same component once in the Pages Router root. If pages/_app.tsx already exists, add only the Bily mount. Keep its existing imports, providers, layouts, global CSS, data hooks, and error boundaries. Use this minimal example only when your application does not already have a Custom App.
pages/_app.tsx
Mount BilyTracking once in each route tree. The root layout covers App Router routes. _app.tsx covers Pages Router routes. Give each environment its own complete URL. Do not build the URL from a hostname or add query parameters in code.

Track successful actions

Call track() from client code only after the operation succeeds.
app/workspaces/create-workspace-button.tsx

Track page views

Move to first-party tracking