For the complete documentation index, see llms.txt. This page is also available as Markdown.

Next.js SSR

How to use the SDK with Next.js and server-side rendering frameworks.

The SDK relies on browser APIs -- Web Workers, IndexedDB, and WebAssembly -- that are not available during server-side rendering. This guide covers the patterns you need to keep FHE operations on the client while still using Next.js App Router and SSR layouts.

Steps

1. Understand the constraint

The FHE relayer runs encryption and decryption inside a Web Worker backed by a WASM binary. IndexedDB stores encrypted transport key pairs. None of these APIs exist in Node.js or during SSR.

This means:

  • You cannot import RelayerWeb, ZamaProvider, or any SDK hook in a Server Component

  • You cannot create the relayer or signer at module level in a file that runs on the server

2. Mark SDK components with "use client"

Any component that imports from @zama-fhe/react-sdk must be a Client Component:

"use client";

import { useConfidentialBalance } from "@zama-fhe/react-sdk";
import { useAccount } from "wagmi";

export function TokenBalance({ tokenAddress }: { tokenAddress: string }) {
  const { address } = useAccount();
  const { data: balance, isLoading } = useConfidentialBalance({
    address: tokenAddress,
    account: address,
  });

  if (isLoading) return <span>Loading...</span>;
  return <span>{balance?.toString()}</span>;
}

3. Place ZamaProvider inside a client component

Create a dedicated client component that sets up the SDK providers. This keeps the relayer and signer initialization off the server.

4. Use the provider in your layout

The root layout is a Server Component by default. Import the client Providers wrapper and nest your pages inside it:

The layout file itself does not need "use client" -- it only imports a component that is already marked as a Client Component.

5. Avoid creating SDK objects in server components

A common mistake is initializing the relayer or signer in a shared module that gets imported by both server and client code:

Instead, keep all SDK initialization inside a "use client" file (like the Providers component above), or gate it behind a dynamic import:

6. Example: page with a confidential balance

Putting it all together -- a Next.js page that displays a confidential token balance:

The server renders the page shell, and the TokenBalance client component hydrates on the browser where FHE APIs are available.

Next steps

Last updated