Next.js
Add Loamly to your Next.js application
Next.js is the most popular React framework, and Loamly integrates seamlessly with both the App Router and Pages Router. This guide covers both approaches.
App Router (Next.js 13+)
For Next.js 13+ with the App Router, add the Loamly script to your root layout using the Script component:
// app/layout.tsx
import Script from 'next/script';
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="en">
<body>
{children}
<Script
src="https://app.loamly.ai/t.js?d=yourdomain.com"
strategy="afterInteractive"
/>
</body>
</html>
);
}Strategy options
- afterInteractive (recommended): Loads after the page becomes interactive
- lazyOnload: Loads during browser idle time
- beforeInteractive: Loads before hydration (not recommended for analytics)
Pages Router
For Next.js with the Pages Router, add the script to your _app.tsx:
// pages/_app.tsx
import Script from 'next/script';
import type { AppProps } from 'next/app';
export default function App({ Component, pageProps }: AppProps) {
return (
<>
<Script
src="https://app.loamly.ai/t.js?d=yourdomain.com"
strategy="afterInteractive"
/>
<Component {...pageProps} />
</>
);
}Track custom events
Create a utility function to track events with TypeScript support:
// lib/analytics.ts
declare global {
interface Window {
loamly?: {
event: (name: string, properties?: Record<string, unknown>) => void;
page: (properties?: { path?: string; title?: string }) => void;
};
}
}
export function trackEvent(
name: string,
properties?: Record<string, unknown>
) {
if (typeof window !== 'undefined' && window.loamly) {
window.loamly.event(name, properties);
}
}
export function trackPageView(path?: string, title?: string) {
if (typeof window !== 'undefined' && window.loamly) {
window.loamly.page({ path, title });
}
}Then use it in your components:
// components/SignupButton.tsx
'use client';
import { trackEvent } from '@/lib/analytics';
export function SignupButton() {
const handleClick = () => {
trackEvent('signup_clicked', {
location: 'hero',
variant: 'primary'
});
};
return (
<button onClick={handleClick}>
Start Free Trial
</button>
);
}Server Components
Loamly tracking runs entirely on the client. For Server Components, wrap any interactive tracking in a Client Component:
// components/TrackableLink.tsx
'use client';
import { trackEvent } from '@/lib/analytics';
import Link from 'next/link';
interface Props {
href: string;
children: React.ReactNode;
eventName?: string;
}
export function TrackableLink({ href, children, eventName }: Props) {
const handleClick = () => {
if (eventName) {
trackEvent(eventName, { href });
}
};
return (
<Link href={href} onClick={handleClick}>
{children}
</Link>
);
}Environment variables
For different domains in development vs production, use environment variables:
// .env.local
NEXT_PUBLIC_DOMAIN=localhost:3000
// .env.production
NEXT_PUBLIC_DOMAIN=yourdomain.com// app/layout.tsx
<Script
src={`https://app.loamly.ai/t.js?d=${process.env.NEXT_PUBLIC_DOMAIN}`}
strategy="afterInteractive"
/>Development tracking
By default, Loamly filters out localhost traffic. If you want to test tracking in development, add your localhost domain to your workspace settings.