Tutorial: Pages, Components, and Layouts
Purpose and Scope
This tutorial page gives new Astro authors a practical path through the first three structural ideas they need before learning islands, integrations, or server rendering. A page is the file that produces a route, a component is a reusable unit of UI, and a layout is an Astro component used as a shared page template. The official tutorial introduces this stage by creating .astro pages, adding Markdown posts, styling a single page, and then applying global styles across pages. In this repository, the strongest concrete signal for that learning path is the basics development container, which opens a starter workspace directly at src/pages/index.astro and starts the local preview server for hands-on editing.
Sources: .devcontainer/basics/devcontainer.json
The goal is not to memorize every syntax feature at once. The goal is to learn how route files, reusable components, and shared document structure divide responsibility inside a small project. Start by making one visible change to a page, then extract repeated markup into a component, and only then introduce a layout to remove duplication across routes. This sequencing keeps each concept attached to a reader problem: pages answer where content appears, components answer how repeated UI is reused, and layouts answer how multiple pages share a consistent shell.
Sources: .devcontainer/basics/devcontainer.json, configs/tsconfig.build.json
Relevant Source Files
- .devcontainer/basics/devcontainer.json — Defines the Basics workspace used as the hands-on entry point, including the example folder, forwarded port
4321, post-create build command, dev server command, Astro editor extension, Prettier extension, and the first file to open:src/pages/index.astro. - configs/tsconfig.build.json — Shows the repository-wide package build convention: source files live under each package
srcdirectory, compiled output goes todist, and TypeScript build metadata is written to a non-published cache path. - packages/astro-prism/tsconfig.build.json — Demonstrates a package-specific build configuration that extends the shared build config while adding both
./srcand./virtual.d.ts, useful for understanding how Astro packages can add local inputs without redefining the shared build shape. - packages/astro-rss/tsconfig.build.json — Demonstrates the simplest package build shape by extending the shared build config directly, reinforcing the
srctodistconvention that appears across maintained Astro packages. - .changeset/sharp-bags-build.md — Records a build correctness fix for prerendered pages on Cloudflare, where render errors are buffered and surfaced as build failures instead of producing truncated HTML with a successful exit.
- packages/astro/src/assets/fonts/infra/build-font-file-id-generator.ts — Shows an internal build-time utility that generates deterministic font file IDs by resolving font content, hashing it, and appending the font type as the extension.
Core Primitives
An Astro page is written with the same component-oriented authoring model as other .astro files, but it has routing significance when placed in the project page tree. The tutorial evidence points the learner to src/pages/index.astro, which is the clearest first file because editing it changes the application entry page. In a beginner workflow, treat a page as the place for route-specific decisions: page title, content for that route, imports for components used only there, and any local styles that are easiest to understand beside the markup they affect.
Sources: .devcontainer/basics/devcontainer.json
A component is the next step once a page contains markup that another page will also need. Astro components can be imported into pages, can accept props, and can render shared HTML without requiring a client-side framework. In a tutorial project, useful first components are navigation links, a header, a footer, a card, or a repeated callout. Extracting these pieces teaches the reader that a page should not become a dumping ground for every visual detail. Pages stay route-focused, while components hold reusable presentation and behavior boundaries.
A layout is a component used by convention as a page template. The official layout documentation defines layouts as Astro components that provide reusable UI structure, often including a page shell with <html>, <head>, and <body> plus a <slot /> where page content is inserted. The important beginner insight is that layouts are not a separate runtime feature with a different mental model. They are ordinary Astro components used in a special role. That means they can accept props, import other components, include styles, and wrap Markdown, MDX, or Astro pages.
Learning Flow
Begin in the basics workspace. The development container sets workspaceFolder to /workspaces/astro/examples/basics, forwards port 4321, installs dependencies, builds the repository from /workspaces/astro, starts the server with pnpm start --host, and opens src/pages/index.astro. That setup is designed to shorten the distance between source code and rendered output. A learner should first change visible text in the opened page, confirm the browser preview updates, and connect the filesystem location to the rendered route.
Sources: .devcontainer/basics/devcontainer.json
After editing the first page, add a second page and intentionally duplicate a small piece of UI, such as navigation. The duplication is useful because it creates the reason to introduce components. Move the repeated markup into a component file, import that component from both pages, and pass any route-specific label or URL as props. This step teaches the difference between route ownership and UI ownership. A page chooses which content and components appear for a URL; a component owns reusable structure that multiple pages can share safely.
The third step is to create a layout once the project has multiple pages that need the same document structure. Put the shared shell in the layout and reserve the page files for unique route content. A typical layout includes metadata, global navigation, a footer, and a slot for page content. This is also the right moment to discuss styling scope. Keep styles local while exploring a single page or component, then move shared rules into a global stylesheet when they are clearly part of the site design rather than a one-off page experiment.
System-to-Code Mapping
The repository evidence maps this tutorial to two layers: a learner-facing example environment and the package build infrastructure that keeps Astro itself organized. The basics devcontainer represents the example environment. It names the starter, points VS Code and Codespaces at the first page file, and configures the preview port. The shared TypeScript build config represents the infrastructure layer. It sets each package root to src, output to dist, and stores build metadata under dist/._cache/ts_build/build.tsbuildinfo, which reinforces a clean separation between authored source and generated output.
Sources: .devcontainer/basics/devcontainer.json, configs/tsconfig.build.json
| Tutorial concept | What the reader does | Repository signal |
|---|---|---|
| Page | Edit src/pages/index.astro and observe a route update | The Basics devcontainer opens that file automatically |
| Component | Extract repeated UI and import it into pages | Astro packages follow predictable source organization under src |
| Layout | Wrap pages in a shared shell with a slot | Layouts are ordinary Astro components used as templates |
| Build feedback | Treat render errors as failures, not deployable output | The Cloudflare changeset documents surfacing prerender rendering errors |
| Asset output | Let the build pipeline produce deterministic files | The font file ID generator hashes resolved content and appends the font type |
Package-level configs make the build convention concrete. packages/astro-rss/tsconfig.build.json extends the shared build config without extra local options, so it inherits the standard source and output locations. packages/astro-prism/tsconfig.build.json also extends the shared config, but adds ./virtual.d.ts beside ./src, showing how a package can add a local type surface while still using the same build structure. For learners, this is background knowledge: Astro projects can be simple, but the repository maintains consistency by centralizing conventions and allowing narrow package-specific differences.
Sources: packages/astro-prism/tsconfig.build.json, packages/astro-rss/tsconfig.build.json, configs/tsconfig.build.json
Build and Feedback Signals
A beginner tutorial needs a fast feedback loop, but it also needs trustworthy failure behavior. The basics container provides the fast loop by forwarding the application port and starting the development server after setup. The Cloudflare changeset provides a correctness signal from the production side of the system: prerender errors thrown while pages render in workerd are now fully buffered before returning to the build process, so streaming errors are caught and reported as build failures. This matters because a broken page or layout should fail loudly instead of producing truncated HTML.
Sources: .devcontainer/basics/devcontainer.json, .changeset/sharp-bags-build.md
The internal font file ID generator is not something a beginner calls directly, but it illustrates how Astro treats build output. Its generate method receives an originalUrl and a font type, resolves the font content, hashes that content, and returns a filename made from the hash plus the extension. This is a useful mental model when a tutorial later introduces assets: authors should focus on meaningful page structure and component boundaries, while Astro build infrastructure turns referenced resources into stable, content-derived output.
Sources: packages/astro/src/assets/fonts/infra/build-font-file-id-generator.ts
Practice Sequence
Use this concrete sequence when teaching the first unit of an Astro project. First, open the Basics workspace and confirm the preview is available on port 4321. Second, edit src/pages/index.astro and make a visible text change. Third, add another page under the page tree and compare how the new file maps to a route. Fourth, copy a small repeated UI fragment into both pages, then extract it into a component. Fifth, create a layout that provides the page shell and place the route-specific content inside its slot.
1. Open the Basics workspace.
2. Start or attach to the dev server on port 4321.
3. Edit src/pages/index.astro.
4. Add a second page under src/pages.
5. Extract repeated markup into a component.
6. Wrap both pages with a layout that owns shared structure.After completing that loop, the reader should be able to explain which files own routes, which files own reusable UI, and which component acts as the shared page frame. The next step is to continue into the Astro API and islands tutorial, where interactivity is added deliberately after the static page structure is understood. For deeper reference, read the pages on Astro Components, Layouts, Astro Pages and Routing Basics, and Markdown or MDX content.