Setting up your project
For the Business website template on Next.js 16 with Cloudflare. Only what your project uses, in the order to do it.
Build this guide for your project
1. Run the project
- 1Unzip the download and open a terminal in the folder. Run
npm install. - 2Run
npm run devand openhttp://localhost:3000. This is a Next.js 16 project (Turbopack by default); it needs Node 20 or newer. - 3The
README.mdinside the project repeats this guide under Go live, so you can hand the folder to someone else.
Pages in the Business website template
//products/pricing/about/support/contact/terms/privacy
With Cloudflare on, this project deploys as static assets (no server code, so no Worker to run). The Cloudflare section below covers that mode.
2. Cloudflare (hosting, DNS and domain)
Your project deploys to Cloudflare with npm run deploy. If it uses Supabase or Resend it runs as a Cloudflare Worker (full Next.js, via OpenNext); otherwise it is exported as static files and served from Cloudflare's edge. Either way the free tier is enough to start.
Deploy for the first time
- 1Cloudflare's tool (Wrangler) needs Node.js 22 or newer. Check with
node -v; if you are on an older version, install the current LTS from nodejs.org or withnvm install 22. - 2Create an account at dash.cloudflare.com. No card needed for the free plan.
- 3In the project folder run
npx wrangler login. A browser window asks you to allow Wrangler; approve it and come back to the terminal. - 4Optional but recommended: run
npm run previewto build and run the site locally exactly as it will run on Cloudflare. Open the printed URL, click around, then stop it with Ctrl+C. - 5Run
npm run deploy. The first time, Wrangler asks to create the Worker. When it finishes it prints a URL ending in.workers.dev. Open it: your site is live.
Every later deploy is the same single command. Deploys take about a minute and are atomic: visitors never see a half-updated site.
Set your production keys
- 1Run
npm run cf:secrets. It reads.env.localand pushes every value to Cloudflare as a Worker secret, the publicNEXT_PUBLIC_ones included: your deployed site reads them at request time, and Cloudflare only knows what you have pushed. Re-run it whenever you change a value. - 2Public values also need to be in
.env.localwhen you runnpm run deploy, because the browser side of the site gets them inlined at build time. Keep the file filled in and both sides agree. - 3You can also see and edit them in the dashboard: Workers & Pages → your Worker → Settings → Variables and Secrets.
Static sites have no server-side values, so this step does not apply to them.
Deploy from CI (optional)
- 1Create an API token at My Profile → API Tokens → Create Token → Create Custom Token with exactly these permissions, each an Account row, scoped to your account: Workers Scripts · Edit, Account Settings · Read. Nothing else is needed for
npm run deploy. - 2In your CI, set
CLOUDFLARE_API_TOKENandCLOUDFLARE_ACCOUNT_ID(the account id is on the dashboard's overview page), then runnpm ciandnpm run deploy. Wrangler uses the token instead of a browser login.
These are the same permissions BytesJoy's own weekly check deploys with, so they are known to be sufficient.
Use your own domain
- 1Buy a domain in Cloudflare → Domain Registration (at-cost pricing), or add one you already own with Add a domain and switch its nameservers to the two Cloudflare gives you at your current registrar. Nameserver changes take minutes to a day.
- 2Open Workers & Pages → your Worker → Settings → Domains & Routes → Add → Custom domain, and enter
yourdomain.com. Cloudflare creates the DNS record and certificate for you. Addwww.yourdomain.comthe same way if you want both. - 3Visit the domain. HTTPS works automatically.
Update the other providers for production
- 1Supabase: under Authentication → URL configuration, set the Site URL to
https://yourdomain.comand addhttps://yourdomain.com/auth/callbackto Redirect URLs. - 2Resend: the sending domain you verified should be this domain or a subdomain of it. If your DNS is on Cloudflare now, add the Resend DNS records under DNS → Records.
- 3If you changed any
NEXT_PUBLIC_value, runnpm run deployagain so it is rebuilt in.
What was added to your project
wrangler.jsoncopen-next.config.ts and scripts/cf-secrets.mjs (Worker mode)next.config.ts: images.unoptimized, plus output: "export" in static modenpm scripts: preview, deploy, cf:secrets, cf:typegen
If something goes wrong
- “Wrangler requires at least Node.js v22”: Upgrade Node:
nvm install 22 && nvm use 22, or download it from nodejs.org. The site itself runs on Node 20+, only the deploy tool needs 22. - “You are not authenticated” or “not logged in”: Run
npx wrangler loginagain. On a server or CI, setCLOUDFLARE_API_TOKENinstead. - Deploy fails with a size limit error: The free plan allows a 3 MB compressed Worker, paid plans 10 MB. Remove unused dependencies, or upgrade the plan.
- Forms or sign-in work locally but not on the deployed site (a setup notice, or “not configured”): The site's values are missing on Cloudflare. Fill in
.env.local, runnpm run cf:secrets, thennpm run deployagain. - Changed a NEXT_PUBLIC_ value but the site still shows the old one: Those are compiled in. Run
npm run deployagain after changing.env.local. - Custom domain shows an error page or old DNS: Make sure the domain's nameservers point at Cloudflare and that you added it under the Worker's Domains & Routes, not just as a DNS record.
Missing something? See the full reference. Back to the builder