By the end of this page you’ll have a Next.js app running locally over HTTPS where creators click Login with Fanvue, approve your app and land on a page that shows their account. The Fanvue App Starter already wires the OAuth 2.0 code flow with PKCE and a cookie session, so you configure it rather than write it. The settings come from environment variables, so the same app deploys to any Node.js host.
You need:
- a Fanvue creator account or agency admin account, to create the app in the Developer Area
- Node.js 18 or later
- pnpm
Adding sign-in to an app you already have? Follow the OAuth implementation guide for framework-agnostic steps, or use the SDK without the starter.
1) Bootstrap from the Fanvue App Starter
The template repository is Fanvue App Starter. Start from it in one of three ways.
- Use this template on GitHub
- Open Fanvue App Starter
- Click Use this template, then Create a new repository
- Clone your new repository locally
- Scaffold with degit
- Clone and re-init
Use pnpm for install, dev and build commands. The starter’s lockfile is a pnpm lockfile, so npm or yarn installs resolve different versions.
2) Set up local HTTPS proxy
A redirect URI must use https:// unless its host is localhost, 127.0.0.1 or [::1]. The starter’s default callback uses the host my-fanvue-app.dev, so you need a local HTTPS proxy in front of the dev server. These steps use mkcert and local-ssl-proxy; if you’d rather skip them, see portless below.
Install mkcert:
Generate certificates, replacing my-fanvue-app with your app name. The second command writes two files, my-fanvue-app.dev.pem and my-fanvue-app.dev-key.pem.
Point the host at your machine:
You start the proxy in step 5, once the environment variables are in place. It forwards HTTPS traffic on port 3001 to the Next.js dev server on port 3000.
Alternative: portless
portless replaces the mkcert, local-ssl-proxy and hosts-file steps. It serves your dev server at a stable https://<name>.localhost URL and trusts a local CA automatically, with no port numbers or /etc/hosts edits.
With portless, use the URL it serves as your callback, for example https://my-fanvue-app.localhost/api/oauth/callback with no :3001 port, both on the Authentication tab and in OAUTH_REDIRECT_URI. Skip the mkcert and local-ssl-proxy steps.
3) Create your Fanvue OAuth app
In the Developer Area, click Create app. The dialog that opens shows your Client ID and Client Secret once, so copy both. The Client ID stays visible on the Authentication tab, and Reset secret there issues a new secret if you lose the first; see Managing your OAuth client secret.
On the Authentication tab, add the redirect URI https://my-fanvue-app.dev:3001/api/oauth/callback and tick the read:self scope. Both apply when you save.
If you’d rather keep redirect URIs and scopes in your repo, set them in an App Manifest. The starter adds the system scopes openid, offline_access and offline to whatever you set in OAUTH_SCOPES, so list only read:self in the manifest’s oauth.scopes.
Create .env.local in the project root. Replace my-fanvue-app with your app name and generate SESSION_SECRET with openssl rand -hex 32; it must be at least 32 characters.
OAUTH_SCOPES must list only scopes your app has on the Authentication tab or in its manifest’s oauth.scopes. Requesting a scope the app lacks fails the authorisation request.
Never commit .env.local to version control. A committed client secret acts on every account that authorised your app; if one leaks, click Reset secret on the Authentication tab.
5) Install and run locally
Install dependencies and start the Next.js dev server:
In a second terminal, start the local SSL proxy, again with your app name in place of my-fanvue-app:
Visit https://my-fanvue-app.dev:3001 (with your app name) and click Login with Fanvue. Sign in and approve the scopes. The browser returns to the app, which renders your current user as JSON.
6) Deploy to production
- Set the same environment variables in your hosting provider, with
OAUTH_REDIRECT_URI set to your production callback, for example https://your-app.com/api/oauth/callback
- Add that production redirect URI on the Authentication tab, or in your manifest’s
oauth.redirectUris followed by Check now on the Versions tab
- Build and run
How the starter works
- Next.js App Router with an OAuth callback at
/api/oauth/callback
- A session cookie named by
SESSION_COOKIE_NAME, signed with SESSION_SECRET
- Server-side calls to
API_BASE_URL using the session’s access token
- In local development, the SSL proxy forwards HTTPS requests to the Next.js dev server
To change it:
- UI and login experience:
src/app/page.tsx
- OAuth callback and session handling:
src/app/api/oauth/callback/route.ts
- API calls after login: server routes under
src/app/api/** using the session’s access token
Using the SDK without the starter
@fanvue/builder-sdk/nextjs/off-platform exports the same flow as route handlers: createLoginHandler ({ GET }), createCallbackHandler ({ GET, POST }) and createLogoutHandler ({ POST }), plus getSession and getAuthenticatedClient for server code.
The SDK reads OAUTH_CLIENT_ID, OAUTH_CLIENT_SECRET, OAUTH_REDIRECT_URI and SESSION_SECRET from the environment. It stores the session in a fanvue_session cookie that is HttpOnly, SameSite=Lax, lasts 30 days, and is Secure when served over HTTPS. Off-platform apps with the Builder SDK is the full guide.
Troubleshooting
- Invalid redirect URI:
OAUTH_REDIRECT_URI must exactly match one of your app’s redirect URIs, including the https:// scheme and port 3001. If your manifest sets them, the Versions tab must show Up to date
- Scope mismatch: every scope in
OAUTH_SCOPES must be among your app’s scopes (the starter uses read:self)
- Missing session secret: set
SESSION_SECRET to a random string of at least 32 characters
- Certificate errors in browser: run
mkcert -install to install the local CA certificate
- Cannot reach app at .dev domain: check the hosts file entry with
grep my-fanvue-app.dev /etc/hosts
- Proxy connection refused: start the Next.js dev server on port 3000 before starting the proxy
- Port already in use: if port 3000 or 3001 is taken, stop the other service or change both the proxy ports and the redirect URI
- Blank page after login: open browser DevTools and your terminal, then check that every env var is set, the proxy is running and the callback route is reachable
Next steps
- Add scopes both on your app (the Authentication tab, or your manifest’s
oauth.scopes) and in OAUTH_SCOPES. Adding a scope makes every existing user authorise again.
- Call other endpoints, such as chats or followers, from your server routes.
- Protect pages with middleware that checks the session.
- Set up a test creator account so development never touches your real profile.