@signal-js/nextjs
v1.0.6
Published
Signal SDK integration for Next.js applications
Maintainers
Readme
@signal-js/nextjs
Signal SDK integration for Next.js applications. Uses @signal-js/browser (client) and @signal-js/node (server); both are included as dependencies.
Installation
npm install @signal-js/nextjs
# or
pnpm add @signal-js/nextjs
# or
yarn add @signal-js/nextjsQuick Start
App Router (Next.js 13+)
// app/providers.tsx
'use client';
import { SignalNextProvider } from '@signal-js/nextjs/client';
export function Providers({ children }: { children: React.ReactNode }) {
return (
<SignalNextProvider
options={{
endpoint: process.env.NEXT_PUBLIC_SIGNAL_ENDPOINT!,
apiKey: process.env.NEXT_PUBLIC_SIGNAL_API_KEY!,
projectId: process.env.NEXT_PUBLIC_SIGNAL_PROJECT_ID!,
}}
trackPageViews
>
{children}
</SignalNextProvider>
);
}
// app/layout.tsx
import { Providers } from './providers';
export default function RootLayout({ children }) {
return (
<html>
<body>
<Providers>{children}</Providers>
</body>
</html>
);
}Using in Components
'use client';
import { useSignal } from '@signal-js/nextjs';
export function MyComponent() {
const { capture, identify, group } = useSignal();
const handleLogin = (user) => {
identify(user.id, { email: user.email });
group('company', user.companyId);
};
return (
<button onClick={() => capture('button_clicked')}>
Click Me
</button>
);
}Server-Side Tracking
// lib/signal-server.ts
import { createSignalServer } from '@signal-js/nextjs/server';
export const signal = createSignalServer({
endpoint: process.env.SIGNAL_ENDPOINT!,
apiKey: process.env.SIGNAL_API_KEY!,
});
// In API routes or Server Actions
import { signal } from '@/lib/signal-server';
signal.capture({
distinctId: userId,
event: 'purchase_completed',
properties: { amount: 99.99 },
});Client Components
SignalNextProvider
Enhanced provider for Next.js App Router with automatic page view tracking.
<SignalNextProvider
options={{
endpoint: 'https://your-api.com',
apiKey: 'your-api-key',
}}
trackPageViews // Auto-track page views (default: true)
trackSearchParams // Include search params in page views
autoStart // Auto-start recording (default: true)
>
{children}
</SignalNextProvider>SignalPageViewTracker
Component that tracks page views on route changes.
import { SignalPageViewTracker } from '@signal-js/nextjs/client';
// Add to layout
<SignalPageViewTracker trackSearchParams />Hooks
All hooks from @signal-js/react are re-exported:
import {
useSignal,
useSignalCapture,
useSignalIdentify,
useSignalGroup,
useSignalSession,
usePageView,
useTrackEvent,
} from '@signal-js/nextjs';Server Components
createSignalServer(options)
Create a server-side Signal client.
import { createSignalServer } from '@signal-js/nextjs/server';
const signal = createSignalServer({
endpoint: process.env.SIGNAL_ENDPOINT!,
apiKey: process.env.SIGNAL_API_KEY!,
projectId: 'my-project',
});withSignalConfig(signalConfig)
Wrap your Next.js config with Signal configuration.
// next.config.js
const { withSignalConfig } = require('@signal-js/nextjs/server');
module.exports = withSignalConfig({
endpoint: process.env.SIGNAL_ENDPOINT,
apiKey: process.env.SIGNAL_API_KEY,
})({
// your Next.js config
});getSignalServerSideProps(getServerSidePropsFunc, options)
Helper for getServerSideProps to inject Signal data.
// pages/dashboard.tsx
import { getSignalServerSideProps } from '@signal-js/nextjs/server';
export const getServerSideProps = getSignalServerSideProps(
async (context) => {
return { props: { data: 'your data' } };
},
{
getDistinctId: (context) => context.req.cookies.userId,
}
);trackServerEvent(options)
Track an event from server-side code.
import { trackServerEvent } from '@signal-js/nextjs/server';
await trackServerEvent({
distinctId: userId,
event: 'server_action_completed',
properties: { action: 'update_profile' },
});Environment Variables
# Public (client-side)
NEXT_PUBLIC_SIGNAL_ENDPOINT=https://your-api.com
NEXT_PUBLIC_SIGNAL_API_KEY=your-public-api-key
NEXT_PUBLIC_SIGNAL_PROJECT_ID=your-project-id
# Private (server-side)
SIGNAL_ENDPOINT=https://your-api.com
SIGNAL_API_KEY=your-server-api-key
SIGNAL_PROJECT_ID=your-project-idFull Example
// app/providers.tsx
'use client';
import { SignalNextProvider } from '@signal-js/nextjs/client';
export function Providers({ children }) {
return (
<SignalNextProvider
options={{
endpoint: process.env.NEXT_PUBLIC_SIGNAL_ENDPOINT!,
apiKey: process.env.NEXT_PUBLIC_SIGNAL_API_KEY!,
projectId: process.env.NEXT_PUBLIC_SIGNAL_PROJECT_ID!,
enableSessionReplay: true,
enableNetworkCapture: true,
}}
trackPageViews
>
{children}
</SignalNextProvider>
);
}
// app/dashboard/page.tsx
'use client';
import { useSignal, usePageView } from '@signal-js/nextjs';
export default function Dashboard() {
const { capture, identify, group, sessionId } = useSignal();
// Track page view with custom properties
usePageView('dashboard', { section: 'analytics' });
return (
<div>
<h1>Dashboard</h1>
<p>Session: {sessionId}</p>
<button onClick={() => capture('export_clicked')}>
Export Data
</button>
</div>
);
}
// lib/signal-server.ts
import { createSignalServer } from '@signal-js/nextjs/server';
export const signal = createSignalServer({
endpoint: process.env.SIGNAL_ENDPOINT!,
apiKey: process.env.SIGNAL_API_KEY!,
});
// app/api/checkout/route.ts
import { NextResponse } from 'next/server';
import { signal } from '@/lib/signal-server';
export async function POST(request: Request) {
const { userId, amount } = await request.json();
signal.capture({
distinctId: userId,
event: 'checkout_completed',
properties: { amount },
});
return NextResponse.json({ success: true });
}License
MIT
