Every page in src/pages/ becomes a page on your website. See the existing page such as index.mdx for reference.
How page names become URLs
| File | Website address |
|---|---|
src/pages/index.mdx |
/ |
src/pages/about.mdx |
/about |
src/pages/services.mdx |
/services |
src/pages/team/alex.mdx |
/team/alex |
Use lowercase filenames with hyphens, such as work-with-me.mdx.
Create an MDX page
Use MDX when your page is mostly text, headings, lists, images, and a few components.
Create src/pages/services.mdx:
---
layout: ../layouts/PageLayout.astro
title: Services
description: Learn about the services I offer.
---
import Button from "../components/Button.astro";
# Services
I help people create simple and useful websites.
## Website design
Add a short description of your service here.
<Button href="/contact">Contact me</Button>
You can now visit /services.
The beginning part between the --- lines is called frontmatter:
layoutadds the shared header, footer, page styles, and page information.titleis the title shown in the browser and search results.descriptionis a short summary of the page.topSpacingis optional. Set it tofalsewhen the page’s first component provides its own top spacing.
Imports go below the frontmatter and before the component is used.
Create an Astro page
This template allows you to create all your pages using Markdown / .mdx.
If, for some reason, you do want to create pages using .astro files you can:
For a custom .astro page, wrap the content in BaseLayout and provide one main element with id="main-content" and tabindex="-1":
---
import BaseLayout from "../layouts/BaseLayout.astro";
---
<BaseLayout title="Services" description="Learn about the services I offer.">
<main
id="main-content"
tabindex="-1"
class="base-layout base-layout-content height-smart-fill-screen padding-top-xl padding-bottom-2xl"
>
<h1>Services</h1>
<p>I help people create simple and useful websites.</p>
</main>
</BaseLayout>The shared skip link targets #main-content. The negative tabindex lets the main element receive focus without adding it to the normal Tab order. MDX pages using PageLayout and blog posts using BlogPostLayout already receive this main element from their layouts; do not add another one.
Create a blog post
Regular pages go in src/pages/. Blog posts go in src/content/blog/.
Create a file such as src/content/blog/my-first-post.mdx:
---
title: My first post
description: A short introduction to my first blog post.
pubDate: 2026-08-01
---
## My first section
Write your post here.
The post will appear at /blog/my-first-post. Start blog post sections with ## because the blog layout already shows the post title as the main heading.
Keep blog post files directly inside src/content/blog/.
Blog posts also support two optional frontmatter fields:
updateDate: 2026-08-15
draft: true
updateDate records when the post was last changed and defaults to pubDate. Set draft to true to preview a post during development without including its page, listing entry, RSS entry, or social image in a production build.
Add page-specific head information
The shared layouts include a head slot for unusual page-specific tags:
<Fragment slot="head">
<meta name="category" content="events" />
</Fragment>Most pages do not need this. Use the existing title, description, canonical, social image, and robots options before adding tags by hand.
Before you publish
Check that:
- The filename creates the URL you want.
- The title and description explain the page clearly.
- The page has one main
#or<h1>heading. - Links do not end with a slash.
- The page is in the menu if visitors need it there.
- Images have useful alternative text.