| name | astro |
| description | Fast static sites with SSG/SSR and component islands. Trigger: When building Astro websites, implementing islands, or configuring SSG/SSR. |
| license | Apache 2.0 |
| metadata | {"version":"1.1","type":"framework","skills":["react","typescript"],"dependencies":{"astro":">=5.0.0 <6.0.0","typescript":">=5.0.0 <6.0.0","react":">=18.0.0 <19.0.0"}} |
Astro
Fast sites with SSG/SSR, minimal JS, TypeScript, and client island architecture.
Client island examples use React (@astrojs/react). For Vue, Svelte, or Solid islands, replace <ReactComp client:load /> with your framework's component — the directive syntax (client:load, client:visible, client:idle) is identical.
When to Use
- Static sites (SSG), server-rendered (SSR), or hybrid
- Content-focused sites (blogs, docs, marketing)
- Partial hydration with islands
Don't use for:
- Full SPAs (use react)
- Client-heavy apps with constant state
- Real-time dashboards with WebSockets
Critical Patterns
✅ REQUIRED: Detect Project Type First
Check astro.config.mjs for project type before coding.
export default defineConfig({ output: 'static' });
export default defineConfig({ output: 'server', adapter: node() });
export default defineConfig({ output: 'hybrid', adapter: node() });
✅ REQUIRED: Use .astro Components by Default
---
interface Props { title: string; }
const { title } = Astro.props;
---
<h1>{title}</h1>
<!-- WRONG: React for static content (unnecessary JS) -->
<!-- <ReactHeader title={title} client:load /> -->
✅ REQUIRED: Client Directives Sparingly
<!-- CORRECT: Only interactive components get JS -->
<Counter client:load />
<StaticContent /> <!-- No directive = zero JS -->
<!-- WRONG: Everything hydrated -->
<Header client:load />
<Footer client:load />
✅ REQUIRED: getStaticPaths for Dynamic Routes (SSG)
export async function getStaticPaths() {
const posts = await getPosts();
return posts.map((post) => ({
params: { slug: post.slug },
props: { post },
}));
}
✅ REQUIRED: SSR with prerender: false
---
export const prerender = false; // Requires adapter
const user = Astro.locals.user;
const data = await fetchUserData(user.id);
---
<h1>Welcome, {user.name}</h1>
✅ REQUIRED: Configure Output Mode
export default defineConfig({ output: 'static' });
export default defineConfig({ output: 'server', adapter: node() });
export default defineConfig({ output: 'hybrid', adapter: node() });
Decision Tree
No adapter (SSG-only)?
→ see ssg-patterns.md
Has adapter + output: 'server'?
→ see ssr-patterns.md
Has adapter + output: 'hybrid'?
→ see hybrid-strategies.md
Adding interactivity?
→ see client-directives.md
Managing content (blog, docs)?
→ see content-collections.md
Building forms?
→ see actions.md
Smooth page transitions or faster navigation?
→ see client-navigation.md
Auth or request logging?
→ see middleware.md
API keys or secrets?
→ see env-variables.md
Dynamic routes with known paths?
→ getStaticPaths (SSG)
Dynamic routes with user data?
→ prerender: false (SSR)
Immediate interaction?
→ client:load
Below fold interaction?
→ client:visible
Non-critical interaction?
→ client:idle
Example
SSG Blog Post
---
// src/pages/blog/[slug].astro
interface Props { post: { title: string; content: string }; }
export async function getStaticPaths() {
const posts = await getPosts();
return posts.map((post) => ({ params: { slug: post.slug }, props: { post } }));
}
const { post } = Astro.props;
---
<article>
<h1>{post.title}</h1>
<div set:html={post.content} />
</article>
SSR Dashboard
---
// src/pages/dashboard.astro
export const prerender = false;
const user = Astro.locals.user;
const data = await fetchUserData(user.id);
---
<h1>Welcome, {user.name}</h1>
<p>Last login: {data.lastLogin}</p>
Hybrid Config
import { defineConfig } from "astro/config";
import node from "@astrojs/node";
export default defineConfig({
output: "hybrid",
adapter: node({ mode: "standalone" }),
});
Edge Cases
- SSG-only errors: No adapter →
prerender: false/Astro.locals/POST fail build.
- SSR needs adapter: Install adapter (node/vercel/netlify) for
output: 'server'/'hybrid'.
- getStaticPaths in SSR: Skip when
prerender: false (routes render on request).
- Hybrid default: Pages default SSG; set
prerender: false only for SSR.
- Env variables:
PUBLIC_ prefix for client-side, no prefix for server.
- Client directives: Work in both SSG and SSR.
- Migration SSG→SSR: Install adapter, set output
'hybrid', add prerender: false per page.
- Architecture: Apply Clean Architecture/SOLID only with complex server logic. See architecture-patterns SKILL.md.
Checklist
Resources