Communitygithub.com

0xDarkMatter/claude-mods

Astro 框架模式、島嶼架構、內容集合、渲染策略與部署。適用於:astro、島嶼架構、內容集合、astro cloudflare、視圖轉場、部分水合、astrojs、SSG、SSR、混合渲染、astro 適配器。

claude-mods 是什麼?

此技能 (skill) 是專為 Astro 框架開發者設計的全面性參考指南,涵蓋了 Astro 生態系統中的核心概念與實務模式,包括島嶼架構 (Islands Architecture)、內容集合 (Content Collections)、渲染策略 (Rendering Strategies)、視圖轉場 (View Transitions) 以及跨平台部署。它提供了一個清晰的決策樹,幫助開發者根據專案需求(如內容類型、互動性需求、建置時間與邊緣運算需求)選擇最合適的渲染模式(SSG、SSR 或 Hybrid)。此外,技能也詳細說明了各種用戶端指令 (`client:load`, `client:idle`, `client:visible` 等) 的水合行為與適用場景,並提供 Astro 5 與 Astro 4 的內容集合 Schema 定義範例與查詢方式。最後,它還涵蓋了部署適配器的比較與選擇(如 Cloudflare、Vercel、Netlify、Node.js),以及一系列常見的開發陷阱與生產安全檢查清單,是建構高效能 Astro 應用不可或缺的知識庫。

相容平台✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/0xDarkMatter/claude-mods/tree/HEAD/skills/astro-ops

在你喜歡的 AI 中提問

開啟一個已預先載入此 Agent Skill 的新對話。

說明文件

Astro 操作指南

事實驗證至 2026 年 7 月。

Astro 框架開發的全面模式:島嶼架構、內容集合、渲染策略、視圖轉場與多平台部署。

渲染策略決策樹

選擇哪種渲染策略?
│
├─ 內容是否大部分為靜態(部落格、文件、行銷頁面)?
│  ├─ 是 → 內容變更頻率是否低於每日一次?
│  │  ├─ 是 → SSG (output: 'static')
│  │  │        TTFB 最快,可被 CDN 快取,執行階段零成本
│  │  └─ 否 → 混合模式 (output: 'hybrid')
│  │           預設靜態 + 依路由選擇性啟用 SSR
│  └─ 否 → 每個頁面是否需要個人化內容?
│     ├─ 是 → SSR (output: 'server')
│     │        依請求動態生成,可感知驗證狀態,即時資料
│     └─ 否 → 混合模式 (output: 'hybrid')
│             靜態外殼 + 伺服器島嶼處理動態部分
│
├─ 應用程式是否需要即時互動性(儀表板、SPA)?
│  ├─ 是 → 是否為完整的用戶端路由 SPA?
│  │  ├─ 是 → 考慮改用 React/Vue SPA,或使用 Astro + client:only
│  │  └─ 否 → 混合模式 + 島嶼架構
│  │           在靜態頁面中嵌入互動式島嶼
│  └─ 否 → SSG (output: 'static')
│
├─ 建置時間是否有疑慮(超過 1 萬頁)?
│  ├─ 是 → 使用混合模式搭配隨需渲染
│  │       預先渲染熱門頁面,對長尾頁面使用 SSR
│  └─ 否 → SSG 即可勝任
│
└─ 是否需要邊緣運算(全球低延遲)?
   ├─ 是 → SSR + Cloudflare/Vercel Edge 適配器
   └─ 否 → SSR + Node 適配器 或 SSG

設定

// astro.config.mjs
import { defineConfig } from 'astro/config';

// SSG(預設)- 所有頁面在建置時預先渲染
// SSG(預設)- 所有頁面在建置時預先渲染
export default defineConfig({
  output: 'static',
});

// SSR - 所有頁面在收到請求時渲染
// SSR - 所有頁面在收到請求時渲染
export default defineConfig({
  output: 'server',
  adapter: cloudflare(), // 或 vercel(), netlify(), node()
});

// 混合模式 - 預設為靜態,依頁面選擇性啟用 SSR
// 混合模式 - 預設為靜態,依頁面選擇性啟用 SSR
export default defineConfig({
  output: 'hybrid',
  adapter: cloudflare(),
});
---
// 在混合模式下,針對特定頁面選擇不進行預先渲染:
export const prerender = false;
// 在 SSR 模式下,選擇進行預先渲染:
// 在 SSR 模式下,選擇進行預先渲染:
export const prerender = true;
---

島嶼架構快速參考

指令水合時機傳送的 JS使用案例
client:load頁面載入後立即執行完整套件折疊區以上的互動元素(導航列、主視覺 CTA)
client:idle頁面閒置後執行 (requestIdleCallback)完整套件折疊區以下的互動元素(評論表單、聊天室)
client:visible滾動到可視區域時執行完整套件頁面深處元件(頁尾小工具、輪播圖)
client:media當媒體查詢條件符合時執行完整套件僅限行動裝置的導航、響應式元件
client:only="react"立即執行,完全跳過 SSR完整套件無法進行 SSR 的元件(Canvas、WebGL)
(無)永不 - 僅產生靜態 HTML零 JS靜態內容、卡片、標頭
---
import NavBar from '../components/NavBar.tsx';
import CommentForm from '../components/CommentForm.tsx';
import ImageCarousel from '../components/ImageCarousel.svelte';
import MobileMenu from '../components/MobileMenu.vue';
import ThreeScene from '../components/ThreeScene.tsx';
---

<!-- 立即載入 - 關鍵互動元素 -->
<NavBar client:load />

<!-- 頁面閒置後載入 - 非關鍵元素 -->
<CommentForm client:idle />

<!-- 滾入可視區域時載入 - 懶載入 -->
<ImageCarousel client:visible />

<!-- 僅在行動裝置上載入 -->
<MobileMenu client:media="(max-width: 768px)" />

<!-- 僅限用戶端,無 SSR(WebGL 無法在伺服器上執行) -->
<ThreeScene client:only="react" />

內容集合快速入門

定義 Schema

// src/content.config.ts (Astro 5) 或 src/content/config.ts (Astro 4)
import { defineCollection, z, reference } from 'astro:content';
import { glob } from 'astro/loaders';

const blog = defineCollection({
  loader: glob({ pattern: '**/*.{md,mdx}', base: './src/content/blog' }),
  schema: z.object({
    title: z.string(),
    description: z.string().max(160),
    pubDate: z.coerce.date(),
    updatedDate: z.coerce.date().optional(),
    heroImage: z.string().optional(),
    tags: z.array(z.string()).default([]),
    draft: z.boolean().default(false),
    author: reference('authors'), // 參照另一個集合
  }),
});

const authors = defineCollection({
  loader: glob({ pattern: '**/*.json', base: './src/content/authors' }),
  schema: z.object({
    name: z.string(),
    avatar: z.string(),
    bio: z.string(),
    socials: z.object({
      twitter: z.string().optional(),
      github: z.string().optional(),
    }).optional(),
  }),
});

export const collections = { blog, authors };

查詢集合

---
import { getCollection, getEntry } from 'astro:content';

// 取得所有非草稿的部落格文章,依日期排序
const posts = (await getCollection('blog', ({ data }) => !data.draft))
  .sort((a, b) => b.data.pubDate.valueOf() - a.data.pubDate.valueOf());

// 取得單一文章
const post = await getEntry('blog', 'my-first-post');

// 解析參照
const author = await getEntry(post.data.author);

// 渲染內容
const { Content, headings } = await post.render();
---

<Content />

內容集合 vs 外部 CMS

準則內容集合外部 CMS (Payload 等)
內容類型本機 Markdown/MDX、文件、部落格關聯式資料模型
作者開發者(版本控制)編輯者(管理員 UI、多用戶驗證)
驗證在建置時透過 Zod 確保型別安全CMS 端 Schema + API 合約
更新頻率隨網站一同部署獨立於部署之外
API 需求無(建置時查詢)供其他消費者使用的 REST/GraphQL
工作流程Git PR、簡易審查編輯工作流程、草稿、角色權限

經驗法則:從內容集合開始;只有當非開發人員需要在無需部署的情況下發布內容,或當內容確實是關聯式資料時,才考慮使用 CMS。

專案結構參考

project-root/
├── astro.config.mjs          # Astro 設定檔
├── tsconfig.json              # TypeScript 設定 (extends astro/tsconfigs)
├── package.json
├── public/                    # 靜態資源(依原樣複製)
│   ├── favicon.svg
│   ├── robots.txt
│   └── og-image.png
├── src/
│   ├── pages/                 # 基於檔案的路由
│   │   ├── index.astro        # → /
│   │   ├── about.astro        # → /about
│   │   ├── blog/
│   │   │   ├── index.astro    # → /blog
│   │   │   └── [slug].astro   # → /blog/:slug (動態)
│   │   ├── api/
│   │   │   └── search.ts      # → /api/search (API 端點)
│   │   └── [...slug].astro    # → 萬用路由/404
│   ├── layouts/
│   │   ├── BaseLayout.astro   # HTML 外殼, <head>, 全域樣式
│   │   └── BlogPost.astro     # 部落格文章版面
│   ├── components/
│   │   ├── Header.astro       # 靜態 Astro 元件
│   │   ├── Footer.astro
│   │   ├── NavBar.tsx         # React 島嶼
│   │   └── Counter.svelte     # Svelte 島嶼
│   ├── content/               # 內容集合原始檔案
│   │   ├── blog/
│   │   │   ├── post-one.md
│   │   │   └── post-two.mdx
│   │   └── authors/
│   │       └── jane.json
│   ├── content.config.ts      # 集合 Schema (Astro 5)
│   ├── middleware.ts           # 請求/回應中介軟體
│   ├── styles/
│   │   └── global.css
│   └── lib/                   # 共享工具
│       ├── utils.ts
│       └── constants.ts
└── .env                       # 環境變數

視圖轉場快速參考

---
// src/layouts/BaseLayout.astro
import { ViewTransitions } from 'astro:transitions';
---

<html>
  <head>
    <ViewTransitions />
  </head>
  <body>
    <slot />
  </body>
</html>

轉場指令

<!-- 跨頁面保留元素(維持狀態,避免重新渲染) -->
<audio transition:persist id="player">
  <source src="/music.mp3" />
</audio>

<!-- 用於動畫配對的命名轉場 -->
<img transition:name="hero" src={post.heroImage} />

<!-- 自訂動畫 -->
<div transition:animate="slide">內容</div>
<div transition:animate="fade">內容</div>
<div transition:animate="none">無動畫</div>

<!-- 搭配名稱使用 persist(用於多個持續元素) -->
<video transition:persist="media-player" />

生命週期事件

<script>
  document.addEventListener('astro:before-preparation', (e) => {
    // 在擷取新頁面之前 - 取消導航、顯示載入中
  });

  document.addEventListener('astro:after-preparation', (e) => {
    // 新頁面已擷取,在交換之前
  });

  document.addEventListener('astro:before-swap', (e) => {
    // 自訂 DOM 交換行為
  });

  document.addEventListener('astro:after-swap', () => {
    // DOM 已更新 - 重新初始化腳本
  });

  document.addEventListener('astro:page-load', () => {
    // 頁面完全載入(在初始載入及每次導航時觸發)
    // 使用視圖轉場時,應以此事件取代 DOMContentLoaded
  });
</script>

返回/前進處理

// astro.config.mjs
export default defineConfig({
  prefetch: {
    prefetchAll: true,         // 懸停時預先擷取所有連結
    defaultStrategy: 'hover',  // 'hover' | 'tap' | 'viewport' | 'load'
  },
});
<!-- 每個連結的預先擷取控制 -->
<a href="/about" data-astro-prefetch>懸停時預先擷取 (預設)</a>
<a href="/blog" data-astro-prefetch="viewport">進入可視區域時預先擷取</a>
<a href="/contact" data-astro-prefetch="load">立即預先擷取</a>
<a href="/external" data-astro-prefetch="false">不預先擷取</a>

部署決策樹

部署到哪裡?
│
├─ 需要邊緣運算 + Cloudflare 生態系統 (KV, D1, R2)?
│  └─ Cloudflare Pages/Workers
│     適配器:@astrojs/cloudflare
│     最適合:全球邊緣節點、Workers 綁定、成本效益
│
├─ 需要無伺服器 + Vercel 生態系統 (ISR, 分析)?
│  └─ Vercel
│     適配器:@astrojs/vercel
│     最適合:從 Next.js 遷移、圖片最佳化、ISR
│
├─ 需要無伺服器 + Netlify 生態系統 (表單, 身份驗證)?
│  └─ Netlify
│     適配器:@astrojs/netlify
│     最適合:JAMstack、內建表單、A/B 測試
│
├─ 需要完整的伺服器控制權(Docker、自訂執行環境)?
│  └─ Node.js (獨立執行或搭配 Express/Fastify)
│     適配器:@astrojs/node
│     最適合:自託管、WebSocket、長時間執行的程序
│
└─ 純靜態網站(無需 SSR)?
   └─ 任何靜態主機(GitHub Pages、S3、Cloudflare Pages)
      不需要適配器,output: 'static'
      最適合:部落格、文件、行銷網站

適配器安裝

# Cloudflare
npx astro add cloudflare

# Vercel
npx astro add vercel

# Netlify
npx astro add netlify

# Node.js
npx astro add node

常見陷阱

陷阱原因修復方式
水合不一致錯誤伺服器 HTML 與用戶端渲染結果不同(日期、隨機 ID、瀏覽器 API)對依賴瀏覽器的元件使用 client:only,或確保渲染結果具有決定性
import.meta.env 在用戶端未定義只有 PUBLIC_ 前綴的變數才會暴露給用戶端程式碼重新命名為 PUBLIC_MY_VAR 或透過 props 從伺服器傳遞
SSG 中動態路由回傳 404getStaticPaths() 未回傳所有可能的參數確保 getStaticPaths() 回傳所有有效的路徑,或切換至混合模式/SSR
圖片未最佳化使用 <img> 而非 Astro 的 <Image /> 元件從 astro:assets 匯入:import { Image } from 'astro:assets' 並對 src 使用本機匯入
SSR 在沒有適配器時失敗output: 'server' 或 'hybrid' 需要一個部署適配器安裝適配器:npx astro add cloudflare (或 vercel、netlify、node)
MDX 元件未渲染未將自訂元件傳遞給 MDX 內容透過 <Content components={{ MyComponent }} /> 傳遞元件,或使用 astro.config.mjs 的 MDX 設定
內容集合 schema 變更未生效型別生成已快取,使用到過時的 .astro 型別執行 astro sync 重新生成型別,重新啟動開發伺服器
在 Astro 元件上使用 client:*用戶端指令僅適用於框架元件(React、Vue、Svelte)Astro 元件僅為靜態;將互動部分提取到一個框架元件中
document / window 未定義伺服端程式碼無法存取瀏覽器全域變數使用 if (typeof window !== 'undefined') 進行防護,或移至 client:only
樣式在元件之間洩漏使用全域 CSS 而非作用域樣式使用 <style>(在 .astro 中預設為作用域)或刻意使用 <style is:global>
視圖轉場破壞腳本DOMContentLoaded 在搭配視圖轉場時僅觸發一次改用 astro:page-load 事件,該事件會在每次導航時觸發
環境變數在正式環境中遺失.env 未載入或平台環境變數未設定在 astro.config.mjs 中使用 envField 進行驗證;在平台管理後台中設定變數

正式環境安全檢查清單

對於每次正式環境部署,都需處理以下事項:

  • CSP 標頭 - 設定嚴格的 Content-Security-Policy(請參閱 references/deployment.md 中的中介軟體模式)
  • 遠端圖片限制 - 強制使用明確的 image.domains / remotePatterns 允許清單;絕不從使用者輸入推導圖片 URL(SSRF 風險)
  • Host 標頭驗證 - 在中介軟體中驗證請求的主機是否符合預期網域(僅限 SSR/混合模式)
  • 機密管理 - 在 Cloudflare 上,使用 Workers Bindings (wrangler secret put),而非內建在程式碼中的環境變數;在其他平台則使用平台的機密儲存庫
  • 僅限 HTTPS - 確保所有外部資源(腳本、圖片、字型)都透過 HTTPS 載入
  • 輸入驗證 - 在 SSR 環境中清理所有使用者輸入(查詢參數、表單主體、Cookie)

參考檔案

檔案內容行數
references/content-collections.mdSchema 模式、Zod 型別、查詢、MDX、內容層 API、遷移~500
references/islands-rendering.md島嶼模式、用戶端指令、部分水合策略、效能~300
references/view-transitions.md轉場 API、生命週期事件、動畫、SPA-like 導航~250
references/deployment.md適配器設定、Cloudflare/Vercel/Netlify/Node.js 模式、CSP、安全性~400
references/project-structure.mdAstro 專案慣例、組織架構、命名規則~200

Individual skills in this repo

This repo contains 1 individual skill — each has its own dedicated page.

相關技能