本文へ移動
cccskills
無料GitHub で公開

web-meta-framework-astro

Astro content-first framework - islands architecture, content collections, file-based routing, SSR/SSG hybrid rendering, View Transitions, server islands, multi-framework component support

インストール方法を見る

含まれるファイル(8)

  • SKILL.md14.9 KB
  • examples/content.md10.0 KB
  • examples/core.md6.6 KB
  • examples/integrations.md7.6 KB
  • examples/islands.md8.0 KB
  • examples/routing.md7.7 KB
  • metadata.yaml368 B
  • reference.md3.0 KB

SKILL.md(原文)

インストールする前に、エージェントに与えられる指示の中身を確認できます。

Astro Patterns

Quick Guide: Astro renders pages to static HTML with zero client JavaScript by default. .astro components carry static content; framework components become interactive islands only when given a client:* directive. Content collections give structured Markdown type-safe frontmatter through Zod schemas. Rendering mode is per page: static unless export const prerender = false. Astro 6 replaced <ViewTransitions /> with <ClientRouter />, replaced Astro.glob() with import.meta.glob(), moved z from astro:content to astro/zod (now Zod 4), requires string getStaticPaths() params, and requires Node 22.12.0+.

Detailed Resources:

  • examples/core.md — typed props, expressions, nested layouts, scoped vs global styles, script handling
  • examples/islands.md — directive selection, client:only, multi-framework islands, server islands, cross-island state
  • examples/content.md — collection schemas, querying, rendering, references, custom loaders, live collections
  • examples/routing.md — static and dynamic routes, rest params, pagination, on-demand routes, endpoints, 404
  • examples/integrations.md — framework integrations, View Transitions, persistence, animations, Starlight
  • reference.md — project layout, route priority, collection API, adapters, rendering checklist

Which path applies

  • Every page is static — the default. No output setting and no adapter; dynamic routes need getStaticPaths(). Follow examples/routing.md.
  • A few pages need request-time data — keep the default, add export const prerender = false to those pages, and install a server adapter. Same file, plus the adapter table in reference.md.
  • Most pages need request-time data — set output: "server" and opt individual pages back to static with export const prerender = true.

<critical_requirements>

Before writing Astro code

Leave pages static and add export const prerender = false only where the page reads request-time data. Static is the default and is where the framework's speed comes from.

Install a server adapter before any page opts out of prerendering. Without one, a build containing prerender = false fails.

Give a framework component a client:* directive when it needs to be interactive. Without a directive it renders to static HTML and its event handlers never run.

Define collections in src/content.config.ts with a Zod schema. The schema validates frontmatter at build time and generates the types the queries return.

Use getStaticPaths() for dynamic routes in static mode. On-demand routes read Astro.params directly and need no such export.

</critical_requirements>


Auto-detection: Astro, .astro files, astro.config, islands architecture, client:load, client:visible, client:idle, client:only, client:media, server:defer, content collections, defineCollection, defineLiveCollection, getCollection, getLiveCollection, getEntry, getLiveEntry, render, astro:content, astro:transitions, ClientRouter, getStaticPaths, Astro.props, Astro.params, Astro.cookies, Astro.redirect, prerender, astro add, @astrojs/react, @astrojs/vue, @astrojs/svelte, Starlight

Applies to:

  • .astro component syntax — frontmatter, template expressions, slots, layouts, scoped styles
  • Islands: client directives, hydration timing, server islands, mixing UI frameworks on one page
  • Content collections: schemas, loaders, querying, rendering, cross-collection references
  • File-based routing: static, dynamic, rest parameters, pagination, API endpoints
  • Rendering mode: static, on-demand, and per-page prerender control
  • View Transitions: <ClientRouter />, transition directives, persisted elements

Handled elsewhere:

  • What an island renders internally — a hydrated component follows the conventions of whichever UI library wrote it, and Astro settles only the boundary.
  • Which CSS approach fills a <style> block — the scoping rules here are Astro's; the styling system is not.
  • Which store library fills the cross-island seam — that islands share no tree, and that a module-scoped store is the way across, is settled in examples/islands.md; which store you reach for is not.
  • Fully interactive applications where every route is user-specific — that shape wants a framework whose default is on-demand rendering rather than one whose default is static output.

<philosophy>

Astro is a content-first framework that ships zero JavaScript by default. Most of a page is static HTML; small interactive "islands" hydrate independently, each paying only for itself.

Four consequences follow, and they explain most of the API:

  1. A component is static until told otherwise — client:* is the opt-in, so the cost of interactivity is always visible at the call site.
  2. The UI library is a detail — React, Vue, Svelte, Solid and Preact components are all just island contents, and one page can carry several.
  3. Content is typed data — collections put a Zod schema between Markdown frontmatter and the code that reads it, so a typo in a post fails the build rather than the page.
  4. Rendering mode is per page — static and on-demand pages coexist in one project, which is why prerender is an export rather than a global setting.
</philosophy>

<decision_framework>

Static or on-demand? A page needs on-demand rendering when it reads cookies, headers or user-specific data at request time, or when its data changes faster than you are willing to rebuild. Everything else is static — including data that changes hourly, which a rebuild handles more cheaply than an adapter does.

.astro or a framework component? No client-side interactivity means .astro — zero JavaScript. Simple interactivity (a toggle, a show/hide) is .astro plus a <script> tag, which is lighter than a framework. Reach for a framework component when the interaction needs that framework's own state model.

Which client directive? The table in Pattern 4 maps each one to what it is for. client:only is the last resort, for a component that cannot server-render at all.

Build-time or live collection? defineCollection for anything that is the same on every request — posts, docs, changelogs, author bios. defineLiveCollection only when the data must be fresh per request (inventory, pricing), which also forces that page into on-demand rendering.

</decision_framework>


<patterns>

Core patterns

Pattern 1: Astro component structure

An .astro file is a server-only script between --- fences followed by an HTML template. The script never reaches the browser, so data fetching belongs there.

---
interface Props { title: string; description?: string }
const { title, description = "Default" } = Astro.props;
const posts = await getCollection("blog");
---

<h1>{title}</h1>
{posts.map((post) => <a href={`/blog/${post.id}`}>{post.data.title}</a>)}

<style>h1 { color: navy; }</style>

Styles in a <style> block are scoped to the component unless marked is:global.

Full code: examples/core.md

Pattern 2: Slots for composition

A <slot /> receives content from the parent. Named slots take a matching slot="name" attribute, and anything inside the <slot> element is fallback content when nothing is passed.

<article>
  <header><slot name="header"><h2>{title}</h2></slot></header>
  <slot />
  <footer><slot name="footer" /></footer>
</article>

Full code: examples/core.md

Pattern 3: Layouts

A layout is an ordinary component that wraps page content through its default slot, and layouts nest — a blog layout wrapping a base layout wrapping the page.

---
const { title } = Astro.props;
---
<html lang="en">
  <head><title>{title}</title></head>
  <body><main><slot /></main></body>
</html>

Full code: examples/core.md

Pattern 4: Islands and client directives

Framework components render to static HTML until a client:* directive hydrates them. The directive chooses when hydration happens.

DirectiveHydratesUse for
client:loadImmediately on page loadCritical interactive UI
client:idleWhen the browser is idleLower-priority interactivity
client:visibleWhen it scrolls into the viewportBelow-the-fold content
client:mediaWhen a media query matchesResponsive interactivity
client:onlyClient only, skipping the server renderBrowser-dependent components
<Header />                                   <!-- static, zero JS -->
<SearchBar client:load />
<Comments client:visible />
<Analytics client:media="(max-width: 768px)" />

Full code: examples/islands.md

Pattern 5: Server islands

server:defer renders a component per request while the rest of the page stays cacheable. The fallback slot holds its place until it arrives.

<ProductInfo product={product} />

<UserReviews server:defer>
  <div slot="fallback">Loading reviews...</div>
</UserReviews>

Full code: examples/islands.md

Pattern 6: Content collections

A collection pairs a loader with a Zod schema. getCollection queries it with an optional filter, and render() turns an entry's Markdown into a component.

// src/content.config.ts
const blog = defineCollection({
  loader: glob({ pattern: "**/*.md", base: "./src/content/blog" }),
  schema: z.object({
    title: z.string(),
    pubDate: z.coerce.date(),
    draft: z.boolean().default(false),
  }),
});
export const collections = { blog };
const posts = await getCollection("blog", ({ data }) => !data.draft);
const { Content, headings } = await render(post);

Live collections are a separate mechanism: defineLiveCollection in src/live.config.ts (not content.config.ts), queried with getLiveCollection() / getLiveEntry(), and only from on-demand pages.

Full code: examples/content.md

Pattern 7: File-based routing

src/pages/ maps to URLs. [param] is a single dynamic segment, [...rest] matches any depth, and a leading underscore excludes a file from routing.

src/pages/
├── index.astro          → /
├── blog/[id].astro      → /blog/:id
├── docs/[...slug].astro → /docs and /docs/*
└── _helpers.ts          → not a route

In static mode each dynamic route exports getStaticPaths() returning { params, props } pairs; paginate() inside it generates numbered pages.

Full code: examples/routing.md

Pattern 8: On-demand rendering and endpoints

export const prerender = false moves a page to request time, where Astro.cookies, Astro.redirect() and a Response return value all become available. API endpoints are .ts files exporting one handler per HTTP method, and they default to static like everything else.

export const prerender = false;

export const GET: APIRoute = async ({ url }) => {
  const query = url.searchParams.get("q");
  if (!query)
    return new Response(JSON.stringify({ error: "Missing query" }), {
      status: 400,
    });
  return new Response(JSON.stringify(await searchDatabase(query)));
};

Full code: examples/routing.md

Pattern 9: View Transitions

<ClientRouter /> in the document head enables cross-page transitions. transition:name pairs elements so they morph, and transition:persist keeps an element alive across a navigation.

<head><ClientRouter /></head>

<img src={post.data.heroImage} transition:name={`hero-${post.id}`} transition:animate="slide" />
<audio controls transition:persist><source src="/music.mp3" type="audio/mp3" /></audio>

Full code: examples/integrations.md

</patterns>

<red_flags>

Red flags

Breaks at runtime:

  • A dynamic route in static mode with no getStaticPaths() — the build fails with "getStaticPaths() is required".
  • prerender = false with no server adapter installed — the build fails.
  • <ViewTransitions /> — removed in Astro 6; import <ClientRouter /> from astro:transitions.
  • Astro.glob() — removed in Astro 6; use import.meta.glob().
  • import { z } from "astro:content" — removed in Astro 6; import z from astro/zod, which is Zod 4, so z.string().email() is now z.email().
  • Numeric getStaticPaths() params — Astro 6 requires strings; wrap with String(id).
  • astro.config.cjs — Astro 6 requires ESM (.mjs or .ts).
  • Functions, class instances or symbols passed as props to a hydrated component — island props must be serializable.
  • Astro.props read outside the frontmatter fence, or an .astro component imported into a framework component — neither is available there.
  • Astro 6 on Node below 22.12.0 — unsupported.

Surprising behaviour:

  • client:load on everything defeats the architecture; a component with no interactivity wants no directive at all.
  • client:only skips the server render, so nothing is in the HTML for crawlers — prefer client:load wherever the component can render on the server.
  • Data fetched in a <script> tag creates a client waterfall; frontmatter runs server-side and has no such cost.
  • A collection with no schema loses both build-time validation and generated types.
  • output: "server" on a mostly-static site gives up the default's caching for pages that did not need it.
  • Unfiltered getCollection returns drafts alongside published entries.
  • <style> is scoped by default — reach for <style is:global> or the :global() selector deliberately.
  • <script> is bundled and deduped; is:inline opts out, which is what makes a script re-run on every View Transitions navigation.
  • client:visible waits on IntersectionObserver, so a component that is never on screen never hydrates.
  • Astro.redirect() works only on on-demand pages; a static page cannot redirect at request time.
  • Islands share no state — cross-island communication needs a store or events you bring.
  • transition:persist needs the same transition:name on both pages, or the element is recreated.
  • Collection entry ids come from filenames unless frontmatter overrides them.
  • Live collections cannot render MDX, and import.meta.env is inlined at build time — read runtime secrets from process.env.
  • A [...slug] route matches its own base path when a params entry passes undefined.

</red_flags>

レビュー

まだレビューはありません。使ってみた感想をお寄せください。

同じリポジトリのスキル

概要と使いどころ

Hugging Face Inference SDK patterns for TypeScript/Node.js — InferenceClient setup, chat completion, text generation, streaming, embeddings, image generation, audio transcription, translation, summarization, and Inference Endpoints

日本語の概要は準備中です。原文の説明を表示しています。

agents-inc/skills242026年9月8日 更新

LiteLLM proxy server setup, TypeScript client patterns via OpenAI SDK, model routing, fallbacks, load balancing, spend tracking, virtual keys, and production deployment

日本語の概要は準備中です。原文の説明を表示しています。

agents-inc/skills242026年9月8日 更新

Serverless GPU compute platform for AI model deployment — web endpoints, GPU functions, model serving, and TypeScript client patterns

日本語の概要は準備中です。原文の説明を表示しています。

agents-inc/skills242026年9月8日 更新

Local LLM inference with the Ollama JavaScript client -- chat, streaming, tool calling, vision, embeddings, structured output, model management, and OpenAI-compatible endpoint

日本語の概要は準備中です。原文の説明を表示しています。

agents-inc/skills242026年9月8日 更新

Replicate SDK patterns for TypeScript/Node.js -- client setup, predictions, streaming, webhooks, file handling, model versioning, deployments, and training

日本語の概要は準備中です。原文の説明を表示しています。

agents-inc/skills242026年9月8日 更新

Together AI SDK patterns for TypeScript — client setup, chat completions, streaming, structured output, function calling, embeddings, image generation, fine-tuning, and OpenAI-compatible endpoints

日本語の概要は準備中です。原文の説明を表示しています。

agents-inc/skills242026年9月8日 更新

agents-inc のスキルをすべて見る

このスキルの問題を報告する