Skip to content
>_devvkit
$devvkit learn --librarie astro-guide

Astro Guide

[astro][ssg][ssr][islands]
JavaScript / TypeScript
Install
npm create astro@latest
# or: pnpm create astro@latest

Astro is a web framework designed for content-rich sites. It renders to HTML at build time and ships zero JavaScript by default. Interactive UI is handled via "islands" — isolated components that hydrate independently.

Astro supports multiple UI frameworks in the same project (React, Vue, Svelte, Solid, Lit, Preact). Components from different frameworks can coexist on the same page. View transitions add SPA-like navigation without client-side JS.

Astro's content collections provide type-safe Markdown/MDX with schema validation. Built-in RSS, sitemap, and image optimization. Deploy to any host — Netlify, Vercel, Cloudflare, Node, or static.

Setup

Create projectScaffold Astro site.
npm create astro@latest my-site -- --template basics
cd my-site
npm run dev
Add a frameworkAdd React/Vue/Svelte.
npx astro add react
npx astro add vue
npx astro add svelte

Pages & Routing

Page routeAstro page (server).
---
// src/pages/index.astro
import Layout from '../layouts/Layout.astro'
const { data: posts } = await Astro.glob('../content/posts/*.mdx')
---
<Layout title="Home">
  {posts.map(post => <a href={post.url}>{post.frontmatter.title}</a>)}
</Layout>
Dynamic routeSSG with getStaticPaths.
---
// src/pages/posts/[...slug].astro
export async function getStaticPaths() {
  const posts = await getCollection('blog')
  return posts.map(post => ({ params: { slug: post.slug } }))
}
const { slug } = Astro.params
const entry = await getEntry('blog', slug)
---
<article>{entry.body}</article>

Content Collections

Content collectionType-safe content.
// src/content/config.ts
import { z, defineCollection } from 'astro:content'

const blog = defineCollection({
  type: 'content',
  schema: z.object({
    title: z.string(),
    pubDate: z.date(),
    tags: z.array(z.string()),
  }),
})

export const collections = { blog }

Islands

Island — ReactInteractive component.
---
// src/pages/index.astro
import Counter from '../components/Counter.tsx'
---
<main>
  <h1>Static HTML</h1>
  <!-- Client-side hydration -->
  <Counter client:load />
  <!-- On visible only -->
  <Counter client:visible />
  <!-- Idle -->
  <Counter client:idle />
  <!-- Media query -->
  <Counter client:media="(min-width: 768px)" />
</main>
View transitionsSPA-like navigation.
---
import { ViewTransitions } from 'astro:transitions'
---
<html>
  <head><ViewTransitions /></head>
  <body transition:animate="slide"><slot /></body>
</html>

Deployment

Build & deployStatic or SSR.
npm run build
# Output in /dist/

# For SSR:
// astro.config.mjs
import { defineConfig } from 'astro/config'
import node from '@astrojs/node'
export default defineConfig({
  output: 'server',
  adapter: node({ mode: 'standalone' }),
})