Skip to content

Delete the static mirror; the terminal is the only page - #128

Merged
ledwards merged 1 commit into
mainfrom
remove-static-mirror
Aug 12, 2026
Merged

Delete the static mirror; the terminal is the only page#128
ledwards merged 1 commit into
mainfrom
remove-static-mirror

Conversation

@ledwards

Copy link
Copy Markdown
Contributor

Follow-up to #123 and #127. Those made the mirror invisible to Google; this removes it.

Why

The static mirror existed to make an xterm.js terminal readable to crawlers, and it worked well enough to cause the problem it now has. Google indexed all 70-odd pages and started showing sitelinks under the root.vc result:

Root Ventures — Deep tech seed fund in San Francisco
About · Team · Jobs · Creator · Radical

That advertises a conventional website sitting behind the terminal. The terminal is the product, so the website goes.

What replaces it

js/terminal-ext.js already parsed the URL fragment as a command to run on load, so the addressing scheme was sitting there unused. /#tldr-chargelab now shows ChargeLab inside the terminal instead of on a page pretending not to be one.

  • _redirects — every old mirror URL 301s to its command. Not a 404: a redirect tells Google to drop the indexed URL and fold its signals into the homepage, and an inbound link from someone else's site still lands on something real. Netlify :slug placeholders cover all 76 companies and the whole team in four rules.
  • The homepage's offscreen block is now the only HTML copy of the portfolio and team, with deep links in place of paths.
  • schema.org — Person and company nodes move into the homepage @graph, keyed by fragment @ids (#person-avidan, #company-chargelab) so each stays individually addressable to a parser.
  • llms.txt / llms-full.txt point at deep links.
  • The www command advertised /about/ and /portfolio/. Those now redirect back into the terminal, so it would have sent people in a circle — it points at llms.txt instead.
  • css/pages.css is deleted; nothing renders from it any more.

What this gives up, deliberately

Long-tail search. Google strips fragments before indexing, so root.vc/#tldr-chargelab and root.vc/ are the same URL to it. root.vc can no longer rank for "root ventures chargelab" with a dedicated result — one page cannot hold 76 topics. Brand queries are unaffected, and consolidating everything into one URL concentrates authority there.

Per-company share cards. Open Graph tags are per-URL, so a deep link pasted into Slack renders the generic Root Ventures card.

Both are the cost of having exactly one indexed URL, which is the point of the change.

Hash parser

The parser split the fragment on every hyphen, so a hyphenated slug became two arguments — a company added as vibe-robotics would have broken its own deep link. Harmless while pages existed; not harmless when the fragment is the only address. It now splits on the first hyphen only.

Deep-link arrivals are also tracked now. Fragments fire no pageview of their own, so every arrival at a specific company was invisible in analytics.

Test plan

  • npm test — 94/94 passing. The count drops from 313 because ~229 were it.each over the 76 mirror pages. New coverage for the redirect map (destinations, both URL forms, rule ordering, all 301), the homepage @graph, deep-link parsing including the hyphenated-slug case, and an assertion that no mirror path is emitted at all.
  • npm run builddist/ contains no about/, jobs/, portfolio/ or team/ directories
  • Served the build and loaded /#tldr-chargelab in a browser: terminal boots with the command already run, photo URL correct
  • Redirects need the deploy preview to verify — Netlify processes _redirects at the edge, not locally

🤖 Generated with Claude Code

The mirror existed to make an xterm.js terminal readable to crawlers, and it
worked well enough to cause the problem it now has: Google indexed all 70-odd
pages and began showing sitelinks to About / Team / Jobs under the root.vc
result, advertising a conventional website sitting behind the terminal. The
terminal is the product, so the website goes.

Content is addressed by URL fragment instead. js/terminal-ext.js already read
the hash as a command to run on load, so /#tldr-chargelab shows ChargeLab
inside the terminal rather than on a page pretending not to be one.

- Every old mirror URL 301s to its command via a generated _redirects. Not a
  404: a redirect tells Google to drop the indexed URL and fold its signals
  into the homepage, and an inbound link from elsewhere still lands somewhere
  real.
- The homepage's offscreen block is now the only HTML copy of the portfolio and
  team, with deep links in place of paths.
- Person and company schema.org nodes move into the homepage @graph, keyed by
  fragment @ids so each stays individually addressable.
- llms.txt and llms-full.txt point at deep links.
- The `www` command advertised /about/ and /portfolio/. Those now redirect back
  into the terminal, so it would have sent people in a circle; it points at
  llms.txt now.

Two things this deliberately gives up. Google strips fragments before indexing,
so root.vc can no longer rank for "root ventures chargelab" with a dedicated
result — one page cannot hold 76 topics. And a deep link shares as the generic
site card, since Open Graph tags are per-URL. Both are the cost of having
exactly one indexed URL, which is the point.

The hash parser now splits the command from its argument on the FIRST hyphen.
Splitting on every hyphen turned a hyphenated slug into two arguments, so a
company added as `vibe-robotics` would have broken its own deep link — fine
while pages existed, not fine when the fragment is the only address. Deep-link
arrivals are also tracked now; fragments fire no pageview, so they were
invisible.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@ledwards
ledwards merged commit 228632a into main Aug 12, 2026
6 checks passed
@ledwards
ledwards deleted the remove-static-mirror branch August 12, 2026 18:58
ledwards added a commit that referenced this pull request Aug 12, 2026
Enabling analytics on deep links in #128 made every window resize fire a second
commandSent event. xterm clears its buffer on resize, so resizeListener reruns
the deep link to redraw the output — that is the same visit, not a new arrival.
Caught it on production: one load of /portfolio/chargelab/ had already logged
two events.

It would have inflated exactly the numbers the tracking was added to produce,
and worst on mobile, where showing and hiding the address bar fires resize.

The replay path now passes trackAnalytics: false, matching the history replay
immediately below it, which calls term.command directly for the same reason.

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
ledwards added a commit that referenced this pull request Aug 13, 2026
…al (#132)

* Update the README for the mirror's removal

It still documented the static mirror as the crawlability story — the URL list,
the <noscript> block, "regenerates that company's page" — all of which #128
deleted. Replaces that section with how it actually works now: fragment
addressing, the redirect map, and the visually-hidden block, plus why the mirror
went away and what it cost.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* Add a swag command for the Root store

Opens https://rootvc.creator-spring.com, listed in help and the README alongside
the other link commands. Tab completion picks it up from the commands object
with no extra wiring.

Also drops a stale comment above `www` that still described the static mirror it
used to point at, left behind when the body was rewritten in #128.

Originally proposed in #65 in September 2022. The patch no longer applied —
commands.js, help.js and the README have all moved underneath it — but the store
is still live and still Root's, so the change is reapplied here rather than
asking for a four-year-old branch to be rebased.

Co-Authored-By: unkrich <unkrich@users.noreply.github.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Co-authored-by: unkrich <unkrich@users.noreply.github.com>
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.

1 participant