> ## Documentation Index
> Fetch the complete documentation index at: https://docs.buckspay.xyz/llms.txt
> Use this file to discover all available pages before exploring further.

# Next.js BFF - @buckspay/nextjs

> App Router route factories that keep the facilitator API key and provider secrets server-side behind same-origin BFF routes.

`@buckspay/nextjs` exports two App Router route factories. They act as the BFF (Backend for
Frontend) boundary described in [Facilitator and BFF](/concepts/facilitator-and-bff): the
browser POSTs to your same-origin routes; the routes forward to the facilitator with the secret
credentials server-side.

<Warning>
  `@buckspay/nextjs` is **server-only**. Never import it in a Client Component or a file that
  ends up in the browser bundle. The API key and provider secrets you pass to these factories
  are captured in a server closure and are never serialized or echoed to the client.
</Warning>

<Steps>
  ### Install

  ```bash theme={null}
  pnpm add @buckspay/nextjs @buckspay/core @buckspay/relayer
  ```

  ### Create the relay route

  Create `app/api/buckspay/relay/route.ts`. `createRelayRoute` returns a `(req: Request) => Promise<Response>`
  handler - assign it to `POST` as required by App Router conventions.

  ```ts theme={null}
  // app/api/buckspay/relay/route.ts - SERVER-ONLY
  import { createRelayRoute } from "@buckspay/nextjs";

  export const POST = createRelayRoute({
    facilitatorUrl: process.env.BUCKSPAY_FACILITATOR_URL!,
    apiKey: process.env.BUCKSPAY_FACILITATOR_API_KEY!, // SERVER-SIDE ONLY
    network: "testnet"
  });
  ```

  `createRelayRoute` accepts a `CreateRelayRouteOptions` object:

  | Option           | Type      | Description                                                  |
  | ---------------- | --------- | ------------------------------------------------------------ |
  | `facilitatorUrl` | `string`  | Base URL of the Buckspay facilitator                         |
  | `apiKey`         | `string`  | Facilitator API key - from a server env var, never a literal |
  | `network`        | `Network` | `"testnet"` or `"mainnet"`                                   |

  The route validates the incoming `RelayPayload` with a strict Zod schema before forwarding, so
  malformed requests are rejected at the BFF layer. On error it returns a coded JSON response
  (`{ error: BuckspayErrorCode }`) without leaking the upstream message.

  ### Create signer proxy routes (social and email login)

  If you use social or email-based signers, create proxy routes that forward the auth body to the
  facilitator's `/auth/*` endpoints while injecting the API key server-side.

  ```ts theme={null}
  // app/api/buckspay/auth/social/route.ts - SERVER-ONLY
  import { createSignerProxyRoute } from "@buckspay/nextjs";
  export const POST = createSignerProxyRoute({ provider: "web3auth", network: "testnet" });
  ```

  ```ts theme={null}
  // app/api/buckspay/auth/email/route.ts - SERVER-ONLY
  import { createSignerProxyRoute } from "@buckspay/nextjs";
  export const POST = createSignerProxyRoute({ provider: "email", network: "testnet" });
  ```

  `createSignerProxyRoute` reads `BUCKSPAY_FACILITATOR_URL` and `BUCKSPAY_FACILITATOR_API_KEY`
  from the server environment by default. You can override both via the optional second argument
  (`CreateSignerProxyRouteDeps`).

  ### Point the browser client at your BFF routes

  In your browser (or React) code, configure the relayer without an API key - it points at your
  same-origin BFF routes:

  ```ts theme={null}
  import { buckspayFacilitator } from "@buckspay/relayer/buckspay-facilitator";

  const relayer = buckspayFacilitator({ url: "/api/buckspay/relay", network: "testnet" });
  // No apiKey here - the key lives server-side in the route handler above.
  ```
</Steps>

## Full example

The snippet below shows all three route handlers in a single file for reference. In production,
each goes in its own `route.ts` under `app/`.

```ts theme={null}
// Recipe 15 - NEXT.JS BFF (App Router). Three server-only route handlers, packaged.
//
// These are the same-origin endpoints your browser code calls (`/api/buckspay/...`). The
// facilitator apiKey and the provider secrets stay SERVER-SIDE - they are never in the client
// bundle. Each `export const POST` below lives in its own `route.ts` under app/.
import { createRelayRoute, createSignerProxyRoute } from "@buckspay/nextjs";

// app/api/buckspay/relay/route.ts - the gasless relay BFF (the dashboard pattern, packaged).
export const relayPOST = createRelayRoute({
  facilitatorUrl: process.env.BUCKSPAY_FACILITATOR_URL ?? "https://facilitator.example",
  apiKey: process.env.BUCKSPAY_FACILITATOR_API_KEY ?? "", // SERVER-SIDE ONLY
  network: "testnet"
});

// app/api/buckspay/auth/social/route.ts - social signer-proxy (forwards to /auth/social).
// Reads BUCKSPAY_FACILITATOR_URL + BUCKSPAY_FACILITATOR_API_KEY from server env.
export const socialPOST = createSignerProxyRoute({ provider: "web3auth", network: "testnet" });

// app/api/buckspay/auth/email/route.ts - email signer-proxy (forwards to /auth/email).
export const emailPOST = createSignerProxyRoute({ provider: "email", network: "testnet" });
```

## Next

<CardGroup cols={2}>
  <Card title="Facilitator and BFF" href="/concepts/facilitator-and-bff">
    Why the API key must stay server-side and how the BFF slot fits the payment flow.
  </Card>

  <Card title="Web - @buckspay/react" href="/platforms/web-react">
    The browser-side hooks that POST to your BFF relay route.
  </Card>
</CardGroup>
