Today Platform Web — Dev Docs
Architecture

China domain routing

How today.ai redirects mainland China page navigations without intercepting embed, API, or resource requests.

The Vercel project redirects eligible mainland China page navigations from today.ai to todayai.cn. This rule is deliberately narrower than a generic geo redirect: it must never capture API traffic, embed bootstrap traffic, or page subresources.

The redirect matcher lives in apps/web/vercel.ts. Shared bypass names and values live in apps/web/domain-routing.mjs.

Redirect decision

A request redirects only when every positive condition is true and no bypass is present:

(mainland China OR explicit simulation)
AND explicitly allowlisted public entry path
AND Sec-Fetch-Dest: document
AND Sec-Fetch-Mode: navigate
AND no session cookie
AND no bypass header
AND no bypass cookie
AND no bypass query
AND not continuing a same-origin navigation on today.ai

The two Fetch Metadata headers are the primary request-type boundary:

  • Sec-Fetch-Dest: document identifies a top-level document. Subframes use iframe, and resources use destinations such as image, script, style, or font.
  • Sec-Fetch-Mode: navigate confirms browser navigation rather than fetch, XHR, or a resource load.

Both headers are required. If either is absent, malformed, or carries another value, the request stays on today.ai. This fail-safe behavior supports older WebViews and non-browser clients without guessing from Accept, a filename extension, or a user agent.

Sec-Fetch-User is not part of the rule. It is present only for some user-activated navigations, so requiring it would miss address-bar entry, reloads, redirects, and programmatic navigations that are still valid page loads.

Public entry allowlist

Only these exact paths can trigger the redirect (with an optional trailing slash):

  • /
  • /landing
  • /waitlist
  • /downloads

Every other path stays on its original origin by default. This includes login, OAuth authorization and callbacks, password recovery, invitations, authenticated app pages, shared content, SEO articles, embeds, APIs, and static resources. Unknown routes and descendants such as /downloads/child are not eligible. Adding a new page must not implicitly opt it into a cross-domain redirect.

Native authentication can start without a same-origin referrer or bypass cookie. Its login and OAuth URLs must therefore remain outside the allowlist regardless of Fetch Metadata. The top-level document check alone cannot distinguish an OAuth navigation from a public landing-page visit.

Bypasses

Any bypass keeps the request on today.ai:

  • Presence of better-auth.session_token, __Secure-better-auth.session_token, or __Secure-today.desktop_session bypasses the redirect. Only the exact cookie name matters: empty, expired, and unverified values also bypass. This is a routing hint; normal authentication still validates the session.
  • x-today-bypass-geo-redirect: true is the explicit per-request bypass for automation and controlled callers.
  • __Host-today-geo-redirect-bypass=1 is the host-wide routing bypass. The current Web application does not write this cookie.
  • bypass_geo_redirect=1 is the URL-scoped bypass for links that must remain on today.ai. It affects only request URLs that carry it and does not create persistent browser state.
  • A Referer beginning with https://today.ai/ keeps subsequent same-origin navigation on the international site.

The embed path itself is excluded from the redirect, so its document and subresources remain on their original origin without relying on a cookie.

The cookie is a host-only, full-site session cookie:

__Host-today-geo-redirect-bypass=1; Path=/; Secure; HttpOnly; SameSite=Lax

Path=/ makes it available to every request on the host. The __Host- prefix requires Secure, forbids Domain, and requires Path=/, preventing a subdomain or narrower path from changing its scope. It has no Expires or Max-Age, so it ends with the WebView or browser session.

This is routing state, not authentication. Vercel consumes it when evaluating the redirect. Do not reuse embed_bearer: that JWT remains scoped to /api/ and must not be broadened to the whole site.

Why classification happens on the request

Vercel must decide whether to redirect before the application produces a response, so response Content-Type cannot classify the request. The request's Fetch Metadata is the closest browser-provided description of the navigation context and is available at the redirect decision point.

Do not replace it with Accept: text/html, file-extension allowlists, or user agent detection. Those are hints rather than navigation identity: APIs may accept HTML, extensionless resources are common, and user agents are neither complete nor reliable.

Validation

The configuration tests cover geo and simulation rules, both Fetch Metadata requirements, incomplete headers, common resource destinations, iframe navigations, bypasses, the public entry allowlist, and protected and unknown paths:

pnpm --filter @todayai-labs/web exec vitest run \
  scripts/vercel-config.test.ts src/proxy.test.ts

For an end-to-end simulation, add all three request headers to a top-level page navigation:

x-today-simulate-geo-redirect: true
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate

An allowlisted public entry page should redirect to https://todayai.cn. Login, OAuth, callback, and unknown paths must stay on today.ai with the same headers. Changing the destination to image, changing the mode to cors, removing either Fetch Metadata header, or adding any bypass must keep the request on today.ai.

On this page