Next.js

Install StepsKit (Next.js)

Install the package and render one component in your root layout. This guide assumes the App Router; the Pages Router pattern is the same — put <StepsKit /> in _app.tsx instead.

Install the package

npm install stepskit

Add StepsKit to your root layout

// app/layout.tsx
import { StepsKit } from "stepskit/react";

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en">
      <body>
        {children}
        <StepsKit apiKey="YOUR_API_KEY" />
      </body>
    </html>
  );
}

The component ships "use client" inside the package, so your layout stays a server component — no "use client" at the top of layout.tsx, and no client boundary around your whole tree.

It loads StepsKit after hydration, so it never blocks first paint, and it mounts once for the lifetime of the page rather than per navigation.

Identify the user

If the user is available in the layout, pass them straight to the component. This is the best option in the App Router, because it identifies the visitor before your first client component renders:

// app/layout.tsx
const user = await getCurrentUser();

<StepsKit
  apiKey="YOUR_API_KEY"
  user={user ? { id: user.id, email: user.email, plan: user.plan } : undefined}
/>;

Passing a new object with the same values does not re-identify, so this is safe to re-render.

Otherwise call identify from your login handler — or anywhere you already have the user object. This works for both new sign-ins and client-side profile changes (plan upgrades, email updates, etc.):

"use client";

import stepskit from "stepskit";

async function handleLogin(credentials) {
  const user = await login(credentials);

  stepskit.identify({
    id: user.id,
    email: user.email,
    plan: user.plan,
  });
}

Without an id, show-once frequency capping and audience targeting silently do nothing — see visitor identification.

Without the package

If you can't add a dependency, load the engine with next/script instead. Use afterInteractive; never beforeInteractive.

import Script from "next/script";

<Script
  src="https://cdn.stepskit.com/stepskit.latest.js"
  data-api-key="YOUR_API_KEY"
  strategy="afterInteractive"
/>;

You can also pass data-user-* attributes on the <Script> tag for purely server-rendered cases. On this path window.stepskit has no types, so you'll want the ambient declaration from the React guide.