# Install StepsKit in a Next.js app

> Add StepsKit to a Next.js app with the stepskit npm package. Render the StepsKit component in app/layout.tsx and identify the user so tours fire with the correct visitor on first paint.

*Source: https://stepskit.com/docs/install/nextjs*

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

```bash
npm install stepskit
```

## Add StepsKit to your root layout

```tsx
// 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:

```tsx
// 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.):

```tsx
"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](/docs/concepts/visitor-identification.md).

## Without the package

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

```tsx
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](/docs/install/react.md#typescript).
