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 src directory, compiled output goes to dist, 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 ./src and ./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 src to dist convention 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 conceptWhat the reader doesRepository signal
PageEdit src/pages/index.astro and observe a route updateThe Basics devcontainer opens that file automatically
ComponentExtract repeated UI and import it into pagesAstro packages follow predictable source organization under src
LayoutWrap pages in a shared shell with a slotLayouts are ordinary Astro components used as templates
Build feedbackTreat render errors as failures, not deployable outputThe Cloudflare changeset documents surfacing prerender rendering errors
Asset outputLet the build pipeline produce deterministic filesThe 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.