Astro Pages and Routing Basics

Purpose and Scope

Astro pages are the files that define the public URLs of a site. In normal project code, the most important directory for this workflow is src/pages/: a file placed there becomes a route, and its file name and folder position determine the URL that visitors can request. This page explains that authoring model, how static and dynamic route organization should be understood, and how the repository’s starter and build signals reinforce the workflow a developer experiences while editing a basic Astro app.

The official routing model is intentionally simple: .astro, Markdown, MDX, HTML, and endpoint files can live in src/pages/, and Astro turns that file tree into pages or API endpoints. A route such as src/pages/index.astro maps to the site root, while src/pages/about.astro and src/pages/about/index.astro both represent an /about page shape. Dynamic route files use bracketed parameters, such as [slug].astro, and static builds require the project to enumerate generated paths with getStaticPaths().

Sources: .devcontainer/basics/devcontainer.json

Relevant Source Files

  • .devcontainer/basics/devcontainer.json — Defines the Basics development container around examples/basics, forwards Astro’s default port 4321, opens src/pages/index.astro, and starts the dev server with pnpm start --host.
  • .changeset/sharp-bags-build.md — Records a rendering failure fix for prerendered pages in the Cloudflare workerd build path, showing why page render errors must surface during astro build.
  • configs/tsconfig.build.json — Provides the shared package build TypeScript shape: source files under src, emitted output under dist, and incremental build metadata in dist/._cache.
  • packages/astro-prism/tsconfig.build.json — Shows an Astro package extending the shared build config while adding virtual.d.ts, a pattern relevant to packages that participate in page rendering capabilities such as syntax highlighting.
  • packages/astro-rss/tsconfig.build.json — Shows another package extending the shared build configuration for a feature commonly exposed through route-like feed endpoints.
  • packages/astro/src/assets/fonts/infra/build-font-file-id-generator.ts — Implements build-time font file ID generation from resolved font content and file type, illustrating how page output can depend on deterministic asset identifiers.

File-Based Routing Model

File-based routing means that authors do not manually register most routes in a central router table. Instead, they create files in the src/pages/ tree and let Astro derive route URLs from that layout. This makes the project structure itself a navigation map: top-level files become top-level pages, nested folders become nested URL segments, and index files represent their containing directory. The model is especially useful for content-heavy sites because adding a page is usually the same operation as adding a file.

Astro’s page files are also responsible for page-level data loading and overall layout composition. A .astro page can contain frontmatter for loading data, imports for layouts and components, and markup for the full document. The official docs emphasize that standard HTML anchor tags are used for navigation rather than a framework-specific link component. That means route organization is visible not only in the filesystem but also in ordinary root-relative links such as /about/ or /authors/sonali/.

Dynamic routes extend the same model when one file needs to produce many URLs. A filename segment like [author].astro declares a route parameter, and in static output mode the page must define the list of parameter values ahead of time. In server-rendered mode, matching pages can be generated on request. For a developer designing a blog, documentation site, or CMS-backed site, the decision is therefore not whether Astro can represent the route, but when the route list is known and which data source supplies it.

Working in the Basics Starter

The repository’s Basics dev container is a concrete signal for the intended first editing experience. Its workspace is /workspaces/astro/examples/basics, it forwards port 4321, and it opens src/pages/index.astro in Codespaces. That combination points new contributors directly at the canonical first page file, then starts an Astro server so route changes can be previewed immediately. The container also installs dependencies and builds the repository before attaching, so the starter is exercised in the same monorepo context as the packages it depends on.

Sources: .devcontainer/basics/devcontainer.json

A practical starter workflow is therefore: open the project, edit src/pages/index.astro, create a sibling route such as src/pages/about.astro, and navigate to /about/ in the forwarded preview. If you need a nested section, create a folder such as src/pages/docs/index.astro for /docs/ and src/pages/docs/install.astro for /docs/install. If you need repeated pages, introduce a dynamic file such as src/pages/blog/[slug].astro and decide whether the slug list comes from local Markdown, a content collection, or an external CMS.

This flow is deliberately close to normal web authoring. Links are ordinary HTML, pages can use layouts to avoid repeating document structure, and Markdown or MDX files can become pages when content is the primary concern. That is why routing basics should be learned alongside project structure: routes are not an isolated API surface, but an authoring convention that connects files, content, layouts, components, and build output.

Rendering and Build Signals

Route organization matters because every page eventually becomes either built output or server-rendered response behavior. The changeset for Cloudflare notes a fix where prerender errors could be silently swallowed when pages threw during rendering in workerd, causing astro build to exit successfully while producing truncated HTML. The fix buffers the response body inside workerd before sending it back to the build process, so streaming errors are caught and reported as build failures with clearer messages.

Sources: .changeset/sharp-bags-build.md

For page authors, the important lesson is that page rendering is not just a local preview concern. A page can import components, load data, render assets, and stream HTML through an adapter-specific environment. If an error happens during prerendering, the build must fail rather than publishing incomplete output. When validating route changes, especially dynamic routes or pages that fetch external data, run a production build in addition to the dev server so routing and rendering assumptions are tested under output conditions.

The shared TypeScript build configuration reinforces that Astro packages are built from src into dist, with package-specific extensions when needed. @astrojs/rss inherits the shared build settings, and astro-prism adds virtual.d.ts to its build input. Those packages are not page files themselves, but they represent capabilities often used by pages: feeds can be exposed as route-like outputs, and syntax highlighting can shape rendered content. The routing surface stays file-based while supporting packages provide behavior used during render.

Sources: configs/tsconfig.build.json, packages/astro-prism/tsconfig.build.json, packages/astro-rss/tsconfig.build.json

System-to-Code Mapping

Routing concernDeveloper-facing behaviorSource-backed signal
First page editingStart from src/pages/index.astro in a basic project and preview on port 4321..devcontainer/basics/devcontainer.json
Static or prerendered outputPage render failures must fail the build rather than emitting truncated HTML..changeset/sharp-bags-build.md
Supporting package buildsPackages compile from src to dist using the shared TypeScript build contract.configs/tsconfig.build.json
Route-adjacent content featuresRSS and Prism packages build as part of Astro’s package ecosystem.packages/astro-rss/tsconfig.build.json, packages/astro-prism/tsconfig.build.json
Asset identity during page buildsFont file IDs are generated from resolved content and font type.packages/astro/src/assets/fonts/infra/build-font-file-id-generator.ts

The font file ID generator is a small but useful example of build-time determinism around page output. It receives an original URL and font type, resolves the referenced font content, hashes that content, and returns a file identifier with the font type extension. A page author usually experiences this indirectly: pages reference fonts or components that reference fonts, and the build pipeline needs stable file names derived from content rather than arbitrary state.

Sources: packages/astro/src/assets/fonts/infra/build-font-file-id-generator.ts

Practical Next Steps

When designing routes, start with the URL map your site needs, then create the matching src/pages/ tree. Use index.astro for section landing pages, nested folders for nested URLs, Markdown or MDX when the page is primarily content, and bracketed filenames for dynamic segments. Keep links root-relative so they describe deployed URLs, not local filesystem relationships. As routes become more complex, move repeated shell markup into layouts and keep page frontmatter focused on data loading and route-specific decisions.

Before shipping, test the same route set in development and production modes. The dev server is best for fast feedback while editing src/pages/index.astro or adding new pages, but astro build is what validates static output, prerendered routes, adapter behavior, and build-time assets. Continue with the broader Routing page for redirects, rest parameters, and endpoint behavior; read Layouts next if pages are repeating document structure; and read Content Collections if dynamic routes are generated from structured content.