Project pages assume they are served at the site root, which breaks under a coilyco.ai vanity proxy #138

Open
opened 2026-08-28 05:16:57 +00:00 by coilyco-ops · 4 comments
Collaborator

Filed by tpm 2026-08-28 at Kai's request, out of a session on coilyco.ai vanity domains.

Context

Kai is putting project pages behind coilyco.ai subdomains, starting with umbra.coilyco.ai proxied to /projects/umbra. The mechanism is a Netlify rewrite rather than a redirect, status = 200, so the vanity hostname stays in the address bar. The name in the address bar is the entire point, so anything that navigates a visitor off umbra.coilyco.ai defeats the feature.

DNS facts as of filing: coilysiren.me resolves to 75.2.60.5, which is Netlify. coilyco.ai has Route 53 nameservers and nothing at the apex.

The problem, which is broader than it first looked

I originally flagged only absolute self-links, where an https://coilysiren.me/... href bounces the visitor off the vanity host on their first click. That is real but it is the smaller half.

The bigger issue is that the page's whole navigation assumes it is served at the site root. Read live, /projects/umbra links to:

  • /
  • /about/
  • /hiring/
  • /resume/
  • /projects/umbra/docs/
  • /projects/mcp-beaver/
  • /projects/agent-compose/
  • /images/marks/umbra.png

Under the proxy every one of those resolves against umbra.coilyco.ai, not coilysiren.me. What happens next depends entirely on how the rewrite is written, and both obvious spellings are wrong.

  • A rule of from = "https://umbra.coilyco.ai/*" to a fixed to = ".../projects/umbra" with force = true swallows every path, so /about/ silently serves the umbra page. That is worse than a 404 because nothing looks broken.
  • A rule without force leaves those paths to the normal site routing on a host that has no such pages, so they 404.

What I verified and what I did not

Verified, by fetching the live page: the link and asset targets listed above are what the page points at.

Not verified: whether those hrefs are written absolute or root-relative in source. The fetch normalised them, so it cannot distinguish the two, and I am not guessing. That is the first thing to check in the repo, because it decides whether this is one problem or two.

What to do

  1. Grep the project page templates and content for coilysiren.me. Any absolute self-link is a straight bug for this feature and should become root-relative regardless of what else is decided.
  2. Decide what the vanity subdomain is scoped to. Either it is a single page and the rewrite must map only the bare host and its own subpaths, or the whole site is reachable under the vanity host and the site-wide nav is fine but now serves duplicate content on two hostnames.
  3. Pick the nav behaviour deliberately. A visitor on umbra.coilyco.ai clicking Resume should probably land on coilysiren.me/resume/, which means those particular links want to be absolute on purpose. That is the opposite of step 1 for those links specifically, so the two need reconciling rather than a blanket rule.
  4. Check /projects/umbra/docs/ and the mark image, since a broken image is the most visible failure and the docs subpath is the one real nested route.
  5. Set a canonical on the proxied page pointing at the coilysiren.me URL, so two hostnames serving identical content does not become a search problem.

Priority

priority/P3. Nothing depends on it yet, because umbra.coilyco.ai does not exist. It is a prerequisite for that subdomain being worth pointing anyone at, rather than a defect in the site as it stands today. The site is fine right now. This only bites the moment the proxy goes up.

Not in scope

The coilyco.ai apex. It has no destination to proxy to and a landing page there is a separate piece of work, deliberately not folded in here.

Filed by tpm 2026-08-28 at Kai's request, out of a session on `coilyco.ai` vanity domains. ## Context Kai is putting project pages behind `coilyco.ai` subdomains, starting with **`umbra.coilyco.ai` proxied to `/projects/umbra`**. The mechanism is a Netlify **rewrite** rather than a redirect, `status = 200`, so the vanity hostname stays in the address bar. **The name in the address bar is the entire point**, so anything that navigates a visitor off `umbra.coilyco.ai` defeats the feature. DNS facts as of filing: `coilysiren.me` resolves to `75.2.60.5`, which is Netlify. `coilyco.ai` has Route 53 nameservers and nothing at the apex. ## The problem, which is broader than it first looked I originally flagged only **absolute self-links**, where an `https://coilysiren.me/...` href bounces the visitor off the vanity host on their first click. That is real but it is the smaller half. **The bigger issue is that the page's whole navigation assumes it is served at the site root.** Read live, `/projects/umbra` links to: * `/` * `/about/` * `/hiring/` * `/resume/` * `/projects/umbra/docs/` * `/projects/mcp-beaver/` * `/projects/agent-compose/` * `/images/marks/umbra.png` Under the proxy every one of those resolves against `umbra.coilyco.ai`, not `coilysiren.me`. **What happens next depends entirely on how the rewrite is written, and both obvious spellings are wrong.** * A rule of `from = "https://umbra.coilyco.ai/*"` to a **fixed** `to = ".../projects/umbra"` with `force = true` **swallows every path**, so `/about/` silently serves the umbra page. That is worse than a 404 because nothing looks broken. * A rule without `force` leaves those paths to the normal site routing on a host that has no such pages, so they 404. ## What I verified and what I did not **Verified**, by fetching the live page: the link and asset targets listed above are what the page points at. **Not verified**: whether those hrefs are written absolute or root-relative in source. The fetch normalised them, so it cannot distinguish the two, and I am not guessing. **That is the first thing to check in the repo**, because it decides whether this is one problem or two. ## What to do 1. **Grep the project page templates and content for `coilysiren.me`.** Any absolute self-link is a straight bug for this feature and should become root-relative regardless of what else is decided. 2. **Decide what the vanity subdomain is scoped to.** Either it is a single page and the rewrite must map only the bare host and its own subpaths, or the whole site is reachable under the vanity host and the site-wide nav is fine but now serves duplicate content on two hostnames. 3. **Pick the nav behaviour deliberately.** A visitor on `umbra.coilyco.ai` clicking Resume should probably land on `coilysiren.me/resume/`, which means those particular links want to be absolute on purpose. That is the opposite of step 1 for those links specifically, so the two need reconciling rather than a blanket rule. 4. **Check `/projects/umbra/docs/` and the mark image**, since a broken image is the most visible failure and the docs subpath is the one real nested route. 5. Set a `canonical` on the proxied page pointing at the `coilysiren.me` URL, so two hostnames serving identical content does not become a search problem. ## Priority **`priority/P3`.** Nothing depends on it yet, because `umbra.coilyco.ai` does not exist. It is a prerequisite for that subdomain being worth pointing anyone at, rather than a defect in the site as it stands today. **The site is fine right now.** This only bites the moment the proxy goes up. ## Not in scope The `coilyco.ai` apex. It has no destination to proxy to and a landing page there is a separate piece of work, deliberately not folded in here.
Author
Collaborator

Two corrections from measuring the live site

Both affect how this gets implemented, so recording them rather than leaving them in a session.

www is canonical, not the apex

Measured 2026-08-28:

  • https://coilysiren.me/ returns 301 with location: https://www.coilysiren.me/
  • https://www.coilysiren.me/ returns 200
  • DNS: www.coilysiren.me is a CNAME at coilysiren-dot-me.netlify.app, apex points at 75.2.60.5

So www.coilysiren.me is the Netlify primary domain and the bare apex is an alias redirected to it.

Step 5 in the body is wrong on this point. The canonical tag should point at the www.coilysiren.me URL, not the bare coilysiren.me one. A canonical pointing at a hostname that 301s is a self-inflicted extra hop.

The automatic primary-domain redirect is live, which raises the stakes on this issue

Netlify redirects non-primary domains to the primary by default, and the apex 301 above is that behaviour running in production on this site today.

That is the first thing to verify when umbra.coilyco.ai is wired up, before any of the link work here is worth doing. If the alias gets 301'd to www.coilysiren.me before the rewrite rule runs, the vanity hostname is gone from the address bar and this entire issue is moot until that is solved.

force = true is what is supposed to take precedence. Treat that as unverified. The check is loading https://umbra.coilyco.ai/ and watching whether the address bar holds.

Rewrite target should be a path, not a URL

For a status = 200 rewrite, use a site-relative target so the host question does not arise:

[[redirects]]
  from = "https://umbra.coilyco.ai/*"
  to = "/projects/umbra"
  status = 200
  force = true

A full-URL target of https://coilysiren.me/projects/umbra would take the apex-to-www 301 on every request.

## Two corrections from measuring the live site Both affect how this gets implemented, so recording them rather than leaving them in a session. ### www is canonical, not the apex Measured 2026-08-28: * `https://coilysiren.me/` returns **301** with `location: https://www.coilysiren.me/` * `https://www.coilysiren.me/` returns **200** * DNS: `www.coilysiren.me` is a CNAME at `coilysiren-dot-me.netlify.app`, apex points at `75.2.60.5` So **`www.coilysiren.me` is the Netlify primary domain** and the bare apex is an alias redirected to it. **Step 5 in the body is wrong on this point.** The canonical tag should point at the `www.coilysiren.me` URL, not the bare `coilysiren.me` one. A canonical pointing at a hostname that 301s is a self-inflicted extra hop. ### The automatic primary-domain redirect is live, which raises the stakes on this issue Netlify redirects non-primary domains to the primary by default, and the apex 301 above is that behaviour running in production on this site today. **That is the first thing to verify when `umbra.coilyco.ai` is wired up**, before any of the link work here is worth doing. If the alias gets 301'd to `www.coilysiren.me` before the rewrite rule runs, the vanity hostname is gone from the address bar and this entire issue is moot until that is solved. `force = true` is what is supposed to take precedence. **Treat that as unverified.** The check is loading `https://umbra.coilyco.ai/` and watching whether the address bar holds. ### Rewrite target should be a path, not a URL For a `status = 200` rewrite, use a site-relative target so the host question does not arise: ```toml [[redirects]] from = "https://umbra.coilyco.ai/*" to = "/projects/umbra" status = 200 force = true ``` A full-URL target of `https://coilysiren.me/projects/umbra` would take the apex-to-www 301 on every request.
Author
Collaborator

Measured the open question. Steps 1 and 5 are already satisfied, so this is one problem rather than two

The body names the absolute-versus-root-relative question as "the first thing to check in the repo" and leaves it explicitly unverified. Answered from the served HTML rather than the source, which is the artifact the rewrite actually acts on.

https://www.coilysiren.me/projects/umbra/, raw attributes as served:

href="/"  href="/about/"  href="/hiring/"  href="/resume/"
href="/projects/agent-compose/"  href="/projects/mcp-beaver/"
href="/projects/umbra/docs/"  href="/images/favicon.ico"
href="/styles/site.css"  href="/styles/prism-tomorrow.css"
src="/images/marks/umbra.png"  src="/project-toc.js"

The only absolute references to www.coilysiren.me on the page are five, and every one of them is supposed to be absolute:

<link rel="alternate" type="application/atom+xml" href="https://www.coilysiren.me/feed.xml">
<link rel="canonical" href="https://www.coilysiren.me/projects/umbra/">
<meta property="og:url" content="https://www.coilysiren.me/projects/umbra/">
<meta property="og:image" content="https://www.coilysiren.me/images/banners/umbra-card.jpg">
<meta name="twitter:image" content="https://www.coilysiren.me/images/banners/umbra-card.jpg">

So step 1 has nothing to fix. There is no absolute self-link in the navigation. The "straight bug for this feature" the body anticipated does not exist, and the smaller half of the problem is closed.

Step 5 is already done, and already correct

The canonical exists and already points at www, which is what the correction in the comment above asks for. It is not project-page-only. Measured across the site:

/                      <link rel="canonical" href="https://www.coilysiren.me/">
/about/                .../about/
/resume/               .../resume/
/hiring/               .../hiring/
/projects/umbra/docs/  .../projects/umbra/docs/

Site-wide, absolute, and on the primary host. The duplicate-content risk this issue raises is already mitigated by construction, on every page a vanity host could serve.

Which reconciles this with #133

#133 decided against subdomains on the grounds that they split authority, and this issue proposes subdomains. Those only conflict if the vanity host is indexable as its own site. It is not: a status = 200 rewrite serves pages that already carry an absolute canonical pointing back at www.coilysiren.me. Search engines consolidate on the canonical, so authority still lands in one pool and #133's argument survives the mechanism intact.

Worth stating in one of the two issues, because a future reader finding both will otherwise think a decision was reversed.

What is actually left

One problem, the one the body correctly called the bigger half: root-relative links resolve against the vanity host. Since the nav is entirely root-relative and the canonical is already right, the safe shape is the second option in step 2, serving the whole site under the vanity host rather than a single page:

[[redirects]]
  from = "https://umbra.coilyco.ai/*"
  to = "/:splat"
  status = 200
  force = true

Nav then works, assets resolve, /projects/umbra/docs/ works, and every page still declares its canonical on www. The cost is that umbra.coilyco.ai/resume/ exists and serves the resume, which is odd but harmless and already canonicalised. Mapping the bare host to /projects/umbra and letting everything else splat is the variant worth trying first if that oddness matters.

Still unverified and still the gating question, unchanged from the comment above: whether Netlify's automatic primary-domain redirect fires before force = true. Nothing here can be tested until umbra.coilyco.ai exists.

Live DNS, since the body's facts are a day old

coilyco.ai still has Route 53 nameservers and no records at all: apex, www, and umbra all resolve to nothing. coilysiren.me still 301s to www, which serves 200. So nothing has moved and this remains prospective.

## Measured the open question. Steps 1 and 5 are already satisfied, so this is one problem rather than two The body names the absolute-versus-root-relative question as "the first thing to check in the repo" and leaves it explicitly unverified. Answered from the served HTML rather than the source, which is the artifact the rewrite actually acts on. ### Every internal link and asset is root-relative `https://www.coilysiren.me/projects/umbra/`, raw attributes as served: ``` href="/" href="/about/" href="/hiring/" href="/resume/" href="/projects/agent-compose/" href="/projects/mcp-beaver/" href="/projects/umbra/docs/" href="/images/favicon.ico" href="/styles/site.css" href="/styles/prism-tomorrow.css" src="/images/marks/umbra.png" src="/project-toc.js" ``` The only absolute references to `www.coilysiren.me` on the page are five, and every one of them is supposed to be absolute: ``` <link rel="alternate" type="application/atom+xml" href="https://www.coilysiren.me/feed.xml"> <link rel="canonical" href="https://www.coilysiren.me/projects/umbra/"> <meta property="og:url" content="https://www.coilysiren.me/projects/umbra/"> <meta property="og:image" content="https://www.coilysiren.me/images/banners/umbra-card.jpg"> <meta name="twitter:image" content="https://www.coilysiren.me/images/banners/umbra-card.jpg"> ``` **So step 1 has nothing to fix.** There is no absolute self-link in the navigation. The "straight bug for this feature" the body anticipated does not exist, and the smaller half of the problem is closed. ### Step 5 is already done, and already correct The canonical exists and already points at `www`, which is what the correction in the comment above asks for. It is not project-page-only. Measured across the site: ``` / <link rel="canonical" href="https://www.coilysiren.me/"> /about/ .../about/ /resume/ .../resume/ /hiring/ .../hiring/ /projects/umbra/docs/ .../projects/umbra/docs/ ``` Site-wide, absolute, and on the primary host. **The duplicate-content risk this issue raises is already mitigated by construction**, on every page a vanity host could serve. ### Which reconciles this with #133 #133 decided against subdomains on the grounds that they split authority, and this issue proposes subdomains. Those only conflict if the vanity host is indexable as its own site. It is not: a `status = 200` rewrite serves pages that already carry an absolute canonical pointing back at `www.coilysiren.me`. Search engines consolidate on the canonical, so authority still lands in one pool and #133's argument survives the mechanism intact. Worth stating in one of the two issues, because a future reader finding both will otherwise think a decision was reversed. ### What is actually left One problem, the one the body correctly called the bigger half: **root-relative links resolve against the vanity host.** Since the nav is entirely root-relative and the canonical is already right, the safe shape is the second option in step 2, serving the whole site under the vanity host rather than a single page: ```toml [[redirects]] from = "https://umbra.coilyco.ai/*" to = "/:splat" status = 200 force = true ``` Nav then works, assets resolve, `/projects/umbra/docs/` works, and every page still declares its canonical on `www`. The cost is that `umbra.coilyco.ai/resume/` exists and serves the resume, which is odd but harmless and already canonicalised. Mapping the bare host to `/projects/umbra` and letting everything else splat is the variant worth trying first if that oddness matters. Still unverified and still the gating question, unchanged from the comment above: whether Netlify's automatic primary-domain redirect fires before `force = true`. Nothing here can be tested until `umbra.coilyco.ai` exists. ### Live DNS, since the body's facts are a day old `coilyco.ai` still has Route 53 nameservers and **no records at all**: apex, `www`, and `umbra` all resolve to nothing. `coilysiren.me` still 301s to `www`, which serves 200. So nothing has moved and this remains prospective.
Author
Collaborator

Decided: swapped chrome via build variants. Supersedes my allowlist recommendation above

Kai's call, 2026-08-28. The vanity host gets its own header and footer rather than inheriting the site nav. That changes the shape of this issue enough that my previous comment's to = "/:splat" rule should not be built.

A status = 200 rewrite cannot do this on its own. It serves identical bytes and the origin never learns the Host, so swapped chrome has to exist as built output or be assembled at the edge. Build variants win here: base.njk already includes nav and footer at two lines, so this is a flag and a second include rather than a runtime dependency.

The swap dissolves most of this issue

Two findings from reading the repo that shrink the problem:

  • footer.njk contains no links. It is a name block. Swapping it is cosmetic and nothing routes through it.
  • The whole nav surface is five links in two files. nav.njk carries the brand href="/", and links.njk carries /about/, /hiring/, /resume/ plus a GitHub link that is already absolute.

So the "visitor bounces off the vanity host" problem was never routing. It was the shared nav. Vanity chrome that does not link to those paths removes the need for a path allowlist or denylist entirely, and the brand-link conflict I raised earlier (/ is both the vanity root and Home) disappears, because vanity chrome can link Home absolutely to www.coilysiren.me.

What changes

Templates. A vanity flag on the page, base.njk selecting nav-vanity.njk and footer-vanity.njk when set. The vanity nav links outward absolutely; the vanity footer carries the "part of coilysiren.me" line.

Docs are cheap, contrary to what I assumed. eleventy.config.js generates docs pages in a loop over docsMountList rather than as hand-written files, so the vanity set is a loop parameter, not 20 new templates.

Internal links must be relative to the vanity root, and this is the load-bearing detail. Vanity pages emit at /vanity/umbra/ and /vanity/umbra/docs/<page>/, and their own internal links are written as / and /docs/<page>/, not /projects/umbra/.... That is what lets a single splat rule work:

# shared assets, and these must precede the catch-all
[[redirects]]
  from = "https://umbra.coilyco.ai/images/*"
  to = "/images/:splat"
  status = 200
  force = true
# repeat for /styles/*, /fonts/*, /project-toc.js

# everything else on this host is the vanity build
[[redirects]]
  from = "https://umbra.coilyco.ai/*"
  to = "/vanity/umbra/:splat"
  status = 200
  force = true

An empty splat resolves to /vanity/umbra/, so the bare host needs no separate rule.

Assets stay shared rather than being emitted absolutely, deliberately. Absolute asset URLs would put fonts cross-origin and depend on CORS headers this site does not currently promise.

/fonts/* is required and is invisible in the HTML. It appears only inside site.css as url("/fonts/roboto-latin-400-normal.woff2"). An asset list built from href and src alone ships a vanity host with no webfonts and no obvious cause.

Must not break

  • Sitemap. Vanity variants stay out of it. #133 already flagged sitemap derivation as a repeat-failure risk.
  • Canonical. umbra.njk already carries canonical: /projects/umbra/ in front matter. Vanity variants keep pointing there, which is what preserves #133's single-authority argument through this mechanism.
  • robots. Vanity pages should be noindex or rely on the canonical, chosen deliberately rather than inherited.

Sequencing, which matters more than the build

Prove the vanity host holds the address bar before building any of this. The gating unknown from the earlier comment is now worse than untested: Netlify documents force = true as overriding file shadowing, and says nothing about it beating the automatic primary-domain redirect. The flag this design leans on is not documented to do the thing it is being relied on for.

coilyco.ai currently has Route 53 nameservers and no records at all, so the cheapest proof is a single record plus one throwaway rewrite, watching whether the address bar survives. If it does not, the whole variant build is wasted work.

Corrections to my earlier comment

  • to = "/:splat" as a single rule is wrong regardless of this decision: the bare host splats to / and serves the site homepage, not the umbra page.
  • The path allowlist and the 301 catch-all are both unnecessary under swapped chrome, beyond the asset rules above.
## Decided: swapped chrome via build variants. Supersedes my allowlist recommendation above Kai's call, 2026-08-28. The vanity host gets its own header and footer rather than inheriting the site nav. That changes the shape of this issue enough that my previous comment's `to = "/:splat"` rule should not be built. **A `status = 200` rewrite cannot do this on its own.** It serves identical bytes and the origin never learns the Host, so swapped chrome has to exist as built output or be assembled at the edge. Build variants win here: `base.njk` already includes nav and footer at two lines, so this is a flag and a second include rather than a runtime dependency. ## The swap dissolves most of this issue Two findings from reading the repo that shrink the problem: * **`footer.njk` contains no links.** It is a name block. Swapping it is cosmetic and nothing routes through it. * **The whole nav surface is five links in two files.** `nav.njk` carries the brand `href="/"`, and `links.njk` carries `/about/`, `/hiring/`, `/resume/` plus a GitHub link that is already absolute. So the "visitor bounces off the vanity host" problem was never routing. It was the shared nav. Vanity chrome that does not link to those paths removes the need for a path allowlist or denylist entirely, and the brand-link conflict I raised earlier (`/` is both the vanity root and Home) disappears, because vanity chrome can link Home absolutely to `www.coilysiren.me`. ## What changes **Templates.** A `vanity` flag on the page, `base.njk` selecting `nav-vanity.njk` and `footer-vanity.njk` when set. The vanity nav links outward absolutely; the vanity footer carries the "part of coilysiren.me" line. **Docs are cheap, contrary to what I assumed.** `eleventy.config.js` generates docs pages in a loop over `docsMountList` rather than as hand-written files, so the vanity set is a loop parameter, not 20 new templates. **Internal links must be relative to the vanity root, and this is the load-bearing detail.** Vanity pages emit at `/vanity/umbra/` and `/vanity/umbra/docs/<page>/`, and their own internal links are written as `/` and `/docs/<page>/`, not `/projects/umbra/...`. That is what lets a single splat rule work: ```toml # shared assets, and these must precede the catch-all [[redirects]] from = "https://umbra.coilyco.ai/images/*" to = "/images/:splat" status = 200 force = true # repeat for /styles/*, /fonts/*, /project-toc.js # everything else on this host is the vanity build [[redirects]] from = "https://umbra.coilyco.ai/*" to = "/vanity/umbra/:splat" status = 200 force = true ``` An empty splat resolves to `/vanity/umbra/`, so the bare host needs no separate rule. Assets stay shared rather than being emitted absolutely, deliberately. Absolute asset URLs would put fonts cross-origin and depend on CORS headers this site does not currently promise. **`/fonts/*` is required and is invisible in the HTML.** It appears only inside `site.css` as `url("/fonts/roboto-latin-400-normal.woff2")`. An asset list built from `href` and `src` alone ships a vanity host with no webfonts and no obvious cause. ## Must not break * **Sitemap.** Vanity variants stay out of it. #133 already flagged sitemap derivation as a repeat-failure risk. * **Canonical.** `umbra.njk` already carries `canonical: /projects/umbra/` in front matter. Vanity variants keep pointing there, which is what preserves #133's single-authority argument through this mechanism. * **`robots`.** Vanity pages should be `noindex` or rely on the canonical, chosen deliberately rather than inherited. ## Sequencing, which matters more than the build **Prove the vanity host holds the address bar before building any of this.** The gating unknown from the earlier comment is now worse than untested: Netlify documents `force = true` as overriding *file shadowing*, and says nothing about it beating the automatic primary-domain redirect. The flag this design leans on is not documented to do the thing it is being relied on for. `coilyco.ai` currently has Route 53 nameservers and no records at all, so the cheapest proof is a single record plus one throwaway rewrite, watching whether the address bar survives. If it does not, the whole variant build is wasted work. ## Corrections to my earlier comment * `to = "/:splat"` as a single rule is wrong regardless of this decision: the bare host splats to `/` and serves the site homepage, not the umbra page. * The path allowlist and the 301 catch-all are both unnecessary under swapped chrome, beyond the asset rules above.
Author
Collaborator

Live and measured. force = true holds, and the worry this issue was built around never applied

All three vanity hosts are serving. Shipped in 8bdc099, probed against production.

umbra.coilyco.ai          200  redirects=0  final=https://umbra.coilyco.ai/
agent-compose.coilyco.ai  200  redirects=0  final=https://agent-compose.coilyco.ai/
mcp-beaver.coilyco.ai     200  redirects=0  final=https://mcp-beaver.coilyco.ai/

Zero redirects. The hostname stays in the address bar, which was the entire point and the thing this issue could not assume.

The gating fear was real and misaimed

Two comments up I raised that Netlify redirects non-primary domains to the primary, that the apex-to-www 301 is that behaviour live on this site, and that force = true is documented only as overriding file shadowing rather than that redirect. That was right about the documentation and wrong about the risk.

Vera measured the alias with no rewrite rule in place at all and it returned 200 on its own hostname with zero redirects, where the apex under the same command took its usual 301 to www. A domain alias and the apex are not the same mechanism. The default I spent three comments designing around does not apply to aliases.

So the probe ended up testing the rewrite rather than testing whether the hostname survived, which is a much smaller question, and the answer is that it works.

What is live, end to end

Chrome swaps. Each host wears its own project, not the site:

<a class="nav-brand" href="/"><span>umbra</span><small>config driven occlusion framework</small></a>
<footer><strong>umbra</strong><span>a project by <a href="https://www.coilysiren.me/">Kai Siren</a></span></footer>

Canonical is intact, so the hosts do not split authority and #133's decision stands: <link rel="canonical" href="https://www.coilysiren.me/projects/umbra/">.

Assets pass through, including the one that would have failed silently:

/styles/site.css                       200 text/css
/fonts/roboto-latin-400-normal.woff2   200 font/woff2
/images/marks/umbra.png                200 image/png
/project-toc.js                        200 application/javascript

Everything else leaves for the real site rather than 404ing on a host with no such page:

/resume/               301 -> https://www.coilysiren.me/resume/
/about/                301 -> https://www.coilysiren.me/about/
/projects/umbra/docs/  301 -> https://www.coilysiren.me/projects/umbra/docs/
/nonsense/             301 -> https://www.coilysiren.me/nonsense/

That last row is worth naming: an unknown path leaves and then 404s on the real site rather than here. Deliberate, and the alternative is a 404 on a hostname with no navigation to recover from.

www.coilysiren.me/projects/umbra/ still serves 200 with the site's own nav, unchanged.

What this issue can close on

Steps 1 and 5 were already satisfied before any work started, measured earlier. Steps 2, 3 and 4 are answered by the swapped chrome: the vanity host simply never offers the links that would have needed an allowlist, so the scoping and nav-behaviour questions dissolved rather than being decided.

The only thing left is the apex, which the body scopes out.

## Live and measured. `force = true` holds, and the worry this issue was built around never applied All three vanity hosts are serving. Shipped in `8bdc099`, probed against production. ``` umbra.coilyco.ai 200 redirects=0 final=https://umbra.coilyco.ai/ agent-compose.coilyco.ai 200 redirects=0 final=https://agent-compose.coilyco.ai/ mcp-beaver.coilyco.ai 200 redirects=0 final=https://mcp-beaver.coilyco.ai/ ``` **Zero redirects.** The hostname stays in the address bar, which was the entire point and the thing this issue could not assume. ## The gating fear was real and misaimed Two comments up I raised that Netlify redirects non-primary domains to the primary, that the apex-to-`www` 301 is that behaviour live on this site, and that `force = true` is documented only as overriding *file shadowing* rather than that redirect. That was right about the documentation and wrong about the risk. Vera measured the alias with **no rewrite rule in place at all** and it returned 200 on its own hostname with zero redirects, where the apex under the same command took its usual 301 to `www`. A domain alias and the apex are not the same mechanism. The default I spent three comments designing around does not apply to aliases. So the probe ended up testing the rewrite rather than testing whether the hostname survived, which is a much smaller question, and the answer is that it works. ## What is live, end to end **Chrome swaps.** Each host wears its own project, not the site: ``` <a class="nav-brand" href="/"><span>umbra</span><small>config driven occlusion framework</small></a> <footer><strong>umbra</strong><span>a project by <a href="https://www.coilysiren.me/">Kai Siren</a></span></footer> ``` **Canonical is intact**, so the hosts do not split authority and #133's decision stands: `<link rel="canonical" href="https://www.coilysiren.me/projects/umbra/">`. **Assets pass through**, including the one that would have failed silently: ``` /styles/site.css 200 text/css /fonts/roboto-latin-400-normal.woff2 200 font/woff2 /images/marks/umbra.png 200 image/png /project-toc.js 200 application/javascript ``` **Everything else leaves for the real site** rather than 404ing on a host with no such page: ``` /resume/ 301 -> https://www.coilysiren.me/resume/ /about/ 301 -> https://www.coilysiren.me/about/ /projects/umbra/docs/ 301 -> https://www.coilysiren.me/projects/umbra/docs/ /nonsense/ 301 -> https://www.coilysiren.me/nonsense/ ``` That last row is worth naming: an unknown path leaves and then 404s on the real site rather than here. Deliberate, and the alternative is a 404 on a hostname with no navigation to recover from. `www.coilysiren.me/projects/umbra/` still serves 200 with the site's own nav, unchanged. ## What this issue can close on Steps 1 and 5 were already satisfied before any work started, measured earlier. Steps 2, 3 and 4 are answered by the swapped chrome: the vanity host simply never offers the links that would have needed an allowlist, so the scoping and nav-behaviour questions dissolved rather than being decided. The only thing left is the apex, which the body scopes out.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
coilysiren/website#138
No description provided.