Pages

How page collections work — frontmatter schema, layout assignment, and the catch-all page pattern.

Page Frontmatter

Every Markdown page starts with YAML frontmatter. The basePageSchema validates these fields:

content/pages/about.mdc
---
title: About Us
description: Our story and mission.
hero: true
image: /images/about-hero.jpg
links:
  - label: GitHub
    icon: i-simple-icons-github
    to: https://github.com/your-org
    target: _blank
---

Page content goes here...
FieldTypeDefaultDescription
titlestringrequiredPage title (used in <h1>, meta, OG)
descriptionstringMeta description and subtitle
labelstringShort label for navigation and badges
herobooleantrueShow hero section with title/description
imagestringHero or OG image path
excerptstringShort summary for listings
navigationbooleanInclude in navigation tree
layoutstringOverride layout (prefer route rules instead)
linksarrayAction links shown in hero/header

Layout Assignment

Layouts are assigned through route rules in nuxt.config.ts, not in frontmatter:

nuxt.config.ts
routeRules: {
  '/': { appLayout: 'landing' },
  '/about': { appLayout: 'default' },
  '/offers/**': { appLayout: 'article' },
  '/docs/**': { appLayout: 'docs' },
}

Available layouts:

LayoutPurpose
landingMinimal chrome, no hero — for landing pages with MDC sections
defaultStandard content page with optional hero
articleArticle format with back button, date, image
docsThree-panel layout with sidebar navigation and table of contents

See Layouts for details on each layout.

How Pages Render

Foundry uses a single catch-all page ([...slug].vue) that delegates rendering to layouts:

  1. A URL hits the catch-all page
  2. The route rule determines which layout to use
  3. The layout calls useContentPage().getPage() to fetch the content
  4. ContentRenderer renders the Markdown body
  5. MDC components (like ::section-hero) are resolved from your components/ directory

This means you never create .vue page files for content pages — you create Markdown files in content/pages/ and assign a layout via route rules.

Creating a New Page

  1. Create a Markdown file in content/pages/:
content/pages/pricing.mdc
---
title: Pricing
description: Simple, transparent pricing.
---

Your pricing content here.
  1. Add a route rule for the layout:
nuxt.config.ts
routeRules: {
  '/pricing': { appLayout: 'default' },
}
  1. The page is now live at /pricing.