---
title: 08 官網架構與 SEO／AI SEO／GEO 做法
h1: 08 官網架構與 SEO／GEO 做法
subtitle: 框架選擇、靜態預產生、讓 Google 與 AI 搜尋都找得到、商業分析接法
chips: [{text: 框架定案：留 TanStack Start 開 prerender（決策者 2026-10-21 最終裁示）, kind: ok}, {text: 部署已定：Cloudflare Pages 純靜態, kind: ok}, {text: 待做 11 項, kind: warn}]
---

# 08 官網架構與 SEO／AI SEO／GEO 做法

> 這份回答三個問題：官網用什麼框架、怎麼讓搜尋引擎與 AI 搜尋（ChatGPT、Perplexity、Claude、Gemini）都看得到內容、怎麼接商業分析。結論是**留 Lovable 拉回來的 TanStack Start，開 prerender 出純靜態檔**；部署與 SEO／GEO 配備照公司已上線的 `design-home-fe` 做法，檔案改寫成 TanStack 的對應寫法。

## 一、先講結論

::: {.callout .decided}
**框架留 TanStack Start（Lovable 產出的那套），開 prerender 出純靜態 HTML。決策者 2026-10-21 最終裁示，不再討論。**

曾評估轉 Next.js（與 design-home 對齊）並派過一棒試轉，決策者中途裁定沿用 TanStack：骨架已能跑、文案與版型都在，轉換只是換底不加價值；TanStack Start 本來就是 SSR 框架，`prerender` 一開就出每頁 `index.html`，SEO／GEO 要的「HTML 裡有內文」照樣成立。design-home 的 SEO 檔案拿來當**內容參考**（爬蟲清單、JSON-LD 欄位、llms.txt 骨架），寫法改成 TanStack 的 `head()`、`public/` 靜態檔與路由。
:::

| 問題 | 答案 |
|---|---|
| 純前端 Vue／React SPA 能不能做 SEO／GEO | 不能。Google 要第二輪才渲染 JS，GPTBot、ClaudeBot、PerplexityBot **不執行 JS**，看到的是空殼 |
| 一定要 Next.js 嗎 | 不用。TanStack Start、Nuxt、Astro 都能出靜態 HTML；本站用 TanStack Start |
| 要不要改成 Astro | 不要，但它是最接近的第二名。技術上更適合官網（零 JS、Cloudflare 旗下、滿意度最高），輸在團隊要多懂一套、與 design-home 分家。何時反悔見一之二 |
| 留 Lovable 給的 TanStack Start 行不行 | 能做但不建議。框架太新（2026-10-13 才 1.0、nitro beta）、社群小出事難找答案、設定被 `@lovable.dev/vite-tanstack-config` 包住；留下等於替 Lovable 的選擇背一輩子，只為省一兩天 |
| 部署放哪 | **Cloudflare Pages，純靜態**。不用 Workers；需要時轉 Workers 只改部署指令、程式碼不動（見第三節之二） |
| 未來接 Payload CMS 行不行 | 行。Payload 是獨立後台，官網 build 時打它的 API 取內容，改完內容由 webhook 觸發重 build，design-home 就是這樣跑 |
| 未來要 call 自家 API 行不行 | 行。build 時抓一次的內容在 server component 裡 fetch；使用者操作時才打的（送表單）在 `"use client"` 元件裡打 |

## 一之二、三個框架對九條需求的對照

決策者在意的是「不要順著單一提問改答案」，所以把需求攤開、三個候選者用同一套標準各打一次分。◎ 強、○ 可、△ 弱。

**需求清單**（來自決策者原話與 02 網站地圖）：

| # | 需求 |
|---|---|
| R1 | SEO |
| R2 | AI SEO／GEO，AI 搜尋找得到 |
| R3 | 商業分析 |
| R4 | 搭配 Payload CMS，公司已有 design-home 那套 |
| R5 | 從 Lovable 轉一次，之後自己維護、不再用 Lovable |
| R6 | 架構定了就不要再變 |
| R7 | 部署 Cloudflare Pages |
| R8 | 決策者對前端生態陌生；團隊既有技能是 Vue（產品）與一個已上線的 Next 站 |
| R9 | 官網範圍小：18 固定頁＋6 篇指南、中英、一個表單；不做登入、價格、試用 |

**對照**：

| 需求 | Next.js 靜態 export | Astro | TanStack Start（Lovable 給的） |
|---|---|---|---|
| R1 SEO 技術面 | ○ HTML 完整，但每頁帶 80～120KB React，Lighthouse 多在 80～90 | ◎ 預設零 JS，Lighthouse 98～100 | ○ 同 Next，帶 React runtime |
| R2 GEO | ○ 內文在 HTML；robots／sitemap／metadata 有內建 API | ◎ 內文在 HTML；2026 年多數評測點名對 AI 搜尋最友善 | ○ 內文在 HTML；配備要自己補 |
| R3 商業分析 | ○ 加一段 script | ○ 同 | ○ 同 |
| R4 Payload | ◎ Payload 本身跑在 Next 上；design-home 的 `lib/payload.ts` 直接抄 | ○ Astro 官方有 Payload 指南，走 REST；社群有 loader 與 live preview 套件 | ○ 走 REST，無現成範例 |
| R5 從 Lovable 轉換 | ○ React 元件原封搬、路由重寫，一到兩天 | ○ React 元件當島嵌入、頁面骨架重寫成 `.astro`，兩到三天 | ◎ 零成本 |
| R6 五年不變 | △ 使用率第一但滿意度 68%→55%，State of JS 2025 收到 303 則「過度複雜」抱怨；12→13→15→16 心智模型改過多次；靜態 export 是它的冷門子集，design-home 的 `build.js` 就是為了繞限制寫的 | ◎ State of JS 2025 滿意度第一（約 91%），大版本升級附 codemod；靜態輸出是預設不是繞出來的 | △ 2026-10-13 才 1.0，承諾 API 穩定，但生態最小、出事最難找答案 |
| R7 Cloudflare Pages | ○ 可以；要關 image 優化、不能有 API route、redirects 改寫成 `_redirects` | ◎ Astro 是 Cloudflare 旗下專案，第一公民 | ○ nitro 打包，可以 |
| R8 團隊與決策者 | ◎ 已上線一站、有 runbook、Payload 同一套；只多懂一種技術 | △ 要多懂一種；但它是「HTML 加一點 JS」，對不熟前端的人最容易讀懂 | △ 要多懂一種，而且是最新的那種 |
| R9 範圍小而靜態 | ○ 只用到 Next 的一小塊 | ◎ 正是它設計的目標場景 | △ 強項（型別路由、server functions）全用不到 |

**怎麼讀這張表與最後的決定**：

- 三個框架在 R1～R3（SEO、GEO、分析）都是「內文在 HTML 裡」，差別只在配備要不要自己補；對 B2B 官網的排名影響不大。
- Next 的優勢在 R4、R8（與 design-home 同一條生產線）；Astro 在 R1、R6、R9（為內容站而生）；TanStack Start 在 R5（零轉換成本）。
- **決策者最終選 TanStack Start**：骨架已經在跑、文案與版型都在，轉換只是換底不加價值；R4（Payload）之後接時走 REST 即可；R6、R8 的風險（框架新、要多懂一種）接受，出事時可把 `vite.config.ts` 攤平、脫離 Lovable 包裝層。一次轉換曾派出（A1）並在中途停掉，工作區已還原。

::: {.callout .pending}
**什麼情況會回頭改框架（反悔條件）**

① TanStack Start 大版本不相容升級讓站起不來、或 nitro beta 出不了靜態檔而官方無修。② 官網長到上百頁、由非工程師頻繁改——Astro 的內容集合明顯好維護。③ 要與 design-home 共用 Payload 的程式碼（不只共用內容）——Next 直接贏。

目前三條都不成立。任一條成立時回來改這一節，並在 README 討論紀錄記推翻。
:::

**資料來源**（2026-10 查證）：[TanStack Start 1.0 is Stable](https://tanstack.com/blog/tanstack-start-1-0)、[State of JavaScript 2025: Meta-Frameworks](https://2025.stateofjs.com/en-US/libraries/meta-frameworks/)、[Astro vs Next.js for Static Sites: 2026 Corporate Website Stack Decision Guide](https://dev.to/aigcharness/astro-vs-nextjs-for-static-sites-a-2026-corporate-website-stack-decision-guide-39n5)、[Astro vs Next.js (2026): Real Benchmarks](https://alexbobes.com/programming/astro-vs-nextjs/)、[Astro 官方 Payload CMS 指南](https://docs.astro.build/en/guides/cms/payload/)、[What is TanStack Start (Cloudflare)](https://www.cloudflare.com/learning/serverless/what-is-tanstack-start/)。

## 二、現況盤點（`guidant-ai-website` repo，Lovable 拉回的版本）

| 項目 | 現況 | 怎麼處理 |
|---|---|---|
| 框架 | TanStack Start 1.168＋TanStack Router 檔案路由＋React 19＋Vite 8＋nitro 3.0 beta，`vite.config.ts` 被 `@lovable.dev/vite-tanstack-config` 包一層 | **留**。`vite.config.ts` 加 `tanstackStart: { prerender: { enabled: true, crawlLinks: true } }`，build 出 `.output/public/` 靜態檔 |
| 路由 | 中文在根層、英文在 `/en/` 同構一份，共 34 支；每支只做 head＋掛頁面元件 | 留。新頁照樣中英各一支；指南用 `$slug` 動態路由，prerender 時列出全部 slug |
| 頁面元件 | `components/pages/`：HomePage 113 行、ProductPage 119 行、StubPage 12 行 | 不動 |
| 全站元件 | `components/site/`：SiteHeader、SiteFooter、primitives（LLink、Logo、Placeholder、CTA） | 不動 |
| 文案 | `i18n/zh-TW.json`、`en.json` 各 429 行；元件不寫字串 | 不動；`pageHead()` 擴充 canonical、hreflang、og（見第四節） |
| 樣式 | `styles.css` 設計 token（oklch）、亮暗兩套、Tailwind 4 | 不動 |
| shadcn | `components/ui/button.tsx` | 不動 |
| `<head>` | `pageHead()` 已出 title、description、og:title、og:description、twitter:card | 在 `pageHead()` 的 `links`／`meta` 補 canonical、hreflang、og:image、og:url、og:locale |
| `robots.txt` | 只放行 Googlebot、Bingbot、Twitterbot、facebookexternalhit 與 `*` | 直接改 `public/robots.txt`，抄 design-home `robots.ts` 的 AI 爬蟲清單 |
| sitemap、JSON-LD、`llms.txt`、分析工具 | 無 | 內容抄 design-home；sitemap 用 build 腳本從路由清單產到 `public/sitemap.xml`，JSON-LD 放 `head().scripts`，`llms.txt` 放 `public/` |
| Lovable 殘留 | `lib/lovable-error-reporting.ts`、`server.ts` 錯誤包裝、`@lovable.dev/*` 依賴 | `lovable-error-reporting` 與 `__lovableEvents` 只在 Lovable 預覽有效，留著無害；想清就刪 |

**估工**：不用搬；開 prerender 半天，SEO 十項約三天。

## 三、TanStack Start 怎麼出靜態檔

```ts
// vite.config.ts（@lovable.dev/vite-tanstack-config 的 defineConfig 允許透傳 tanstackStart 設定）
export default defineConfig({
  tanstackStart: {
    server: { entry: "server" },
    prerender: { enabled: true, crawlLinks: true, autoSubfolderIndex: true },
  },
});
```

`npm run build` 後 `.output/public/` 下每個網址一支 `index.html`；動態路由（指南 `$slug`）要在 `prerender.pages` 或路由的 `loader` 可列舉時由 `crawlLinks` 從清單頁連結爬到。Cloudflare Pages 輸出目錄填 `.output/public`。

::: {.callout .warn}
**三個坑**

① prerender 時 `useI18n()` 靠 `useRouterState` 取路徑，SSR 期間可用，不必改。② `localStorage` 主題腳本已在 `__root.tsx` 用 inline script，prerender 不會執行它，正確。③ `.output/public/` 已含 `public/` 的靜態檔（robots.txt、sitemap.xml、llms.txt、og 圖）；sitemap 用 `scripts/gen-sitemap.mjs` 在 build 前從路由清單產，不手寫。
:::

## 三之二、部署定案：Cloudflare Pages 純靜態

::: {.callout .decided}
**官網部署在 Cloudflare Pages，只上傳 `.output/public/` 靜態檔，不用 Workers。**

需求裡沒有任何一項需要伺服器：SEO／GEO 要的是 HTML 裡有內文，靜態檔是最強版本；Payload 改內容是觸發重 build，不是即時運算；表單是瀏覽器端打 BE。Workers 多出來的只有「每次請求即時算頁面」這一項能力，用不到卻多一層會出錯的程式、多一組 wrangler 設定、多一項帳單。
:::

| 元件 | 放哪 | 備註 |
|---|---|---|
| 官網 | Cloudflare Pages，純靜態 | 連 GitLab repo，build 指令 `npm run build`，輸出目錄 `.output/public`，push 自動部署。與 design-home 的 `WEB_BUILD_MODE=export` 同一條路 |
| Payload CMS | 自架 VPS，Cloudflare Tunnel 對外 | 之後內容要搬進去時才起；存檔打 Pages Deploy Hook 重 build，約 1～2 分鐘生效 |
| 圖片、og 圖 | Cloudflare R2 | 與 design-home 同 |
| 表單、自家 API | 現有 Guidant BE | BE 對官網網域開 CORS；表單端點要有 rate limit 或驗證碼（公開可打）。也可比照 design-home 直送 Google Forms，不經 BE |

**Pages 上誰能 call API**：

| 誰在 call | 什麼時候 | 能不能 | 例子 |
|---|---|---|---|
| 使用者的瀏覽器 | 使用者操作時 | 能 | 送預約表單、聯絡表單 |
| build 機器 | `npm run build` 那一刻 | 能 | 從 Payload 抓文章、FAQ，寫進 HTML |
| Pages 伺服器 | 使用者每次開頁 | 不能 | 純靜態沒有伺服器。官網沒有「每個訪客看到不同內容」的頁，不需要 |

**之後要轉 Workers 怎麼辦**：nitro 本來就以 cloudflare 為預設目標，`.output/server/` 已是 Workers 可跑的格式，關掉 prerender 改部署 server 即可，頁面程式碼不動。Pages Functions 等同把 Workers 塞回來，不用。

**會需要轉 Workers 的只有兩種情況**，目前都沒有：登入後才看得到或每個訪客不同的頁（官網不做登入、不做試用）；編輯在 Payload 存檔前要即時預覽（design-home 也沒做，等重 build 就夠；真要做是另開一條預覽路由給編輯，官網本體不動）。

設定步驟照 `design-home-fe/docs/runbooks/production-deploy.md` Part B／C3（Pages）、C2（R2）、C1（Tunnel）。

## 四、SEO（讓 Google 與 Bing 收錄）

| 配備 | 做法 | design-home 參考 |
|---|---|---|
| 每頁 title、description | 已有，確認每頁文案獨一無二、title 60 字內、description 150 字內 | `apps/web` 各 `page.tsx` 的 `generateMetadata` |
| canonical | 每頁 `<link rel="canonical">` 指自己的正式網址（含網域、不含 query） | 同上 |
| hreflang | 中英各一套網址，每頁互指：`zh-Hant`、`en`、`x-default` 指中文 | 本站新寫 |
| Open Graph 圖 | 每頁或至少每區一張 1200×630 的 og:image，社群與 AI 引用時會抓 | 本站新寫 |
| sitemap.xml | prerender 自動產；確認含中英全部頁 | `apps/web/src/app/sitemap.ts` |
| robots.txt | 放行全部，附 `Sitemap:` 行 | `apps/web/src/app/robots.ts` |
| 效能 | 靜態檔天生過關，LCP 目標 2.5 秒內；圖片走 WebP、標寬高 | 無 |
| 送件 | 上線後到 Google Search Console 與 Bing Webmaster Tools 驗證網域、送 sitemap | `docs/ai-seo/local-presence-checklist.md` |

## 五、AI SEO／GEO（讓 ChatGPT、Perplexity、Claude、Gemini 引用）

AI 搜尋引擎抓網站的方式跟 Google 不同：**不跑 JS、偏好一段就能摘出答案的文字、很依賴結構化資料與站外的一致訊號**。四件事：

### 1. 放行 AI 爬蟲（`public/robots.txt`）

照 design-home 已查證過的清單，`User-agent: *` 已放行時另外明列是「明確表態」，部分爬蟲會先找針對自己的規則：

```
User-agent: GPTBot
User-agent: OAI-SearchBot
User-agent: ChatGPT-User
User-agent: ClaudeBot
User-agent: Claude-User
User-agent: Claude-SearchBot
User-agent: PerplexityBot
User-agent: Google-Extended
User-agent: Amazonbot
User-agent: CCBot
User-agent: meta-externalagent
Allow: /

User-agent: *
Allow: /

Sitemap: https://<官網網域>/sitemap.xml
```

參考：`design-home-fe/apps/web/src/app/robots.ts`（內含各家 UA 的查證註解，`Claude-Web` 是舊名已棄用）。

### 2. JSON-LD 結構化資料

每頁 `<head>` 放一段 `<script type="application/ld+json">`。Guidant AI 是 B2B 軟體，型別與 design-home（室內設計、`LocalBusiness`）不同：

| 頁 | schema.org 型別 | 關鍵欄位 |
|---|---|---|
| 全站（放在 root） | `Organization` | name 竣盟科技股份有限公司、url、logo、address、telephone、email、`sameAs`（LinkedIn、billows.tech） |
| 產品總覽、功能細頁 | `SoftwareApplication` | name Guidant AI、applicationCategory `BusinessApplication`、operatingSystem、description、offers 不填（報價制） |
| 指南六篇 | `Article` | headline、datePublished、dateModified、author（Organization）、inLanguage |
| 有問答的頁（解決方案、信任中心） | `FAQPage` | `mainEntity` 每題一組 Question／Answer，答案第一句就是答案 |
| 每頁 | `BreadcrumbList` | 麵包屑，幫 AI 理解站的階層 |

參考：`design-home-fe/apps/web/src/lib/jsonld.ts`，注意它把 `<` 轉義成 `<` 的作法要照抄，避免文案含 `</script>` 把標籤提早關掉。

### 3. `llms.txt`

站根放一份純文字 `/llms.txt`，給 AI 助理的網站導覽：一段公司與產品介紹、主要頁面清單（每行「標題、網址、一句說明」）、指南文章清單。prerender 後放 `public/llms.txt` 即可，內容改動時手動更新。

參考：`design-home-fe/apps/web/src/app/llms.txt/route.ts`（它從 CMS 動態產，本站先寫死）。

### 4. 內容寫法與站外佈局

- **問答式內容**：每個解決方案頁與指南開頭放「什麼是 X、誰需要、怎麼過」三段直接回答；FAQ 每題 150 字內、第一句就是答案。AI 引用時摘的就是前兩句。
- **實體一致**：公司名、地址、電話、產品名在官網、LinkedIn 公司頁、billows.tech、G2／Capterra 等平台**一字不差**。AI 靠這個確認是同一家。
- **站外訊號**（B2B 版，對應 design-home 的 Google 商家與評論）：LinkedIn 公司頁與產品頁、G2 或 Capterra 建產品檔案、產業媒體或合作夥伴（CMMC C3PAO、顧問公司）的報導與連結、GitHub 若有開源元件。這些是「別人怎麼說你」，官網做得再好、站外空白的公司 AI 不敢推薦。

參考：`design-home-fe/docs/ai-seo/faq-draft.md`（FAQ 寫法原則）、`local-presence-checklist.md`（站外清單的結構，內容要換成 B2B 平台）。

## 六、商業分析怎麼接

| 要看什麼 | 工具 | 做法 |
|---|---|---|
| 流量、來源、停留、轉換 | GA4（或 Plausible、Cloudflare Web Analytics 等不用 cookie 同意的方案） | 在 root 加 script；預約展示與聯絡表單送出設成轉換事件 |
| Google 收錄、查詢詞、點閱率 | Google Search Console | 驗證網域、送 sitemap |
| Bing 收錄 | Bing Webmaster Tools | 同上，ChatGPT 搜尋的索引來源是 Bing |
| **AI 搜尋帶來的流量** | GA4 自訂管道群組 | 把 referrer 含 `chatgpt.com`、`perplexity.ai`、`claude.ai`、`copilot.microsoft.com`、`gemini.google.com` 歸成「AI 搜尋」管道 |
| 對外投放與引用 | UTM 參數 | 所有對外貼的連結帶 `utm_source`／`utm_medium`，才分得出 AI 引用與自然搜尋 |
| 有沒有被 AI 引用 | 手動抽查 | 每月用 ChatGPT、Perplexity 問「CMMC 合規管理工具」「ISO 27001 稽核軟體 台灣」之類的題，看有沒有出現 Guidant AI |

## 七、驗收：AI 看得到內容嗎

開 prerender、部署後，**用爬蟲身分抓原始 HTML**，不是用瀏覽器看：

```bash
# 數字是 0 代表 AI 爬蟲看到的是空殼
curl -s -A "GPTBot" https://<官網網域>/ | grep -c "Guidant"
curl -s -A "ClaudeBot" https://<官網網域>/solutions/cmmc | grep -c "CMMC"

# 每一支路由都要有靜態檔（本機 build 後）
find out -name index.html | wc -l                # 應等於 17 頁 × 2 語言 = 34（加指南 6 篇 × 2）

# 結構化資料驗證
# https://validator.schema.org/ 貼網址
# https://search.google.com/test/rich-results
```

另外 `robots.txt`、`sitemap.xml`、`llms.txt` 三支用瀏覽器直接開要能看到內容。

## 八、待做清單（對應 Notion 子卡 CM-2940～2953）

| # | 做什麼 | 檔案 |
|---|---|---|
| 1 | 開 prerender、確認 `.output/public/` 每頁一支 `index.html`（併入 B1 第一步） | `vite.config.ts` |
| 2 | `pageHead()` 補 canonical、hreflang（zh-Hant／en／x-default）、og:url、og:image、og:locale | `src/i18n/index.ts`、各 `routes/**.tsx` |
| 3 | `public/robots.txt` 放 AI 爬蟲清單與 Sitemap 行 | `public/robots.txt` |
| 4 | sitemap 產生腳本，中英全頁 | `scripts/gen-sitemap.mjs` → `public/sitemap.xml` |
| 5 | JSON-LD 工具與五種型別，root 掛 Organization，各頁掛對應型別 | `src/lib/jsonld.ts`、`__root.tsx`、各路由 `head()` |
| 6 | 寫 `llms.txt` | `public/llms.txt` |
| 7 | 每區一張 og:image（1200×630） | `public/og/` |
| 8 | 接分析工具、設轉換事件、AI 搜尋管道群組 | `__root.tsx`、Cloudflare 後台 |
| 9 | Cloudflare Pages 專案連 GitLab repo，build `npm run build`，輸出 `.output/public` | Cloudflare 後台 |
| 10 | 上線後 Search Console、Bing Webmaster 驗證與送 sitemap | 後台操作 |
| 11 | B2B 站外佈局清單（LinkedIn、G2／Capterra、合作夥伴連結）給決策者排程 | 本 FR 新文件 |

網址先用 `VITE_SITE_URL` 環境變數佔位（Vite 的公開變數要 `VITE_` 前綴）。

## 九、參考資料

**公司內部（抄內容，寫法改 TanStack）**：`~/Projects/Design-Home/design-home-fe/`

| 檔 | 看什麼 |
|---|---|
| `apps/web/src/app/robots.ts` | AI 爬蟲 UA 清單與查證註解 |
| `apps/web/src/app/sitemap.ts` | sitemap 結構 |
| `apps/web/src/lib/jsonld.ts` | JSON-LD 工具、`<` 轉義 |
| `apps/web/src/app/llms.txt/route.ts` | llms.txt 內容骨架 |
| `apps/web/scripts/build.js` | 產 `_headers` 的做法 |
| `apps/web/src/app/layout.tsx`、`(main)/*/page.tsx` | 每頁 meta 要有哪些欄位（寫法不同，欄位照抄） |
| `apps/web/src/lib/payload.ts` | 官網 build 時打 Payload API 的資料層（含租戶過濾），未來接 CMS 直接抄 |
| `docs/decisions/ADR-003`、`ADR-005` | 為什麼選純靜態＋Cloudflare Pages＋webhook 重 build |
| `docs/runbooks/production-deploy.md` | Cloudflare Pages、R2、Tunnel、Access 的設定步驟 |
| `docs/ai-seo/faq-draft.md`、`local-presence-checklist.md` | FAQ 寫法、站外佈局清單結構 |
| `apps/admin/src/hooks/revalidateWeb.ts` | Payload 改內容後打 Deploy Hook 重 build（未來接 CMS 用） |

**外部**：

- TanStack Start 靜態 prerender：https://tanstack.com/start/latest/docs/framework/react/guide/static-prerendering
- TanStack Router `head()`（meta／links／scripts）：https://tanstack.com/router/latest/docs/framework/react/guide/document-head-management
- Cloudflare Pages 部署靜態站：https://developers.cloudflare.com/pages/
- schema.org `SoftwareApplication`：https://schema.org/SoftwareApplication 、`FAQPage`：https://schema.org/FAQPage
- Google 結構化資料測試：https://search.google.com/test/rich-results
- llms.txt 規範：https://llmstxt.org/
- 各家 AI 爬蟲 UA 官方頁：OpenAI https://platform.openai.com/docs/bots 、Anthropic https://support.anthropic.com/en/articles/8896518 、Perplexity https://docs.perplexity.ai/guides/bots
