Function
The origin, without a trailing slash, so a pathname can be appended
Every absolute URL the site emits — metadataBase, the canonical link, the
hreflang alternates, og:url — is built on this. It is resolved rather
than configured because the correct answer differs per environment: a
production deployment, a Vercel preview whose hostname changes on every push,
and a local dev server on whatever port it managed to bind are three
different origins, and only the first is known ahead of time.
Resolution order, first match wins:
NEXT_PUBLIC_SITE_URL — an explicit override, and the production answerVERCEL_PROJECT_PRODUCTION_URL — the project's stable production domainVERCEL_URL — this specific deployment, so a preview describes itself
rather than advertising productionhttp://localhost:${PORT ?? 3000}A value that is set but not an absolute http(s) URL throws instead of
falling through to the next candidate. Falling through would turn a typo into
a production site quietly advertising a preview origin — and the symptom of a
missing origin is invisible in the running app: Next emits relative
og:image and og:url values, nothing errors, and crawlers drop them.
Read at call time, not at module load, so a value set after import is seen.
The absolute origin the application publishes about itself.