SEO: real robots.txt + hreflang pairs + BlogPosting schema
Deploy / build (push) Successful in 18s

robots.txt was absent at the origin, so Cloudflare served its Free-plan
Content Signals Policy placeholder — a file with no User-agent, no Sitemap
and no directives. Adds src/pages/robots.txt.ts (origin 200 → CF merges
instead of substituting) pointing at sitemap-index.xml, disallowing
/pagefind/, and expressing search=yes / ai-input=yes / ai-train=no in line
with the two-lane SEO+GEO strategy in docs/seo-reference.md. Citation
crawlers (Google-Extended, OAI-SearchBot, PerplexityBot, ClaudeBot) stay
allowed; only training-only harvesters blocked.

hreflang was never emitted despite full EN/ZH i18n: both language versions
sat in the sitemap with no cross-reference. BaseLayout gains altLocaleUrl
and emits en/zh/x-default per page; every post pair, category pair, and
landing page now cross-links.

Also adds BlogPosting JSON-LD (@id-linked to the site-wide Person node)
so Google has a rich-result-eligible node per article, and creates the
missing /zh/about/ page — the EN about page pointed its language switch at
a 404, and /about/ was the only unpaired page after hreflang landed.
This commit is contained in:
hoelee committed 2026-09-19 21:41:22 +08:00
1 parent 86f3a977b9
commit 7e0802f913
12 files changed
+163 -3

No files matched your search

+1 -1
View File
@@ -9,7 +9,7 @@ import { sortByUpdated } from '../lib/sort';
const posts = sortByUpdated(await getCollection('posts', isEn));
---
<BaseLayout title={SITE.title} description={SITE.description}>
<BaseLayout title={SITE.title} description={SITE.description} altLocaleUrl={`${SITE.url}/zh/`}>
<section>
<h1>Hi, I'm {SITE.author}.</h1>
<p>