Skip to content

feat(website): serve the site at nostream.dev and redirect every other host to it - #889

Merged
cameri merged 4 commits into
mainfrom
website/nostream-dev
Oct 18, 2026
Merged

cameri merged 4 commits into
mainfrom
website/nostream-dev

Conversation

@chappie-daemon

Copy link
Copy Markdown
Collaborator

The site's canonical origin moves to https://nostream.dev. Previews stay on ema.tnsor.network — a broken PR build must never sit on the domain that is the project's public face.

What changes

file change
wrangler.jsonc custom domain → nostream.dev
wrangler.router.jsonc binds nostream.dev, www.nostream.dev, keeps ema.tnsor.network; adds vars.CANONICAL_HOST
worker/router.ts http → 301 https; non-canonical host → 301 canonical
astro.config.mjs, README.md, package.json domain updated
build-social-card.mjs + both PNGs card regenerated with nostream.dev
deploy-website.yml SITE_URL + CANONICAL_HOST, the worker gets --var
deploy-website-preview.yml previews keep the preview origin, with the reason written down

Redirect policy

  • http:// anything → 301 to the same URL over https, previews included
  • a non-canonical host → 301 to nostream.dev, keeping path and query
  • preview paths are exempt from the host redirect — they are served from their own domain

Three defects found by exercising the worker, fixed here

  1. Response.redirect re-encodes an encoded path: /docs/a%20b → /docs/a%2520b, a path that does not exist. The redirect writes its own Location.
  2. The first draft 301'd ema.tnsor.network/preview/888/ to nostream.dev/preview/888/.
  3. The same draft treated a port-carrying host as canonical and issued no redirect.

Measured after the fixes:

https upgrade                301 https://nostream.dev/docs/x
http on www                  301 https://www.nostream.dev/
www→apex keeps encoded path  301 https://nostream.dev/docs/a%20b?y=1
stale domain to canonical    301 https://nostream.dev/about
preview untouched            200 -
canonical served             200 -

Verification

  • pnpm run build → 14 pages, canonical/og:url/og:image all https://nostream.dev, no ema.tnsor.network left in dist/
  • wrangler deploy --dry-run bundles with env.CANONICAL_HOST ("nostream.dev") bound
  • card headers still 1200×630 and 1280×640

Needs Cloudflare-side setup, not code

  1. the nostream.dev zone must exist before the deploy binds it
  2. Always Use HTTPS on the zone is the edge-level version of the same redirect; the worker's own 301 covers the case where it is off
  3. the repo's Homepage field is still http://ema.tnsor.network — a settings change, not a file

@chappie-daemon
chappie-daemon deployed to website-preview October 18, 2026 14:56 — with GitHub Actions Active
@changeset-bot

changeset-bot Bot commented Oct 18, 2026 •

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 3860762

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
nostream-website Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@github-actions

github-actions Bot commented Oct 18, 2026 •

Copy link
Copy Markdown
Contributor

🧹 Site preview for this PR was deleted (PR closed).

@greptile-apps

greptile-apps Bot commented Oct 18, 2026 •

Copy link
Copy Markdown

RetriggerView in GreptileConfidence Score: 4/5

[High impact] Changes website domain and adds host-based routing logic.

Do not merge until preview requests stop looping between the preview and production domains.

Findings

  1. P1 Previews redirect forever ▶

Summary

Moves the public website to https://nostream.dev and adds redirects from other hosts.

  • The website redirects other hosts to nostream.dev and keeps previews on their own domain.

Diagram

%%{init: {'theme': 'neutral'}}%%
flowchart LR
  A["ema.tnsor.network/preview/888/"] -->|"301: non-canonical host"| B["nostream.dev/preview/888/"]
  B -->|"301: preview on production"| A
Loading

Reviews (3) · Last reviewed commit: "fix(website): no redirect loop with no c..." · Reviewed by Greptile

Comment thread website/site/wrangler.router.jsonc
Comment thread website/site/worker/router.ts Outdated
…r host to it

The site's canonical origin moves from ema.tnsor.network to https://nostream.dev.
Previews keep the preview domain: a broken PR build must never sit on the domain
that is the public face of the project.

The router worker now binds nostream.dev and www.nostream.dev alongside
ema.tnsor.network, and CANONICAL_HOST decides which host serves content:

- http -> 301 to the same path over https, for every host, preview paths
  included (the proxy hop to the preview worker is already https);
- a non-canonical host -> 301 to the canonical one, keeping path and query.
  Preview paths are exempt, because they are served from their own domain and a
  redirect would move every preview off the origin its links name;
- everything else -> the static assets, as before.

The domain is an input rather than a constant. SITE_URL (build) and
CANONICAL_HOST (worker, passed with --var) are both set in deploy-website.yml,
so a future move is two lines instead of a search through the source, the README
and the social card.

Three defects were found by exercising the worker before writing it down, and
fixed in the same change:

1. `Response.redirect` re-encodes an already-encoded path - `/docs/a%20b` came
   back as `/docs/a%2520b`, a path that does not exist. The redirect writes its
   own Location from url.origin + url.pathname + url.search.
2. The first host-redirect draft ran before the preview match, so
   `ema.tnsor.network/preview/888/` was 301'd to nostream.dev/preview/888/.
3. The same draft treated a port-carrying host as canonical and issued no
   redirect at all; the comparison uses the bare host.

The social card is regenerated with the new domain in its footer (both PNGs,
1200x630 and 1280x640, regenerated at their own sizes). Verified: the site
builds with canonical/og:url/og:image all on https://nostream.dev and no
ema.tnsor.network left in dist/; the worker passes wrangler's bundler with
env.CANONICAL_HOST bound.

Cloudflare setup this needs, not code: the nostream.dev zone must exist, and
Always Use HTTPS on the zone makes the upgrade happen at the edge before the
worker (the worker's own 301 covers the case where it is off).
… prod host

Two review findings, both real and both verified by exercising the worker.

1. Static pages skipped the redirects. Cloudflare serves a matching static
   asset before invoking the worker unless `assets.run_worker_first` is set,
   and this deployment's assets are the whole site - every built route is a
   file. So `www.nostream.dev/` and `ema.tnsor.network/` would have answered
   200 with the page, and the host redirect would have run only on paths that
   did NOT match an asset, i.e. almost never. `run_worker_first: true` puts the
   worker back in front, which is what a router is.

2. Previews were reachable from the production domain. The preview branch
   proxied `/preview/<n>/` from any host, so once `nostream.dev` was bound,
   `https://nostream.dev/preview/<n>/` would serve a pull request's build on
   the site's own address. Previews now answer only from PREVIEW_HOST; a
   preview path on the canonical host is 301'd to PREVIEW_HOST, and a preview
   path on www or the stale domain is proxied in place (it is not the
   production host, so no PR build lands on a domain people trust).

Exercised after the change:

  http -> https                    301 https://nostream.dev/docs/x
  http preview -> https            301 https://ema.tnsor.network/preview/888/
  www -> apex (encoded path kept)  301 https://nostream.dev/docs/a%20b?y=1
  stale host -> canonical          301 https://nostream.dev/about
  preview on preview host          200
  preview on PROD host             301 https://ema.tnsor.network/preview/888/
  preview via www                  200
  canonical served                 200

wrangler deploy --dry-run bundles with run_worker_first and CANONICAL_HOST.
Comment thread website/site/worker/router.ts Outdated
Comment thread website/site/worker/router.ts Outdated
…e whole authority

Two review findings on the host layer.

1. With CANONICAL_HOST empty the layer inverted: `onCanonical` defaulted to
   true, so a preview request was 301'd to the URL it was already on, forever,
   and the documented "unset disables the redirects" behaviour became "unset
   breaks previews". Unset now leaves the request alone, which is what
   documented means.

2. The comparison used `url.hostname`, which drops the port, so
   `nostream.dev:8443` counted as canonical and served the pages without
   redirecting - a second origin for the same content, the thing the redirect
   exists to prevent. The comparison is now against `url.host`, so a port the
   config does not name is a different authority.

The first fix exposed a third defect that neither finding named: a preview on
PREVIEW_HOST was 301'd to the canonical host, whose preview branch then 301'd
it back - a two-hop loop. Restructured so exactly one rule can move a preview
off the production domain and nothing moves it anywhere else.

Exercised with and without the variable, and with a configured port:

  http -> https                            301 https://nostream.dev/docs/x
  http preview -> https                    301 https://ema.tnsor.network/preview/8/
  www -> apex (encoded path kept)          301 https://nostream.dev/a%20b?y=1
  stale host -> canonical                  301 https://nostream.dev/about
  preview host -> canonical                301 https://nostream.dev/preview/888/
  prod host preview -> preview host        301 https://ema.tnsor.network/preview/888/
  canonical served                         200
  port on canonical -> stripped            301 https://nostream.dev/about
  CANONICAL unset: preview served          404 (proxied, no loop)
  CANONICAL unset: page served             200
  configured port: canonical served        200
  configured port: default port -> redirect 301 https://nostream.dev:8443/about
@chappie-daemon
chappie-daemon deployed to website-preview October 18, 2026 15:18 — with GitHub Actions Active
Comment thread website/site/worker/router.ts Outdated
…them back

Greptile caught what my own matrix could not: the previous fix made
`ema.tnsor.network/preview/888/` redirect to `nostream.dev/preview/888/`, whose
preview rule redirects to `ema.tnsor.network/preview/888/` - a two-host
browser redirect loop. Neither hop reaches the preview worker.

The matrix reported "preview host: redirect to canonical 301 ..." as correct.
It is not: one hop is only correct if the destination serves the page, and the
destination's own rule sends it back. The check that catches this class is
walking the chain the way a browser does, not asserting a single hop - which is
what this commit adds to the reasoning, and what the evidence below records.

A preview path on PREVIEW_HOST is now served in place by the proxy branch;
every other authority still converges on the canonical host, and previews on
the production host still move to PREVIEW_HOST once, then stop there.

Chain walks, six starts, no path revisits a URL:

  ema.../preview/888/                 -> 404        (proxied, one hop, terminal)
  ema.../preview/888/docs/x?y=1       -> 404        (query and path preserved)
  http://ema.../preview/888/          -> https ema  -> 404
  ema.../about                        -> nostream.dev/about -> 200
  nostream.dev/preview/888/           -> ema.../preview/888/ -> 404
  nostream.dev/about                  -> 200
  www.nostream.dev/                   -> nostream.dev/ -> 200
@chappie-daemon
chappie-daemon deployed to website-preview October 18, 2026 16:47 — with GitHub Actions Active
@cameri
cameri merged commit eb68475 into main Oct 18, 2026
13 checks passed
@cameri
cameri deleted the website/nostream-dev branch October 18, 2026 16:56
@cameri
cameri deployed to website-preview October 18, 2026 16:56 — with GitHub Actions Active

This branch was successfully deployed

1 active deployment
website-preview — 38607620 Deployed Oct 18, 2026 by cameri via preview #71
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.

3 participants