# Next.js
Use Plandalf from Next.js App Router or Pages Router with next/script, client components, identity, and checkout attributes.
Source: /docs/platforms/nextjs
Last modified: 2026-06-19
Use Plandalf in client-rendered parts of your Next.js app. Load the organization SDK with `next/script`, render normal React buttons with Plandalf attributes, and keep identity or API work on the server.


> **The SDK runs in the browser**
>

  Checkout buttons, inline mounts, and promo widgets are browser behavior. Server routes are useful for signing identity tokens or creating backend records, not for opening checkout frames.


## The path


### Load the SDK after hydration


    Use `next/script` with `afterInteractive` in your root layout or the route that contains checkout.


### Render one client-side buying action


    Start with a normal button that has `data-plandalf-present`.


### Move identity to the server


    If checkout should know the logged-in customer, sign a JWT in a route handler or server action, then pass it to a client component.


### Test mode before live traffic


    Add `data-plandalf-mode="test"` or call `present()` with `{ mode: "test" }` while validating the route.


## App Router setup


### Next.js checkout route


```tsx layout.tsx
import Script from "next/script";

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html>
      <body>
        {children}
        <Script
          src="https://acme.plandalf.com/js/plandalf-sdk.js"
          strategy="afterInteractive"
        />
      </body>
    </html>
  );
}
```

```tsx BuyButton.tsx
"use client";

export function BuyButton() {
  return (
    <button
      data-plandalf-present="pro-plan"
      data-plandalf-frame="slideout"
      data-plandalf-mode="test"
    >
      Buy Pro
    </button>
  );
}
```

```ts identity.ts
// Server-only helper. Sign with your Plandalf API credentials.
export async function createPlandalfIdentity(user: {
  id: string;
  email: string;
}) {
  return signPlandalfJwt({
    external_id: user.id,
    email: user.email
  });
}
```


## Programmatic checkout

Use direct SDK calls when a click needs app logic before checkout opens.

```tsx
"use client";

export function UpgradeButton({ userJwt }: { userJwt?: string }) {
  async function upgrade() {
    const flow = plandalf.present("pro-plan", {
      user: userJwt,
      frame: "modal",
      mode: "test"
    });

    for await (const event of flow.events) {
      console.log(event.type);
    }

    await flow;
  }

  return <button onClick={upgrade}>Upgrade</button>;
}
```


### Next.js boundaries


- `Server routes` (API keys and JWT signing):
    Keep API credentials and identity signing off the browser.


- `Client components` (checkout UI):
    Render buttons, inline checkout containers, and SDK method calls from browser code.


- `Environment` (test | live | preview):
    Use test mode before you expose the route to real buyers.


## Related docs


### [Identify customers](/docs/sdk/identity)


    Pass server-signed identity into browser checkout.


### [React SDK](/docs/sdk/react)


    Use provider and hooks when your app should manage SDK state through React.


### [Live events](/docs/sdk/events)


    Listen to FlowHandle events after checkout opens.