AstroAstro 6Content Security PolicyContent Collections前端框架Astro 教學

Astro 6 三大核心更新:CSP、Runtime 與遷移實戰

Astro 6 正式發布:Content Security Policy、Runtime 改進、Content Collections 重構三大更新對現有專案的實際影響。立即了解升級注意事項!

· 5 分鐘閱讀

三週前 Astro 6 正式發布,很多人在問「該升級嗎?」這篇文章不做功能列表,而是從「實際影響」的角度,分析三個核心更新對現有 Astro 專案的影響,以及何時該 adopt。


前言:Astro 6 的發布背景

Astro 在 2026 年初的社群調查中,成為「內容驅動網站」類型的首選框架——領先 Next.js 超過 20 個百分點。但 Astro 的問題也很明顯:企業級功能落後

Astro 6 的三個核心更新(CSP、Runtime、Content Collections),都是在補這個差距。


更新一:Content Security Policy(CSP)原生支援

CSP 是 Astro 6 最重要的企業級功能。過去,Astro 專案要實作 CSP,需要自己寫 middleware,或者用第三方套件。Astro 6 現在內建 CSP 支援

實作方式

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

export default defineConfig({
  output: 'static', // 或 'server'、'hybrid'
  security: {
    csp: {
      // 允許內聯脚本和樣式(needed for Astro's island architecture)
      inlineScripts: true,
      inlineStyles: true,
      
      // 設定允許的來源
      directives: {
        'default-src': ["'self'"],
        'script-src': ["'self'", "'unsafe-inline'"],
        'style-src': ["'self'", "'unsafe-inline'"],
        'img-src': ["'self'", 'https:', 'data:'],
        'connect-src': ["'self'", 'https://api.example.com'],
      },
      
      // 報告端點(CSP 違規會 POST 到這個 URL)
      reportUri: '/__csp-report',
    },
  },
});

這個更新的實際影響

對於大多數內容網站(部落格、文檔、行銷頁面),內建的 CSP 設定綁定太嚴格,可能需要客製化。真正受惠的是企業內部系統或 SaaS 產品——這些產品本來就需要嚴格的安全政策,Astro 6 的 CSP 支援讓他們可以用 Astro 來建構,節省原本需要自己處理的安全設定成本。


更新二:Runtime 效能改進

Astro 6 的 Runtime(用於 SSR 和 Islands 的客戶端 JavaScript)有兩個重要改進。

改進一:更小的 hydration bundle

Astro 6 重新設計了 client 指令的 hydration 策略,減少了約 23% 的 client-side JavaScript

---
// 假設有一個互動式搜尋元件
import SearchBox from './SearchBox.tsx';
---

<!-- Astro 5:整個元件 hydrate -->
<SearchBox client:load />

<!-- Astro 6:更聰明的分割 -->
<!-- 當元件在 viewport 內才 hydrate,且只下載需要的部分 -->
<SearchBox client:visible={ { rootMargin: "200px" } } />

client:visible 這個 directive 現在底層使用 Intersection Observer 的改進版本,hydration 只在元素真正可見時才觸發,而且只下載需要的 JavaScript,不再是整個 bundle。

改進二:Server Render 效能提升

Astro 6 的 SSR 模式現在使用Streaming HTML作為預設行為,不再需要手動設定:

---
// Astro 6:streaming 是預設行為
// 這個元件的 HTML 會盡快 flush 到客戶端
// 不需要 await,也不需要特殊的 SSR 設定
const data = await fetchSomeData();
---

<main>
  <h1>{data.title}</h1>
  <!-- 其他內容會與這個平行 render -->
  <AsyncComponent data={data} />
</main>

Streaming SSR 的注意事項

Streaming HTML 在某些情境下可能造成問題——例如,當你在 <head> 裡有依賴資料的 meta 標籤時:

---
// 這個 meta 標籤依賴 fetch 的資料
const seo = await fetchSeoData();
---

<head>
  <!-- Astro 5:這個 meta 在 HTML flush 後就固定了 -->
  <!-- Astro 6:streaming 可能在 meta 完全產生前就 flush -->
  <title>{seo.title}</title>
</head>

Astro 6 解決了這個問題,用 <meta>is:inline 來確保關鍵 meta 標籤在 streaming 時不被衝掉:

<head>
  <title is:inline>{seo.title}</title>
  <!-- is:inline 確保這個標籤在 streaming 時被正確處理 -->
</head>

更新三:Content Collections 重構

Content Collections 是 Astro 最受歡迎的功能之一——讓你在 src/content/ 資料夾中用 Markdown 或 MDX 寫內容,並用 type-safe 的 API 取用。

Astro 6 對 Content Collections 做了破壞性重構

新的 schema 定義方式

// src/content/config.ts
import { defineCollection, z } from 'astro:content';

const blog = defineCollection({
  // Astro 6:使用新的 zod 整合方式
  schema: ({ image }) => z.object({
    title: z.string(),
    description: z.string().max(160),
    pubDate: z.coerce.date(),
    updatedDate: z.coerce.date().optional(),
    heroImage: image().optional(), // Astro 6 的新語法
    tags: z.array(z.string()).default([]),
    draft: z.boolean().default(false),
  }),
});

export const collections = { blog };

Astro 6 的破壞性變更

getStaticPaths 的返回格式改變

// Astro 5
export async function getStaticPaths() {
  const posts = await getCollection('blog');
  return posts.map(post => ({
    params: { slug: post.slug },
    props: { post },
  }));
}

// Astro 6:slug 改為 id,API 更一致
export async function getStaticPaths() {
  const posts = await getCollection('blog');
  return posts.map(post => ({
    params: { id: post.id }, // 注意:不是 slug 了
    props: { post },
  }));
}

這個變更的背後原因:過去「slug」和「id」在 Content Collections 裡指的是同樣的東西,但當使用虛擬內容(從 CMS 或資料庫而來的內容)時,這個區別就變得很重要。Astro 6 統一用 id 來代表一個內容項目的識別符。


Astro 6 vs Next.js 16:何時選哪個

這是 EditorInChief 要我特別著墨的問題。

維度Astro 6Next.js 16
核心定位內容驅動網站全端應用、SaaS 產品
SEO 友好度極高(原生 MPA)高(但需要額外設定)
學習曲線中高
SSR / API Routes支援(Output: server)完整支援
企業級安全CSP 原生支援需要額外設定
內容管理Content Collections + MDXApp Router + Server Components
生態系成熟度較小,但高度整合龐大且完整

選 Astro 6 的時機

  • 部落格、文檔、行銷網站
  • 對 SEO 有高度要求
  • 想要最小的 JavaScript bundle
  • 團隊熟悉 Markdown/MDX 寫作流程

選 Next.js 16 的時機

  • 需要完整的後端 API(不只是 SSR)
  • 高度互動的應用(複雜的客戶端狀態)
  • 團隊已經熟悉 React 生態系
  • 需要與大型 CMS 或電子商務平台深度整合

升級注意事項

從 Astro 5 升級到 Astro 6

最重要的三件事:

1. 備份 src/content/config.ts

Content Collections schema 格式有重大變更。升級前,確保你對現有的 schema 有完整備份。

2. 檢查 getStaticPaths 的返回值

post.slug 全部改成 post.id。如果你的 slug 是從 frontmatter 讀取出來的自訂值,可以用 post.data.slug 代替。

3. 測試 Streaming SSR

如果你的網站有 <head> 內的動態 meta 標籤,確保用 is:inline 處理它們。


總結:誰該現在升級

Astro 6 是一個企業級功能補完的版本,不是效能爆炸的版本。

立刻升級

  • 新專案,直接用 Astro 6
  • 企業內部系統(受益於 CSP)
  • 需要更好 SSR Streaming 效能的現有專案

觀望 1-2 個月

  • 內容網站但目前運行良好(等 CSP 生態系更完整)
  • 使用很多第三方 Astro 整合的專案(等整合作者更新)

不建議升級

  • 已有穩定 Astro 5 專案,沒有明顯痛點(等等看社群的第一批坑)

本文屬於「Astro 框架」系列文章。