Your First Site
This is a member-only chapter. Log in with your Signal Over Noise membership email to continue.
Log in to readModule 2: Your First Site
The best way to understand Astro is to create a project and look at what you get. This module walks you through the scaffold, explains the structure, and gets you to a working local preview. Claude Code will help from the start.
Scaffolding the Project
Open your terminal in the directory where you want the project to live, then run:
npm create astro@latest my-site
The installer asks a few questions:
- Template: Choose “Empty” — you don’t need the starter content, and a clean slate is easier to understand.
- TypeScript: Yes. It adds a small amount of upfront ceremony but catches errors before they become build failures.
- Install dependencies: Yes.
Once it’s done, move into the project directory:
cd my-site
npm run dev
Open your browser at http://localhost:4321. You’ll see a nearly blank page — that’s correct. An empty template is genuinely empty.
What You Just Created
Open the project in your editor. The structure looks like this:
my-site/
├── src/
│ ├── pages/
│ │ └── index.astro
│ └── env.d.ts
├── public/
├── astro.config.mjs
├── package.json
└── tsconfig.json
The only page is src/pages/index.astro. In Astro, the file system is the router — the path of the file under src/pages/ determines the URL. index.astro maps to /. Create src/pages/about.astro and you get /about automatically.
Your First Layout
Pages without layouts repeat the same HTML boilerplate (<html>, <head>, <body>) on every file. Layouts solve that. Create src/layouts/BaseLayout.astro:
---
interface Props {
title: string;
description?: string;
}
const { title, description = "My site" } = Astro.props;
---
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width" />
<meta name="description" content={description} />
<title>{title}</title>
</head>
<body>
<slot />
</body>
</html>
The --- fenced block at the top is the frontmatter — server-side JavaScript that runs at build time. The Astro.props object contains whatever the parent passes down. The <slot /> is where child content goes.
Now update src/pages/index.astro to use it:
---
import BaseLayout from '../layouts/BaseLayout.astro';
---
<BaseLayout title="Home">
<h1>Hello, world.</h1>
</BaseLayout>
Refresh the browser. The title in the browser tab should now say “Home”. You’ve got a layout working.
Adding a Component
Components in Astro work the same way as layouts — they’re .astro files with props. The difference is convention, not mechanism. Create src/components/Header.astro:
---
const { siteName } = Astro.props;
---
<header>
<a href="/">{siteName}</a>
<nav>
<a href="/about">About</a>
</nav>
</header>
Import and use it in your layout:
---
import Header from '../components/Header.astro';
---
...
<body>
<Header siteName="My Site" />
<slot />
</body>
Using Claude Code to Generate Boilerplate
This is where AI-assisted development earns its place. Once you have a working empty site, you can ask Claude Code to generate components rather than writing them from scratch.
Open Claude Code in your project directory (claude in the terminal). A useful starting prompt:
This is an Astro project. I need a nav component that:
- Shows a site name linking to /
- Has navigation links (Home, About, Blog)
- Highlights the active link based on the current page
- Uses CSS custom properties for colours (--color-text, --color-primary)
- Is responsive, collapsing to a hamburger on mobile
Read src/layouts/BaseLayout.astro first so the component fits the existing pattern.
The “read the existing file first” instruction matters. Without it, Claude Code generates plausible-looking components that don’t match your conventions. With it, it works within what you’ve already built.
Build and Preview
To see what the production build looks like:
npm run build
npm run preview
The build command generates static HTML into dist/. The preview command serves that directory locally. This is what your visitors will actually get — no development server, no hot reload, just the output.
Get in the habit of running a build before you deploy. Errors that the dev server tolerates will often fail at build time.
What Claude Code Needs to Work in Your Project
Before you write your first CLAUDE.md for this project, here are the facts Claude needs to know:
- The framework (Astro)
- The Node version and package manager (npm)
- The TypeScript setup
- Where pages, layouts, and components live
- The build and dev commands
- Any naming conventions you’ve established
We’ll build the proper CLAUDE.md in Module 6. For now, note down the decisions you’ve already made — they’ll all go in there.
You now have a running Astro site with a layout and a component. Module 3 covers making it look like something.
Check Your Understanding
Answer all questions correctly to complete this module.
1. How does Astro's routing work?
2. What is the purpose of <slot /> in an Astro layout?
3. Why does the chapter emphasise 'read the existing file first' when prompting Claude Code?
Pass the quiz above to unlock
Save failed. Please try again.