Skip to content

Blog Post

Every blog post in Astro Docus lives as a Markdown file inside src/pages/blog/. This is different from documentation pages, which live in src/content/docs/. Blog posts use the same Markdown format but are rendered with a dedicated blog layout.

This page explains the frontmatter fields used by blog posts, how to create a new post, and how the layout and metadata work together.


src/pages/
└── blog/
├── artcilepage-astro.md
├── blog-detail.md
├── contactform-astro-js.md
└── ...

Each .md file in src/pages/blog/ becomes a blog post at /blog/<filename>/. For example, contactform-astro-js.md renders at /blog/contactform-astro-js/.

Note: The filename becomes the URL slug. Keep names short, lowercase, and hyphenated.


A blog post frontmatter looks like this:

---
layout: ../../design/blog/blogpost.astro
title: "Contact Form Astro JS Themes"
description: "With Blacks you can handle customer messages directly in your email"
image: https://blogger.googleusercontent.com/img/b/R29vZ2xl/...
pubDate: 2023-12-10
tags: ["astro", "contact form", "astro template", "astro themes"]
categories: ["contact"]
---
FieldTypeRequiredPurpose
layoutstringYesPath to the blog post layout component
titlestringYesPost title — shown on the post page and in listings
descriptionstringYesMeta description and summary text
imagestringNoCover image for the post (URL or local path)
pubDatedateYesPublication date — used for sorting
tagsarrayNoList of tags for tag archive pages
categoriesarrayNoList of categories for category archive pages

The layout field points to the Astro component that wraps your post content:

layout: ../../design/blog/blogpost.astro

This layout provides the blog post shell — header, metadata display, and styling. Because the post lives in src/pages/blog/, the path is ../../design/blog/blogpost.astro (two levels up, then into design/blog/).

The visible title of the post. It appears:

  • As the main heading on the post page
  • In the blog listing
  • In the browser tab
  • In social media previews

Wrap it in quotes if it contains special characters:

title: "Contact Form Astro JS Themes"

A short summary of the post. Used for:

  • SEO meta description
  • Social media preview text
  • Blog listing excerpt

Keep it under 160 characters for best search results.

The cover image for the post. Can be:

  • A full external URL (https://...)
  • A local path inside public/ (/images/my-cover.png)
  • A local path inside src/assets/ (/src/assets/my-cover.png)

If you use an image from src/assets/, Astro can optimize it. External URLs are loaded as-is.

The publication date. Used to:

  • Sort posts in the blog listing (newest first)
  • Display the date on the post page
  • Generate the RSS feed

Format: YYYY-MM-DD.

pubDate: 2023-12-10

An array of tags for the post. Each tag creates an entry in the tag archive system.

tags: ["astro", "contact form", "astro template", "astro themes"]

Tags appear on the post page as clickable links. Clicking a tag opens /tags/<tag>/, which lists all posts with that tag.

Rules for tags:

  • Use lowercase
  • One word or short phrases
  • No duplicates within the same post
  • Consistent naming across posts (use contact form, not contact-form in one post and contactform in another)

An array of categories. Categories are broader than tags — use them for high-level grouping.

categories: ["contact"]

Each category creates an entry in the category archive system at /categories/<category>/.

Tags vs Categories:

TagsCategories
Specific, many per postBroad, few per post
astro, contact form, templatecontact, tutorial
Used for discoveryUsed for grouping

  1. Open src/pages/blog/ in VS Code.
  2. Right-click → New File.
  3. Name it with .md: my-new-post.md.

Copy this template and adjust:

---
layout: ../../design/blog/blogpost.astro
title: "My New Post"
description: "A short summary of what this post covers."
image: /src/assets/astrojs.svg
pubDate: 2025-01-15
tags: ["astro", "tutorial"]
categories: ["guides"]
---

Below the frontmatter, write your post content in Markdown:

## Introduction
This is my new blog post. It covers an interesting topic.
## Main Section
Here is the main content.
- Point one
- Point two
## Conclusion
Thanks for reading.
  1. Run npm run dev if it’s not already running.
  2. Open http://localhost:4321/blog/my-new-post/.
  3. The post renders with the blog layout.

The post also appears automatically in the blog listing at /blog/.


  1. Open the .md file in src/pages/blog/.
  2. Change the frontmatter or body.
  3. Save.

The dev server reloads automatically. Changes to title or description update the post page and listing immediately.


  1. Right-click the .md file.
  2. Click Delete.
  3. Confirm.

The post URL stops working. The post is removed from the listing.

Reminder: If the post is referenced from elsewhere (a link in another post, an external site), those links will break.


Posts are sorted by pubDate in descending order — newest first. The blog listing reads all posts and sorts them at build time.

This means:

  • A post with a future date appears above older posts
  • Reordering posts means changing their pubDate
  • The RSS feed uses the same order

When you add tags and categories to a post, the post automatically appears in:

ArchiveExample URL
Tag page/tags/astro/
Category page/categories/contact/

No additional configuration needed. The tag and category pages are generated dynamically from all posts.

Tip: Keep a consistent vocabulary. If you use contact form as a tag, use the same spelling in every post. Inconsistent tags create duplicate archives.


Blog posts support full Markdown syntax:

  • Headings (##, ###)
  • Bold and italic
  • Lists (ordered and unordered)
  • Links [text](url)
  • Images ![alt](path)
  • Code blocks
  • Blockquotes
  • Tables

For interactive components, rename the file to .mdx and import Astro components.


MistakeResultFix
Missing layoutPost renders without stylingAdd layout: ../../design/blog/blogpost.astro
Wrong path to layoutBuild errorCheck ../../design/blog/blogpost.astro
Missing pubDatePost may not sort correctlyAdd pubDate: YYYY-MM-DD
Inconsistent tag spellingDuplicate tag archivesUse the same spelling everywhere
Filename with spacesURL breaksUse hyphens instead
Missing quotes around title with special charsYAML parse errorWrap in "double quotes"

src/pages/blog/my-post.md → /blog/my-post/
Frontmatter:
├── layout: ../../design/blog/blogpost.astro
├── title: "Post Title"
├── description: "Short summary"
├── image: /src/assets/cover.png
├── pubDate: 2025-01-15
├── tags: ["astro", "tutorial"]
└── categories: ["guides"]
Body: standard Markdown
  • One file = one post. Filename becomes the URL.
  • layout is required — it provides the blog post shell.
  • pubDate controls order — newest first.
  • Tags and categories generate archive pages automatically.
  • No sidebar entry needed — blog posts appear in the listing.