Skip to content

✨ Separate where a build is hosted from the url it is canonically at #21

Description

@taras

Motivation

--base currently answers two different questions at once:

  1. where these bytes live — what a[href], [src], and asset links should
    point at
  2. what this content is called — what <link rel="canonical"> and
    <meta property="og:url"> should claim

For an ordinary site those coincide, so nothing forced them apart. They diverge
the moment a site is served from one origin and published at another, which is
how the Frontside sites work: Effection is hosted at effection.netlify.app and
published at frontside.com/effection, and the same holds for Interactors and
Graphgen.

Today the only way to get a correct canonical is to point --base at the
published url, which then drags every other url along with it. The build becomes
valid only at the published address, and a preview cannot say "index production
instead of me" without also rewriting its own navigation onto production.

It has already cost something

thefrontside/effection#1248 moved Effection's production --base to
https://frontside.com/effection to get the canonical right. That also moved the
sitemap, so effection.netlify.app/sitemap.xml began listing
https://frontside.com/effection/.... frontside.com mounts a proxied site's
sitemap by prefixing /effection onto every entry, so the prefix landed twice
and every url 404'd:

Error: could not download http://127.0.0.1:8005/effection/effection/docs/resources
  Error: GET ... responded 404 Not Found

519 errors, and frontside.com's deploy has been failing since
(thefrontside/frontside.com#509 is the fix on that side). None of that was the
intent of #1248 — it followed from --base meaning two things.

What is actually being rewritten

Worth recording, because it narrows the problem. On the deployed builds, no
navigation was rewritten at all
:

effection.netlify.app pr-333 interactors preview
relative nav links, untouched 54 28
absolute links still on the hosting origin 0 0
absolute urls rewritten to frontside.com 6 4

Every one of those 6 and 4 is identity metadata:

<link rel="canonical">      <meta property="og:url">
<meta property="og:image">  <meta name="twitter:image">
<link rel="alternate" hreflang=…>

Both sites navigate with relative hrefs, so they still browse standalone. The
conflation is not breaking navigation today — it works by luck rather than by
design, and it did break the sitemap.

Approach

Add --canonical, defaulting to --base, so every existing invocation behaves
exactly as it does now. rebase() then gets called with one of two targets
depending on what the url is for:

selector rebased onto why
link[rel=canonical] canonical names the published page
meta[property=og:url] canonical the same claim in another vocabulary
link[rel=alternate] canonical hreflang should name the indexed url
a[href], [src], other link[href] base where this build's bytes are

A preview then expresses what it actually means:

--base=https://pr-333--interactors.netlify.app   # browsable on its own
--canonical=https://frontside.com/interactors    # index production, not me

Open questions

og:image / twitter:image. Assets, so base by the rule above — a
preview shows its own card. But a social card arguably should always be
production's. Listed as base in the table; easy to move.

The sitemap. It maps this deployment, so base keeps a preview from
listing production urls, and keeps frontside.com's prefixing working as it
always did. Google's guidance is that sitemaps list canonical urls, which argues
the other way.

Textual bodies (#17). The sharp one. #1248's intent was that production
documents advertise production, which it got by pointing --base there. Split
canonical out, leave text on base, and llms.txt goes back to naming the
Netlify origin — a regression of that intent. canonical seems right, since
llms.txt is a map telling agents where the docs live. The exception is a
feed's rel="self", which should name where the feed is, and a blind text
substitution cannot tell the two apart.

What the consuming sites do afterwards

  • Interactors — flag change only. It already emits its canonical from the
    crawl origin, which is what lets staticalize rewrite it.
  • Graphgen — needs the <link rel="canonical"> it never had
    (🐛 Specify canonical url as frontside.com/graphgen with staticalize graphgen#74), then the same flag change.
  • Effection — gets simpler. Its canonical is currently emitted by the site
    from its own base option, so staticalize skips it as off-origin. If
    staticalize owns canonical, that plumbing collapses and Effection stops having
    two different flags named --base.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions