Astro 静态站点深度:群岛架构 & 内容集合

Choyeon· 2026年9月2日· 2 分钟阅读· 240 阅读· 442 字· 1,676 字符
Astro 静态站点深度:群岛架构 & 内容集合

Astro 默认零 JavaScript,核心是群岛架构(组件按需水合)和类型安全的内容集合,兼具极致性能和现代开发体验。

群岛架构与水合策略

非交互内容输出纯静态 HTML,只有标记 client:load/visible/idle/only 的组件才会加载 JS 并水合。同一页面可混合 React/Svelte/Vue 组件互不冲突。

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

const blog = defineCollection({
  type: 'content',
  schema: z.object({
    title: z.string().max(80),
    description: z.string().max(200),
    pubDate: z.coerce.date(),
    tags: z.array(z.string()).default([]),
    cover: z.object({ src: z.string(), alt: z.string() }).optional(),
    draft: z.boolean().default(false),
    category: z.enum(['tutorial','technology','essays','translation']),
  }),
});
const projects = defineCollection({
  type: 'content',
  schema: ({ image }) => z.object({
    name: z.string(), summary: z.string(),
    hero: image(), stack: z.array(z.string()),
    repo: z.string().url().optional(), live: z.string().url().optional(),
    featured: z.boolean().default(false),
  }),
});
export const collections = { blog, projects };

// src/pages/blog/[...slug].astro
/* ---
import { getCollection, type CollectionEntry } from 'astro:content';
import { Image } from 'astro:assets';
import LikeCounter from '../../components/LikeCounter.svelte';

export async function getStaticPaths() {
  const posts = await getCollection('blog', ({ data }) => import.meta.env.DEV || !data.draft);
  return posts.map(p => ({ params: { slug: p.slug }, props: { post: p } }));
}
const { post } = Astro.props as { post: CollectionEntry<'blog'> };
const { Content } = await post.render();
--- ---
<article>
  <header>
    <h1>{post.data.title}</h1>
    {post.data.cover && <Image src={post.data.cover.src} alt={post.data.cover.alt} widths={[400,800,1200]} />}
  </header>
  <Content />
  <LikeCounter client:idle postSlug={post.slug} />
</article>
*/

Content Collections 类型安全

在 content/config.ts 中用 Zod 为集合定义 schema,getCollection 返回内容时自动校验 frontmatter,不匹配直接报错。支持图片自动优化。

水合指令 触发时机 体积开销 适合组件
(默认) 永远不水合 0 JS 纯展示卡片/正文
client:load 页面加载即水合 最高 导航/核心交互
client:idle 浏览器空闲时 中低 点赞/次要交互
client:visible 滚动进入视口 极低 页脚/长列表后项

最佳实践

默认先不写 client:*,确定需要交互再添加。内容集合 schema 严格化避免脏数据。用 getStaticPaths + Slug 预渲染所有动态路由。

本文作者

评论 (0)

暂无评论,来抢沙发吧。