Skip to content

fix(ratewise): 修復內容頁與 404 頁殘留的 React #418 hydration mismatch - #622

Merged
s123104 merged 1 commit into
experiment/ratewise-product-2026h2from
fix/content-pages-418
Jul 5, 2026
Merged

fix(ratewise): 修復內容頁與 404 頁殘留的 React #418 hydration mismatch#622
s123104 merged 1 commit into
experiment/ratewise-product-2026h2from
fix/content-pages-418

Conversation

@s123104

@s123104 s123104 commented Jul 5, 2026

Copy link
Copy Markdown
Contributor

Summary

staging 驗證(#459 comment、.claude/product-intel/qa-staging-report.md P1-2)發現 #595 部署後 app 殼層四頁已乾淨,但內容頁(/faq/、/guide/、/usd-twd/、/sell-rate-vs-mid-rate/、/usd-twd/100/)每次載入仍拋 #418 args[]=text,404 頁拋 args[]=HTML。本 PR 定位並修復兩個獨立根因。

根因 A|內容頁 args[]=text:建置時間格式化隨時區漂移

apps/ratewise/src/config/version.tsgetFormattedBuildTime()toLocaleDateString('zh-TW')toLocaleTimeString('zh-TW') 未指定 timeZone。staging/CI 在 UTC build → SSG HTML 寫入 Built on 2026/07/05 19:27;使用者瀏覽器在 Asia/Taipei → client 算出 2026/07/06 03:27 → Footer tooltip 文字節點 mismatch。只有掛 Layout(含 Footer)的內容頁中招;app 殼層走 AppLayout 無 Footer,所以 #595 後看似「殼層已修、內容頁沒修」——實為另一獨立根因。

為何 #595 驗證沒抓到(誠實檢討)#595 本地驗證 build 與瀏覽器同在 Asia/Taipei,兩側格式化結果相同、必然通過——是驗證方法盲點(缺跨時區組合),不是路由集合漏抽。本次以 TZ=UTC pnpm build × 台北時區瀏覽器在本地完整重演 staging 現象後定位。

修法getFormattedBuildTime() 兩處格式化固定 timeZone: 'Asia/Taipei'

根因 B|404 頁 args[]=HTML:SPA fallback 送首頁快照仍被 hydrate

未知路徑經 SW navigation fallback(或任何 /* → index.html 主機)拿到首頁 SSG 快照(帶 data-server-rendered=true),client 端渲染 NotFound 樹 → 結構性 mismatch。vite-react-ssg 0.8.9 production 因 NODE_ENV gate 一律 hydrate;上游已在 PR #90 merge 修正(!isSSRrender())但尚未發版。

修法(三件一組)

  1. vite.config.ts onBeforePageRender 為每個預渲染頁注入 <meta name="ssg-route"> 標記
  2. src/utils/ssgFallbackGuard.tsmain.tsx:hydration 前比對標記與當前 URL,不符(404/SW shell fallback/無尾斜線 fallback)即清空 root 並移除 data-server-rendered
  3. patches/vite-react-ssg@0.8.9.patch:對齊上游 PR fix(pwa): 修復 Safari PWA 離線顯示「無法打開網頁」問題 #90 一行修正,讓無標記快照走乾淨 render();上游發版後應移除 patch 改升版

防回歸

  • version.test.tsgetFormattedBuildTime() 必須等於 Asia/Taipei 顯式格式化結果(CI 為 UTC,timeZone 被移除即紅)
  • prerender.test.ts:抽樣 dist 頁必含 ssg-route 標記;faq 頁 Built on 文字必須等於以 Asia/Taipei 格式化 build-time meta 的結果(build 機器時區漂移即紅)
  • ssgFallbackGuard.test.ts:stale 快照降級 render/正確路由維持 hydrate/無標記保守不介入

驗證(零 #418 證據)

停 SW、production build+preview,11 路由(//multi/favorites/settings/faq//guide//about//usd-twd//sell-rate-vs-mid-rate//usd-twd/100/、404 未知路徑)Playwright console 巡檢:

組合 修復前 修復後
台北 build × 台北瀏覽器 4 筆(fallback 類) 0
台北 build × UTC 瀏覽器 10 筆 0
UTC build × 台北瀏覽器(staging 重演) 內容頁全中 0

404 頁修復後正確渲染 NotFound(h1「404」+h2「頁面不存在」)、/multi(無尾斜線 fallback)正確渲染多幣別頁。

閘門

  • pnpm typecheck 全綠
  • ratewise vitest:3322 passed | 2 skipped(含新增守門測試)
  • pnpm build:ratewise 成功(pre-push 亦全綠)
  • changeset:patch(使用者可感知:console 不再出現錯誤)
  • 002 已更新(reward+1/penalty−1,總分 +134 不變)

Refs

Follow-up(已立案,非本 PR 範圍)

請勿直接 merge:等待 review 與使用者授權。

Made with Cursor

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, you can upgrade your account or add credits to your account and enable them for code reviews in your settings.

- getFormattedBuildTime 固定 timeZone Asia/Taipei:CI(UTC)SSG 與使用者瀏覽器
  (台北)此前對同一 BUILD_TIME 產出不同字串,Footer 文字節點 mismatch 使
  所有掛 Layout 的內容頁(faq/guide/幣別/金額頁)每次載入拋 418 args=text
- SSG 注入 ssg-route 標記+main.tsx 前置守門:SPA fallback/SW shell 對未預
  渲染路徑送首頁快照時,偵測快照路由不符即清空 root 改走 client render,
  修復 404 頁 418 args=HTML;同時涵蓋離線 shell fallback 與無尾斜線路徑
- patch vite-react-ssg@0.8.9:對齊上游已 merge 未發版的 PR 90,production
  非 SSR 快照走 render() 而非 hydrate(),上游發版後移除 patch 改升版
- 防回歸:version 時區測試(CI UTC 會抓 timeZone 遺失)、prerender 守門
  (ssg-route 標記+Built on 需等於 Asia/Taipei 格式化結果)、guard 單元測試

測試:pnpm typecheck 全綠、ratewise vitest 3322 綠、雙時區(UTC/台北 build×瀏覽器)停 SW 11 路由巡檢 418 全歸零

Co-authored-by: Cursor <cursoragent@cursor.com>
@s123104
s123104 force-pushed the fix/content-pages-418 branch from 0f77258 to 656cab2 Compare July 5, 2026 23:24
@github-actions

github-actions Bot commented Jul 5, 2026

Copy link
Copy Markdown
Contributor

⚠️ Deprecation Warning: The deny-licenses option is deprecated for possible removal in the next major release. For more information, see issue 997.

Dependency Review

✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.

Scanned Files

None

@github-actions

github-actions Bot commented Jul 5, 2026

Copy link
Copy Markdown
Contributor

✅ SEO 審計通過!所有 2026 標準驗證項目都符合要求。

  • ✅ Sitemap 2026 標準
  • ✅ Breadcrumb Schema
  • ✅ JSON-LD 結構化數據
  • ✅ 內部連結結構

@s123104
s123104 merged commit f3046ad into experiment/ratewise-product-2026h2 Jul 5, 2026
20 of 21 checks passed
@s123104
s123104 deleted the fix/content-pages-418 branch July 5, 2026 23:46
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