@alaasync/layersync-react
v0.4.0
Published
React adapter for the LayerSync conversion-tracking SDK — Provider, hook, and auto-pageview tracking for Next.js (App + Pages Router) and React Router.
Maintainers
Readme
@alaasync/layersync-react
React adapter for LayerSync — conversion tracking + server-side CAPI delivery, drop-in for React, Next.js, and React Router apps.
npm install @alaasync/layersync-react @alaasync/layersync-webSame backend as @alaasync/layersync-web — adds a Provider, a hook, and framework-aware auto-pageview helpers.
Next.js App Router
// app/layout.tsx
import { LayerSyncProvider } from '@alaasync/layersync-react';
import { LayerSyncPageView } from '@alaasync/layersync-react/next-app';
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html>
<body>
<LayerSyncProvider
siteId={process.env.NEXT_PUBLIC_LAYERSYNC_SITE_ID!}
publishableKey={process.env.NEXT_PUBLIC_LAYERSYNC_KEY!}
>
<LayerSyncPageView />
{children}
</LayerSyncProvider>
</body>
</html>
);
}// Any client component
'use client';
import { useLayerSync } from '@alaasync/layersync-react';
export function CheckoutButton() {
const ls = useLayerSync();
return (
<button onClick={() => ls.track('begin_checkout', { value: 99.95, currency: 'USD' })}>
Buy now
</button>
);
}Next.js Pages Router
// pages/_app.tsx
import type { AppProps } from 'next/app';
import { LayerSyncProvider } from '@alaasync/layersync-react';
import { LayerSyncPageView } from '@alaasync/layersync-react/next-pages';
export default function MyApp({ Component, pageProps }: AppProps) {
return (
<LayerSyncProvider
siteId={process.env.NEXT_PUBLIC_LAYERSYNC_SITE_ID!}
publishableKey={process.env.NEXT_PUBLIC_LAYERSYNC_KEY!}
>
<LayerSyncPageView />
<Component {...pageProps} />
</LayerSyncProvider>
);
}React Router v6 (Vite, CRA, Remix in SPA mode)
// App.tsx
import { BrowserRouter, Routes, Route } from 'react-router-dom';
import { LayerSyncProvider } from '@alaasync/layersync-react';
import { LayerSyncPageView } from '@alaasync/layersync-react/react-router';
export default function App() {
return (
<BrowserRouter>
<LayerSyncProvider siteId="1" publishableKey="pk_live_xxx">
<LayerSyncPageView />
<Routes>
<Route path="/" element={<Home />} />
<Route path="/product/:id" element={<Product />} />
</Routes>
</LayerSyncProvider>
</BrowserRouter>
);
}Framework-agnostic SPA tracking
If you're not using a known router (or you've built a custom one), usePageView() patches history.pushState + replaceState + popstate so any URL change fires page():
import { LayerSyncProvider, usePageView } from '@alaasync/layersync-react';
function GlobalTracker() {
usePageView();
return null;
}
export default function App() {
return (
<LayerSyncProvider siteId="1" publishableKey="pk_live_xxx">
<GlobalTracker />
<YourApp />
</LayerSyncProvider>
);
}Hooks API
useLayerSync(): LayerSyncClient
Returns the active client. Throws if called outside a <LayerSyncProvider> — that's almost always a bug worth surfacing. Available methods are documented in @alaasync/layersync-web.
useLayerSyncOptional(): LayerSyncClient | null
Non-throwing variant. Useful in components that render during SSR before the provider mounts, or in analytics-optional code paths.
usePageView(options?)
Auto-fires page() on SPA navigations via a history-patching shim. Pass { trackInitial: false } if you want to suppress the on-mount pageview (you'd typically do this only when you've already wired the framework-specific adapter and don't need the fallback).
Server-side rendering (SSR)
The Provider is SSR-safe: when typeof window === 'undefined', it skips init() and renders children. The SDK boots on the client during hydration. No special handling needed for Next.js, Remix, or any SSR setup.
For consent-gated bootstrapping (e.g. don't load the SDK until the user accepts cookies), pass enabled={false} then flip to true once consent fires:
<LayerSyncProvider enabled={consentGranted} siteId="..." publishableKey="...">
{children}
</LayerSyncProvider>Auth model
publishableKey is safe to ship in your client bundle (it can only POST events for its site). Get yours from the LayerSync dashboard → Sites → API Keys.
For server-to-server calls from Node, use @layersync/node with a secret key (sk_live_*) instead. The browser SDK never holds a secret.
License
MIT.
