中文译文
Astro v6 架构规则(严格模式)
1. 核心理念
遵循 Astro 的「HTML 优先 / 默认零 JavaScript」原则:
- 除非明确需要交互,否则一切都是静态 HTML。
- JavaScript 是一种成本 → 只有在能创造真实用户价值时才添加。
始终以「岛屿架构」思考:
- 页面是静态 HTML
- 交互部分是被隔离的岛屿
- 绝不把整个页面当作一个应用
在编写任何 JavaScript 之前,始终先问: 「这能否用 HTML + CSS 或服务端逻辑解决?」
2. 组件模型
使用
.astro组件来处理:- 布局
- 组合
- 静态 UI
- 数据获取
- 服务端逻辑(frontmatter)
.astro组件:- 在构建时或服务端运行
- 默认不发送 JavaScript
- 必须保持框架无关
绝不在
.astro中使用 React/Vue/Svelte 钩子
3. 岛屿(交互组件)
仅将框架组件(React、Vue、Svelte 等)用于交互。
将每个交互组件视为一个隔离的岛屿:
- 独立
- 自包含
- 范围最小
绝不:
- 水合整个页面或布局
- 将大型组件树包裹在单个岛屿中
- 在循环中不必要地创建许多小岛屿
优先:
- 静态列表渲染
- 仅水合最小的交互单元
4. 水合策略(关键)
始终使用
client:*指令显式定义水合。选择尽可能最低的优先级:
client:load→ 仅用于关键的、首屏内的交互client:idle→ 用于页面加载后的次要 UIclient:visible→ 用于首屏之外或重量级组件client:media→ 用于响应式 / 条件性 UIclient:only→ 仅在 SSR 失效时使用(window、localStorage 等)
默认规则: ❌ 绝不默认使用
client:load✅ 优先使用client:visible或client:idle水合是一项性能预算:
- 每个孤岛都会增加 JS
- 保持总 JS 最小化
📌 Astro 不会水合组件,除非通过 client:* 显式告知 :contentReference[oaicite:0]{index=0}
5. 服务端逻辑 vs 客户端逻辑
对于以下情况,优先使用服务端逻辑(在
.astrofrontmatter 内):- 数据获取
- 转换
- 过滤 / 排序
- 派生值
仅在以下情况使用客户端状态:
- 用户交互需要它
- 需要实时更新
避免:
- 在客户端重复逻辑
- 将服务端逻辑移入孤岛
6. 状态管理
除非绝对必要,避免使用客户端状态。
如果需要:
- 仅将状态限定在孤岛内部
- 除非有要求,绝不创建全局应用状态
对于跨孤岛状态:
- 使用轻量级共享存储(例如 nano stores)
- 默认避免使用重量级全局状态系统
7. 性能约束(硬性规则)
最小化发送到客户端的 JavaScript:
- Astro 仅为已水合的组件加载 JS :contentReference[oaicite:1]{index=1}
优先使用:
- 静态渲染
- 部分水合
- 惰性水合
避免:
- 水合大型列表
- 在循环中重复使用孤岛
- 过度使用
client:load
每个孤岛:
- 有自己的 bundle
- 独立加载
- 应保持小而专注 :contentReference[oaicite:2]{index=2}
8. 文件与项目结构
/pages- 入口点(SSG/SSR)
- 无客户端逻辑
/components- 共享 UI
- 孤岛位于此处
/layouts- 仅静态包装器
/content- Markdown / CMS 数据
让
.astro文件专注于组合,而非行为
9. 反模式(严格禁止)
- ❌ 在
.astro中使用 hooks - ❌ 将 Astro 变成 SPA 架构
- ❌ 水合整个布局/页面
- ❌ 到处使用
client:load - ❌ 将列表映射为已水合的组件
- ❌ 用客户端 JS 解决静态问题
- ❌ 用客户端逻辑替换服务端逻辑
10. 首选模式
- ✅ 静态优先渲染
- ✅ 最小化、隔离的岛屿
- ✅ 惰性水合(
visible、idle) - ✅ 服务端计算
- ✅ 先 HTML + CSS,后 JS
- ✅ 渐进增强
11. 决策框架(非常重要)
对于每个功能:
这可以是静态 HTML 吗? → 是 → 使用
.astro它需要交互吗? → 否 → 保持静态
它需要 JS 吗? → 是 → 创建一个岛屿
它应该在何时加载? → 选择最低优先级的
client:*
12. 心智模型(不可妥协)
Astro 不是:
- Next.js
- SPA 框架
- React 优先的系统
Astro 是:
- 静态优先渲染器
- 部分水合系统
- 性能优先的架构
思考方式: ❌ “构建一个应用” ✅ “交付 HTML + 撒点 JS”
English original
Astro v6 Architecture Rules (Strict Mode)
1. Core Philosophy
Follow Astro’s “HTML-first / zero JavaScript by default” principle:
- Everything is static HTML unless interactivity is explicitly required.
- JavaScript is a cost → only add when it creates real user value.
Always think in “Islands Architecture”:
- The page is static HTML
- Interactive parts are isolated islands
- Never treat the whole page as an app
Before writing any JavaScript, always ask: "Can this be solved with HTML + CSS or server-side logic?"
2. Component Model
Use
.astrocomponents for:- Layout
- Composition
- Static UI
- Data fetching
- Server-side logic (frontmatter)
.astrocomponents:- Run at build-time or server-side
- Do NOT ship JavaScript by default
- Must remain framework-agnostic
NEVER use React/Vue/Svelte hooks inside
.astro
3. Islands (Interactive Components)
Only use framework components (React, Vue, Svelte, etc.) for interactivity.
Treat every interactive component as an isolated island:
- Independent
- Self-contained
- Minimal scope
NEVER:
- Hydrate entire pages or layouts
- Wrap large trees in a single island
- Create many small islands in loops unnecessarily
Prefer:
- Static list rendering
- Hydrate only the minimal interactive unit
4. Hydration Strategy (Critical)
Always explicitly define hydration using
client:*directives.Choose the LOWEST possible priority:
client:load→ Only for critical, above-the-fold interactivityclient:idle→ For secondary UI after page loadclient:visible→ For below-the-fold or heavy componentsclient:media→ For responsive / conditional UIclient:only→ ONLY when SSR breaks (window, localStorage, etc.)
Default rule: ❌ Never default to
client:load✅ Preferclient:visibleorclient:idleHydration is a performance budget:
- Every island adds JS
- Keep total JS minimal
📌 Astro does NOT hydrate components unless explicitly told via client:* :contentReference[oaicite:0]{index=0}
5. Server vs Client Logic
Prefer server-side logic (inside
.astrofrontmatter) for:- Data fetching
- Transformations
- Filtering / sorting
- Derived values
Only use client-side state when:
- User interaction requires it
- Real-time updates are needed
Avoid:
- Duplicating logic on client
- Moving server logic into islands
6. State Management
Avoid client state unless strictly necessary.
If needed:
- Scope state inside the island only
- Do NOT create global app state unless required
For cross-island state:
- Use lightweight shared stores (e.g., nano stores)
- Avoid heavy global state systems by default
7. Performance Constraints (Hard Rules)
Minimize JavaScript shipped to client:
- Astro only loads JS for hydrated components :contentReference[oaicite:1]{index=1}
Prefer:
- Static rendering
- Partial hydration
- Lazy hydration
Avoid:
- Hydrating large lists
- Repeated islands in loops
- Overusing
client:load
Each island:
- Has its own bundle
- Loads independently
- Should remain small and focused :contentReference[oaicite:2]{index=2}
8. File & Project Structure
/pages- Entry points (SSG/SSR)
- No client logic
/components- Shared UI
- Islands live here
/layouts- Static wrappers only
/content- Markdown / CMS data
Keep
.astrofiles focused on composition, not behavior
9. Anti-Patterns (Strictly Forbidden)
- ❌ Using hooks in
.astro - ❌ Turning Astro into SPA architecture
- ❌ Hydrating entire layout/page
- ❌ Using
client:loadeverywhere - ❌ Mapping lists into hydrated components
- ❌ Using client JS for static problems
- ❌ Replacing server logic with client logic
10. Preferred Patterns
- ✅ Static-first rendering
- ✅ Minimal, isolated islands
- ✅ Lazy hydration (
visible,idle) - ✅ Server-side computation
- ✅ HTML + CSS before JS
- ✅ Progressive enhancement
11. Decision Framework (VERY IMPORTANT)
For every feature:
Can this be static HTML? → YES → Use
.astroDoes it require interaction? → NO → Stay static
Does it require JS? → YES → Create an island
When should it load? → Choose LOWEST priority
client:*
12. Mental Model (Non-Negotiable)
Astro is NOT:
- Next.js
- SPA framework
- React-first system
Astro IS:
- Static-first renderer
- Partial hydration system
- Performance-first architecture
Think: ❌ “Build an app” ✅ “Ship HTML + sprinkle JS”