We use cookies to understand how the site is used and to display ads. Analytics and advertising only run after you accept. You can change your choice anytime. Privacy policy

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 project· Scaffold Astro site.
npm create astro@latest my-site -- --template basics
cd my-site
npm run dev
Add a framework· Add React/Vue/Svelte.
npx astro add react
npx astro add vue
npx astro add svelte

Pages & Routing

Page route· Astro 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 route· SSG 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 collection· Type-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: React· Interactive 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 transitions· SPA-like navigation.
---
import { ViewTransitions } from 'astro:transitions'
---
<html>
  <head><ViewTransitions /></head>
  <body transition:animate="slide"><slot /></body>
</html>

Deployment

Build & deploy· Static 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' }),
})