Skip to content

文章可讀性優化 + 遊戲化寫作 + 產出多國語系文章 + Generative Engine Optimization#202

Open
futianshen wants to merge 39 commits into
mainfrom
feature/i18n-multilingual-site
Open

文章可讀性優化 + 遊戲化寫作 + 產出多國語系文章 + Generative Engine Optimization#202
futianshen wants to merge 39 commits into
mainfrom
feature/i18n-multilingual-site

Conversation

@futianshen

Copy link
Copy Markdown
Contributor

No description provided.

Rhett and others added 7 commits July 11, 2026 20:00
Raises post-page Lighthouse Accessibility 88→98 and SEO 92→100.
- Dark inline/plain code colour #d65c5c (3.3:1) → #ffb0a3 (AA on the dark
  code surfaces)
- Add alt="" to the about-the-author avatar (was missing the attribute)

Remaining heading-order flag is post markdown starting at h3 (content, not template).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Generative-Engine-Optimization groundwork so LLM/AI crawlers can index the
blog well.
- /llms.txt: curated markdown index (site summary + all articles with absolute
  URLs + key pages/feeds), generated from collections.postsZhTW
- robots.txt: explicit Allow for GPTBot, OAI-SearchBot, ChatGPT-User, ClaudeBot,
  Claude-Web, PerplexityBot, Google-Extended, Applebot-Extended; sitemap via metadata.url

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@futianshen futianshen requested a review from benben6515 July 11, 2026 12:21
@futianshen futianshen self-assigned this Jul 11, 2026
@futianshen futianshen changed the title 遊戲化寫作 + 產出多國語系文章 + Generative Engine Optimization 文章可讀性優化 + 遊戲化寫作 + 產出多國語系文章 + Generative Engine Optimization Jul 11, 2026
@benben6515

Copy link
Copy Markdown
Contributor

先說結論:整體架構很紮實(opt-in 機制、讀 git index 而非 working tree、sourceHash 驗證正確、build 與 10 個測試都會過),但這個 PR 把四個獨立功能綁在一起,有一些值得討論的地方。

亮點

  • i18n 採 opt-in:只有同時具備 lang: zh-TW + translationKey 的文章才進守門流程,目前只有 posts/tian/git-flow.md,其他作者的既有文章完全不受影響 👍
  • 守門腳本讀 git index(git show :<file>),不會被 working tree 的未暫存內容影響,設計嚴謹
  • 我實跑 node scripts/check-translations.js --hash posts/tian/git-flow.md,算出的 hash 與三份譯文 frontmatter 裡的 sourceHash 完全一致
  • 無障礙改善:skip-link、toggle 改成 <button>、lang switcher 用原生 <details> 免 JS

建議討論

1. PR 範圍過大 + 缺描述

這個 PR 一次包了「文章可讀性(TOC)」「遊戲化寫作」「多國語系 i18n」「GEO(llms.txt / robots)」四件事,56 個檔案、+3077/-290,且 PR body 是空的。對 reviewer 負擔很大,也增加 revert 的顆粒度。建議至少補上 PR 描述說明動機與測試方式;若可能,拆成 2~3 個 PR 會更好 review。

2. 翻譯測試不在 npm test 範圍

scripts/check-translations.test.js 是獨立執行檔(用 assert,非 mocha),對應的是 npm run test:translations;但 npm test 目前是 echo 'no test for now',npm run build 也只跑 npm run test。也就是 CI 不會跑到這 10 個測試。建議把測試搬進 test/ 目錄,或在 build script 裡納入 test:translations,否則這些測試很容易靜悄悄壞掉沒人發現。

3. pre-commit 全倉生效

package.json"pre-commit": ["check-translations"] 會對所有貢獻者的每次 commit 觸發。雖然 opt-in 下多半是 no-op,但仍改變了 repo 既有流程。README 有提到不用 Husky,但沒提到貢獻者必須先 npm installpre-commit 套件掛上 hook 才會生效——可以補一句說明,避免有人以為 hook 自動啟用。

4. 翻譯皆為 draft: true,production 實際是「空轉」?

三份 git-flow 譯文都是 draft: true,搭配 eleventyComputed.js 在非 dev 環境會 permalink: false + eleventyExcludeFromCollections: true。也就是正式站上這些譯文不會被 build 出來,translations collection 裡不會有它們 → hreflang 連結與語言切換器在該篇文章會顯示「尚無此語言版本」。

如果這是刻意分階段(先上 infra、譯文人工審核後再陸續發布),那沒問題,但建議在 PR 描述講清楚,免得 reviewer 以為合併後 /en/posts/tian/git-flow/ 就能用。

5. 既有文章內容被改動

tiangit-flow.md(本文 +21/-32)、react-intl-automation.mdts-react-pattern-nested-todo-list.mdyou-might-not-need-react-memo.md 的內文都被修改了,混在 i18n 基礎建設 PR 裡。如果是為了加 description 給 llms.txt 用,建議在 commit message 或 PR 描述說明改動理由,方便日後追蹤。


小提醒:git-flow.md 出現了兩個 <!-- summary --> 標記(其他文章也有此 pattern),不確定是原本就如此還是這次新增,可以順手確認一下 summary 擷取是否符合預期。

整體方向我認同,infra 做得很確實,主要是希望能拆小 + 補描述,讓 review 更有效率 🙌

Rhett and others added 19 commits July 12, 2026 08:21
- Exclude page-list.njk from output; clean _site before production
  builds so stale per-language pages can't linger (scripts/clean-output.js)
- Languages with no published translations no longer emit home, About,
  author pages, or feeds (collections.siteLangsWithPublishedPosts)
- Draft translations are kept out of sitemap, hreflang, feeds, and the
  language switcher
- Sitemap now verifies every URL has real build output and rejects
  duplicates and malformed URLs

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Pin Node 24 across .nvmrc, package.json engines, lockfile, Netlify
- Add push/PR CI workflow: npm ci -> npm run build
- Update actions to checkout@v6, setup-node@v6, codeql-action@v4
- Wire clean/test scripts into npm run build

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Replace skipped boilerplate tests with assertions against the real
  homepage and post output
- Add coverage for sitemap, per-language pages, hreflang, internal
  docs exclusion, and the image pipeline
- Missing, unreadable, or badly URL-encoded local images now fail the
  build instead of warning; data: URIs and remote images still skipped
- Fix Sharp write race when multiple pages process the same image

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- sourceHash now covers title + body, so title changes mark
  translations stale; existing translations migrated to the new hash
- Staged translation deletions are now reported as missing
- Add --all mode so CI validates the whole checkout, not just staged
  files; pre-commit still reads the Git index precisely
- Update AGENTS.md to document the new hash semantics

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Git hook runners (pre-commit/pre-push packages) export GIT_DIR and
GIT_INDEX_FILE to child processes. The translation-guard integration
tests inherited them, so every 'git add' inside their temporary repos
rewrote the actual repository's index — staging the whole tree as
deleted plus four posts/tester fixtures. Strip GIT_* from the
environment of every git/guard subprocess so the temp repos stay
hermetic. Verified by running the suite under a hostile GIT_INDEX_FILE.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Homepage cards linked /posts/<display name> (e.g. /posts/Benben) and
five author keys (Xiang, Cian, Umer, Ruofan, Lavi) were capitalized
while their page directories are lowercase, so those links 404 on the
case-sensitive production host. Use the author key in home-postslist
and normalize the five keys to match their directories across
metadata.json, post frontmatter, and the author index pages. Display
names are unchanged.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
netlify.toml force-redirects /archive/:page to /archive/, so any second
pagination page would be unreachable. Raise the page size well above
the post count and document the constraint next to the pagination
block.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Extend the AI-crawler allowlist in robots.txt to the crawlers feeding
Meta, Amazon, and Common Crawl (which most model training sets consume),
matching the existing GEO policy.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
/css/* assets are fingerprinted via addHash, so they can share the
same immutable cache policy as /js/*. Archive rows render one avatar
per post; mark them loading=lazy.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The inline script that applies the colour theme before first paint was
missing the csp-hash attribute, so re-enabling the site's CSP meta tag
would block it and reintroduce the dark-mode flash. apply-csp.js only
whitelists inline scripts carrying this attribute.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Force CI and Netlify to evaluate draft visibility as production, while keeping local serve behavior explicit. Remove the PurgeCSS v3 option that the pinned v2 release silently ignores.
Prefer original image files over passthrough copies that Eleventy may still be writing. Keep generated derivatives in _site and retain the existing fallback for generated-only assets.
Derive site and translation guards from langs.json, validate required locale strings, and preserve dotted source slugs. Add a non-redirecting preferred-language banner, localized RSS links and 404 guidance, while keeping the zh-TW tags index source-only.
Provide Tian's translated biographies and route homepage author links to localized author pages only when those pages actually exist.
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.

2 participants