Skip to main content

Overview

In this guide you use shipd in a Next.js App Router app. Server Components and route handlers use shipdit with a server SDK key. Client components use shipdit/client and the React hooks with a client SDK key. There is no Next.js-specific package. You combine the Node.js and React setups.

Which key goes where

Create one key of each type in SDK keys for the environment. See Keys.
.env.local
Next.js inlines every NEXT_PUBLIC_ variable into the browser bundle. Never give the server key a NEXT_PUBLIC_ name.

Evaluate on the server

Create the server client in a module that only server code imports. Adding import "server-only" (from the server-only package) is optional. It makes the build fail if a client component imports this file.
src/lib/shipd.server.ts
This client doesn’t set stream: true, so it polls. To add realtime updates on a long-running Node.js server, see Node.js. Await ready() before you evaluate, then pass per-request context:
src/app/checkout/page.tsx
ready() resolves once per client, so later requests don’t wait. Route handlers work the same way:
src/app/api/search/route.ts
Pass context on each server call. On the server client, identify() only records an identify event and never changes evaluation context.

Evaluate in client components

Bind the hooks in a client module:
src/lib/shipd-react.ts
Create the browser client and provider in providers.tsx:
src/app/providers.tsx
src/app/layout.tsx
Identify the signed-in user from a client component inside Providers, as shown in React.

Avoid hydration mismatches

Client components are also rendered on the server. The server render and the first browser render can see different snapshots and identities, so a flag can evaluate differently in each. Use one of these patterns: Evaluate on the server and pass the value down. The value is fixed in the HTML, so both renders agree. Use this for content that must be correct on first paint.
src/app/checkout/CheckoutButton.tsx
Gate on useReady(). useReady() is false during the server render and the first browser render, so both output the same placeholder. The component renders the real value after the client is ready.
src/components/SearchBox.tsx

Next