@fanvue/builder-sdk/nextjs/off-platform.
You need:
- an off-platform app in the Developer Area, with its Client ID and Client Secret
- a Next.js App Router project with
@fanvue/builder-sdkandnext14 or later installed - an
httpsorigin for your dev server, unless it runs onlocalhost
Run over HTTPS locally
A redirect URI useshttps:// on any host, or http:// only on localhost, 127.0.0.1 or [::1]. The examples in this guide use my-fanvue-app.dev, which is neither, so give your dev server an https origin with portless, or with mkcert and local-ssl-proxy. Set up local HTTPS proxy walks through both.
Use the resulting URL, for example https://my-fanvue-app.dev:3001/api/auth/callback, as the redirect URI in your app registration and in OAUTH_REDIRECT_URI.
If you use an App Manifest, it can’t live on the local hostname, because Fanvue reads it from a public domain. Serve it from your production or staging domain and list the local redirect URI in oauth.redirectUris alongside the production one.
Configure the client
createConfig(opts?) resolves your OAuth client from options or environment variables and throws when a required value is missing. createConfigSafe(opts?) returns { ok: false, missing } instead, naming the unset variables, so a route can answer 503 on a misconfigured deployment. Both read the same variables, listed in full under Environment variables.
The SDK’s default callback path is /api/auth/callback, which differs from the /api/oauth/callback used by the App Starter. Register whichever your routes serve.
.env.local
OAUTH_SCOPES adds to the default openid offline_access offline, so list only the Fanvue scopes your app needs. Every scope must be registered on your app’s Authentication tab or in its App Manifest.
Add the route handlers
Each handler factory takes anOffPlatformOptions object, which is the resolved config plus afterLoginPath and afterLogoutPath. Both paths are required, and both accept null, which means /.
Build one options object and share it across the three routes.
lib/fanvue.ts
app/api/auth/login/route.ts
app/api/auth/callback/route.ts
app/api/auth/logout/route.ts
Read the session
After sign-in, the callback stores a signed JWT in anhttpOnly cookie. The JWT holds the access token, refresh token and expiry, plus the creator’s uuid, handle, displayName, isCreator and avatarUrl.
getSession(secret, cookieName?) verifies the cookie and returns the SessionPayload, or null when the cookie is missing or fails verification.
getAuthenticatedClient({ sessionSecret, sessionCookieName, config }) returns a FanvueClient bound to the session’s access token, or null when there is no valid session. When the access token is within 30 seconds of expiry and a refresh token exists, it refreshes first and rewrites the cookie with the new tokens. A failed refresh also returns null, so treat null as a signal to send the creator to /api/auth/login.
app/home/page.tsx
Receive webhooks
Webhook subscriptions are created with the creator’s OAuth token, which this entrypoint produces, so it re-exportscreateWebhookReceiverHandler and its port types. Receive webhooks with the SDK covers the setup.