Pages as Structured Data

Pages are built by defining a content model in the frontmatter. Each page specifies its layout template and an array of section components. The layout template orchestrates these sections while individual component files handle specific rendering logic.

This page demonstrates the component-based approach:

layout: pages/sections.njk
bodyClasses: 'sections-page'
hasHero: true

navigation:
  navLabel: 'Home'
  navIndex: 0

seo:
  title: Metalsmith Components
  description: 'A collection of section components for use with Metalsmith'
  socialImage: '/assets/images/sample2.jpg'
  canonicalURL: ''

sections:
  - sectionType: hero
    # hero configuration
  - sectionType: text-only
    # text-only configuration
  - sectionType: media-image
    # media-image configuration

Configuration Properties:

  • layout determines the template file for page rendering
  • bodyClasses adds CSS classes to the body element
  • navigation defines menu label and position
  • seo contains metadata for search engine optimization
  • sections array defines the sequence of components to render

Composable Sections

Components are built from smaller, reusable partials. The media-image section demonstrates this composition pattern by combining text, call-to-action buttons, and image partials.

Media Section Configuration

- sectionType: media-image
  containerTag: aside
  classes: ''
  id: ''
  isDisabled: false
  isReverse: false
  containerFields:
    inContainer: true
    isAnimated: true
    noMargin:
      top: false
      bottom: true
    noPadding:
      top: true
      bottom: true
    background:
      color: ''
      image: ''
      imageScreen: 'none'
  text:
    leadIn: 'And what is this?'
    title: Media Section Example
    titleTag: 'h2'
    isCentered: true
    subTitle: ''
    prose: Example of a media section with text and image. Change positions by setting the 'isReverse' property.
  ctas:
    - url: 'https://metalsmith.io'
      label: 'Metalsmith Central'
      isButton: true
      buttonStyle: 'primary'
    - url: 'https://example.com'
      label: 'Read more'
      isButton: false
      buttonStyle: 'primary'
  image:
    src: '/assets/images/sample7.jpg'
    alt: 'Component example'
    caption: 'Media section demonstration'

Component Properties

The media section combines three primary elements:

Text Component:

  • leadIn: Introductory text above the title
  • title: Main heading text
  • titleTag: HTML heading level (h1-h6)
  • isCentered: Centers title over default columns
  • subTitle: Secondary heading text
  • prose: Body content supporting markdown formatting

CTA Component:

  • url: Link destination
  • label: Display text
  • isButton: Boolean for button vs text link styling
  • buttonStyle: Visual style variant

Image Component:

  • src: Image file path
  • alt: Alternative text for accessibility
  • caption: Optional descriptive text
{% from "components/_partials/ctas/ctas.njk" import ctas %}
{% from "components/_partials/text/text.njk" import text %}
{% from "components/_partials/image/image.njk" import image %}

<div class="media-image content {% if section.isReverse %}is-reverse{% endif %}">
  {% if section.image %}
    <div class="image">{{ image(section.image)}}</div>
  {% endif %}

  {% if section.text and section.ctas | length > 0 %}
    <div class="text flow">
      {% if section.text %}
        <div class="prose flow">{{ text(section.text)}}</div>
      {% endif %}
      {% if section.ctas | length > 0 %}
        {{ ctas(section.ctas) }}
      {% endif %}
    </div>
  {% endif %}
</div>

Benefits of Component-Based Architecture

The component-based approach provides significant advantages over traditional monolithic templates. Each component exists as an independent unit with its own template and configuration schema, enabling development, testing, and maintenance in isolation. This modularity creates a foundation for systematic page construction.

Components work across different page types and layouts without modification. A hero section defined once can appear on homepages, landing pages, or blog posts without duplication. This reusability eliminates redundant code and ensures consistency across the site. When component logic needs updating, changes happen in one location and propagate automatically. Updating the CTA button styling, for example, affects all instances across the site without hunting through multiple template files.

Page restructuring becomes straightforward through frontmatter configuration. Reordering sections or trying different layouts requires no template modifications—simply adjust the sections array in the frontmatter. This flexibility extends to content management where the separation between content structure and presentation logic allows content editors to work with data while developers focus on component implementation. The frontmatter defines what appears on the page while templates determine how it renders.