📋 Cheat Sheets

Astro Cheat Sheet — Components, Content Collections, and Routing


Click any item to expand the explanation and examples.

📝 Components

.astro component structure basics
---
// Frontmatter (runs at build time on the server)
const title = "Hello";
const items = await fetch("https://api.example.com/items").then(r => r.json());
---

<!-- Template (HTML output) -->
<h1>{title}</h1>
<ul>
  {items.map(item => <li>{item.name}</li>)}
</ul>

<style>
  /* Scoped to this component */
  h1 { color: blue; }
</style>
Props basics
---
// Card.astro
interface Props {
  title: string;
  url: string;
  description?: string;
}
const { title, url, description = "No description" } = Astro.props;
---

<a href={url}>
  <h3>{title}</h3>
  <p>{description}</p>
</a>

<!-- Usage -->
<Card title="My Post" url="/blog/my-post" />
Slots basics
---
// Layout.astro
const { title } = Astro.props;
---
<html>
  <head><title>{title}</title></head>
  <body>
    <header><slot name="header" /></header>
    <main><slot /></main>
    <footer><slot name="footer">Default footer</slot></footer>
  </body>
</html>

<!-- Usage -->
<Layout title="Home">
  <h1 slot="header">Welcome</h1>
  <p>Main content here</p>
</Layout>

📂 Routing

File-based routing routing
src/pages/
  index.astro          → /
  about.astro          → /about
  blog/index.astro     → /blog
  blog/[slug].astro    → /blog/my-post
  blog/[...slug].astro → /blog/2024/01/my-post (catch-all)
  404.astro            → Custom 404 page
Dynamic routes routing
---
// src/pages/blog/[slug].astro
import { getCollection } from 'astro:content';

export async function getStaticPaths() {
  const posts = await getCollection('blog');
  return posts.map(post => ({
    params: { slug: post.id },
    props: { post },
  }));
}

const { post } = Astro.props;
const { Content } = await post.render();
---

<h1>{post.data.title}</h1>
<Content />

📚 Content Collections

Define and query collections content
// src/content.config.ts
import { defineCollection, z } from 'astro:content';

const blog = defineCollection({
  schema: z.object({
    title: z.string(),
    pubDate: z.date(),
    tags: z.array(z.string()).optional(),
    draft: z.boolean().default(false),
  }),
});

export const collections = { blog };
---
// Query posts
import { getCollection } from 'astro:content';

const posts = await getCollection('blog',
  ({ data }) => !data.draft
);
const sorted = posts.sort((a, b) =>
  b.data.pubDate.valueOf() - a.data.pubDate.valueOf()
);
---

🏝️ Islands (Client-Side Interactivity)

client: directives islands
---
import Counter from './Counter.react';
import Search from './Search.svelte';
---

<!-- Load JS immediately -->
<Counter client:load />

<!-- Load JS when visible in viewport -->
<Search client:visible />

<!-- Load JS when browser is idle -->
<Counter client:idle />

<!-- Load JS on specific media query -->
<Sidebar client:media="(min-width: 768px)" />

<!-- No directive = zero JS (static HTML only) -->
<Counter />

⚙️ Config & CLI

astro.config.mjs and CLI config
// astro.config.mjs
import { defineConfig } from 'astro/config';
import react from '@astrojs/react';
import tailwind from '@astrojs/tailwind';
import sitemap from '@astrojs/sitemap';

export default defineConfig({
  site: 'https://example.com',
  integrations: [react(), tailwind(), sitemap()],
  output: 'static',  // or 'server' for SSR
});
npm create astro@latest          # New project
npx astro dev                    # Dev server
npx astro build                  # Production build
npx astro preview                # Preview build locally
npx astro add react              # Add integration

See also: What is Astro? | Tailwind CSS cheat sheet