Dosu LogoDosu Logo
Ask
Join our Discord
Waline's SpacePublic
Waline
DocumentsWaline's Space
Server Base URL Resolution
Server Base URL Resolution
Type
Topic
Status
Published
Created
Jul 27, 2026
Updated
Jul 27, 2026
Created by
Dosu Bot
Updated by
Dosu Bot

Server Base URL Resolution#

serverURL is a per-request computed property on the ThinkJS context that provides an absolute base URL for the Waline server. It is the single source of truth for constructing all outbound URLs — OAuth redirects, email verification links, RSS feeds, and the admin dashboard's API endpoint.

Resolution Logic#

The serverURL getter in packages/server/src/config/extend.js applies this priority chain:

  1. SERVER_URL env var — if set, it is returned verbatim. Use this whenever the server is behind a reverse proxy, load balancer, or any configuration where the observed host header differs from the public URL.
  2. Netlify environment — detected via think.env === 'netlify' . The base URL becomes ${protocol}://${host}${netlifyFunctionPrefix}, where netlifyFunctionPrefix is derived from the _HANDLER environment variable . This prefix accounts for Netlify Functions' path structure (e.g. /.netlify/functions/server).
  3. Request protocol + host fallback — ${protocol}://${host}, derived directly from the incoming HTTP request. This is the default for self-hosted or Vercel/Railway deployments that surface the correct host header.

Important: If your deployment sits behind a reverse proxy and the host header is an internal name, you must set SERVER_URL explicitly or all server-generated links will be broken.

Consumers of ctx.serverURL#

FeatureFileUsage
Admin dashboard bootstrapmiddleware/dashboard.js:19Sets window.serverURL = '${ctx.serverURL}/api/' so the SPA knows the API root
OAuth redirect URLscontroller/oauth.js:14-15, 33-37Builds the redirect callback passed to the OAuth provider
User registration emailcontroller/user.js:94-97Constructs the /verification?token=…&email=… link
Password reset emailcontroller/user/password.js:25Constructs the /ui/profile?token=… link
RSS feed channel linkcontroller/comment/rss.js:61Falls back to ctx.serverURL when SITE_URL env var is absent
Akismet spam checkcontroller/comment.jsPasses the server URL to the Akismet API

RSS Feed: SITE_URL vs SERVER_URL#

The RSS controller resolves its channel link as process.env.SITE_URL || this.ctx.serverURL . SITE_URL is the public-facing blog/site URL, while SERVER_URL is the Waline API server URL — they are often different. The buildAbsoluteUrl helper then prepends the resolved base URL to relative comment paths, short-circuiting if the path is already an absolute URL.

Demo Page: Client-Side serverURL#

The root indexAction in controller/index.js derives serverURL client-side using location.protocol + '//' + location.host + location.pathname.replace(/\/+$/, ''). This is only used for the built-in example/demo page and does not interact with the server-side ctx.serverURL getter.

Key Files#

  • Resolution logic: packages/server/src/config/extend.js — the serverURL getter
  • Netlify detection: packages/server/src/config/netlify.js — isNetlify + netlifyFunctionPrefix
  • Dashboard injection: packages/server/src/middleware/dashboard.js
  • OAuth redirect construction: packages/server/src/controller/oauth.js
  • RSS feed construction: packages/server/src/controller/comment/rss.js
Documents
Comment Management Admin Panel
Docker Image Build & Release
Markdown Math Rendering
Request Origin & Referer Validation
Server Base URL Resolution