Skip to main content
Server-rendered apps should treat Fanfare as a browser SDK. Render the surrounding page on the server, then mount Fanfare inside a client component after hydration. The server can prepare product data, authenticated customer context, and checkout routes. The SDK should be initialized in the browser with a publishable key, and admitted customers should be handed to a trusted server or checkout boundary.

Integration Shape

SSR integration shape showing server route, SSR page, browser Fanfare boundary, handoff API, and checkout. Key rules:
  • Put FanfareProvider, ExperienceWidget, and useExperienceJourney in client-only code.
  • Use environment variables that are safe for the browser, such as NEXT_PUBLIC_FANFARE_PUBLISHABLE_KEY.
  • Keep grants out of URLs and third-party telemetry.
  • Let the server validate the handoff before protected checkout actions.

Next.js App Router

Create a small client provider.
Wrap only the part of the tree that needs Fanfare.
Render the widget in a client component.
Use checkoutUrl instead of onGranted when simple browser navigation is enough.

Custom Client UI

For a custom SSR page, keep the server-rendered shell stable and branch on JourneyView only after the client component mounts.
Avoid rendering state-specific buttons from server assumptions. The current client view decides what is valid.

Remix And Nuxt

The same boundary applies in other SSR frameworks:
  • Load product and routing data on the server.
  • Mount Fanfare in browser-only code.
  • Import @fanfare-io/fanfare-sdk-react/styles once for React surfaces.
  • Use the core SDK or web components when React is not part of the client island.
For static or CMS-rendered islands, register the web component once:

Server Handoff

Your admission endpoint should accept the grant from your own page and prepare the next trusted step.
Keep the endpoint focused on your application contract. Do not mirror private routing details into public responses.

Testing SSR Integrations

  • Confirm the page renders without accessing browser-only APIs on the server.
  • Confirm the client boundary hydrates and renders a public journey state.
  • Test admitted handoff through your own API route.
  • Repeat with a returning browser session.
  • Keep assertions based on visible states and app-owned side effects.
See Testing Your Integration for app-boundary test guidance.