Skip to content

fix(web): inline the build-time site origin for the function runtime - #245

Merged
damianrosellen1 merged 1 commit into
mainfrom
fix/site-origin-netlify-runtime
Oct 27, 2026
Merged

damianrosellen1 merged 1 commit into
mainfrom
fix/site-origin-netlify-runtime

Conversation

@damianrosellen1

@damianrosellen1 damianrosellen1 commented Oct 24, 2026 •

Copy link
Copy Markdown
Collaborator

On Netlify, canonicals, hreflang, og:url and the sitemap fell back to http://localhost:3000 on any deploy without NEXT_PUBLIC_SITE_URL, deploy previews always. siteUrl.ts reads Netlify's URL / DEPLOY_PRIME_URL at module load, but those only exist at build: the function runtime that serves ISR regenerations and route handlers doesn't have them. Found in a project built from the starter.

1. Inline the build-time origin (web/next.config.ts)
next.config.ts imports SITE_BASE_URL and sets NEXT_PUBLIC_SITE_URL: SITE_BASE_URL in env, so the value resolved at build is what every later render reads. An explicit NEXT_PUBLIC_SITE_URL still wins; a deploy host with nothing resolvable now fails at config load instead of later.

2. Production context takes URL (web/src/utils/siteUrl.ts)
netlifyOrigin() uses URL when isProduction || CONTEXT === "production". A staging site on the development dataset (SANITY_STUDIO_DEPLOYMENT_TARGET=development on the production context) serves its primary domain; DEPLOY_PRIME_URL there is the <branch>-- host. Doc comments in siteUrl.ts and isProductionDeployment updated to match.

Verified

  • Resolver per context: production → URL; production + target development → URL; deploy preview / branch deploy → DEPLOY_PRIME_URL; runtime with only the inlined value → that value; Netlify with nothing → throws; local → http://localhost:3000.
  • Local next build without any host variables succeeds; required-server-files.json carries NEXT_PUBLIC_SITE_URL: "http://localhost:3000".
  • pnpm typecheck, pnpm lint, pnpm format (no diff).
  • Deploy preview of this PR: canonical, hreflang, og:url and sitemap.xml use https://deploy-preview-245--…. So did preview fix: Presentation connects again from the Sanity Dashboard #243 before the fix: these pages are prerendered at build, where the old code already resolved.

Not verified: the runtime path the fix targets (an ISR regeneration or route handler on Netlify). It needs a revalidation on a deployed site.

Variant-Port: #246

🤖 Generated with Claude Code

`siteUrl.ts` falls back to Netlify's `URL` / `DEPLOY_PRIME_URL`, which only
exist at build. The function runtime that serves ISR regenerations and route
handlers lacks them, so canonicals and the sitemap fell back to
`http://localhost:3000` on every deploy without `NEXT_PUBLIC_SITE_URL`,
deploy previews included. `next.config.ts` now resolves the origin at build
and inlines it as `NEXT_PUBLIC_SITE_URL`.

Netlify's production context now always takes `URL`: a staging site on the
development dataset (`SANITY_STUDIO_DEPLOYMENT_TARGET=development`) serves
the primary domain, where `DEPLOY_PRIME_URL` is the `<branch>--` host.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Copilot AI balanced review requested due to automatic review settings October 24, 2026 11:08
@netlify

netlify Bot commented Oct 24, 2026 •

Copy link
Copy Markdown

✅ Deploy Preview for bef-next-sanity-starter ready!

Name Link
🔨 Latest commit 18e6f96
🔍 Latest deploy log https://app.netlify.com/projects/bef-next-sanity-starter/deploys/6adc91c95a3a7d2c4152fa94
😎 Deploy Preview https://deploy-preview-245--bef-next-sanity-starter.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

The build-to-function handoff central to this fix remains unverified on a real Netlify deployment.

No open issues 🎉

What changed in this PR

This PR preserves the build-time site origin for later server renders, preventing Netlify metadata and sitemap URLs from falling back to localhost when runtime host variables are unavailable.

Changes:

  • Inlines the resolved origin as NEXT_PUBLIC_SITE_URL through Next.js configuration.
  • Uses Netlify’s primary domain in production context, including staging sites using the development dataset.
  • Updates comments to explain origin resolution and deployment behavior.
File Description
web/​src/​utils/​siteUrl.ts Adjusts Netlify origin selection and documents build-time resolution.
web/​next.config.ts Inlines the resolved site origin for application runtime use.
packages/​sanity-dataset-resolve/​src/​index.ts Updates documentation for the Netlify canonical-origin exception.

Review effort: Balanced

@damianrosellen1

Copy link
Copy Markdown
Collaborator Author

Runtime check: build env ≠ runtime env

Simulated the Netlify function runtime locally to check that the origin survives an ISR regeneration.

Setup, run for both the merge-base (4c26529d) and this branch (18e6f969):

  1. next build with NETLIFY=true CONTEXT=deploy-preview URL=https://primary-site.example DEPLOY_PRIME_URL=https://deploy-preview-245--primary-site.example
  2. next start with those four variables unset
  3. Read canonical, og:url, hreflang of /docs and the first <loc> of sitemap.xml
  4. Signed webhook POST /api/revalidate with {"_type":"page"} → {"revalidated":true,"tags":["pages","site-pages"]}
  5. Fetch both again (the regenerated render)

Result

4c26529d (main) 18e6f969 (this PR)
From the build deploy-preview origin deploy-preview origin
After revalidation: canonical http://localhost:3000/docs ❌ https://deploy-preview-245--primary-site.example/docs ✅
og:url localhost ❌ deploy-preview origin ✅
hreflang (en, de, x-default) localhost ❌ deploy-preview origin ✅
sitemap <loc> localhost ❌ deploy-preview origin ✅

On main the bug reproduces: without NETLIFY at runtime the resolver falls through to the local fallback, with no error. On this branch the inlined NEXT_PUBLIC_SITE_URL keeps the build-time origin. In both runs en/docs.html and the sitemap were rewritten after the build had finished, so the value on this branch comes from a runtime render, not from the build output.

Not covered: next start is not Netlify's function runtime or cache handler; only the missing build variables are reproduced. The new CONTEXT === "production" branch was not part of this run.

@damianrosellen1
damianrosellen1 merged commit 406c7ec into main Oct 27, 2026
12 checks passed
@damianrosellen1
damianrosellen1 deleted the fix/site-origin-netlify-runtime branch October 27, 2026 13:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants