Skip to content

Frontmatter

By default Colophon reads a meta_img_props object from a post’s frontmatter, takes the template name from a template field within it, and reads the post slug from a top-level slug.

---
title: My post
slug: my-post
meta_img_props:
template: banner
title: "@kensio/colophon"
subtitle: Generate social meta images from frontmatter
version: 1.2.0
---

Fields other than the template name are passed through to the template, so what a props block may contain depends on which template reads it. See Templates.

A props block that sets no title gets the post’s own top-level one, so an image titled after its post needs nothing said twice:

---
title: Setting up continuous integration
meta_img_props:
template: banner
---

That image is titled Setting up continuous integration. A title inside the props block is used ahead of it, and so is one from a props mapper.

The fallback fills in a title for a post that is having an image drawn. It does not ask for one: a file with no props block and no mapper is skipped as before, whatever its title says. Templates that need no title, such as code, still render without one where the post has none either.

Every part of that is configurable under content:

Option Default What it names
propsKey meta_img_props The frontmatter key holding the props object.
templateField template The field within it naming the template.
defaultTemplate none Template to use when that field is absent.
slugField slug Top-level field to read the slug from.
slugStrategy basename How to derive a slug when there is none.
extensions .md and .markdown Which files in the tree are content.
props none Build props from a post’s existing frontmatter.

slugStrategy is covered in Output sizes and filenames.

content lives in the config module rather than being a CLI flag because props is a function. generate’s walk option is the programmatic equivalent and takes precedence where both are given.

Posts usually carry the fields an image needs already, under names of their own. props maps them, so a site can render images from the frontmatter it has rather than adding a props block to every file:

export default defineConfig({
content: {
defaultTemplate: "banner",
props: (frontmatter) =>
frontmatter.draft === true
? undefined
: { subtitle: frontmatter.description },
},
});

A site set up this way gets its images without any post being edited. The title needs no mapping, since a post’s own is used where nothing else sets one.

That is the filter for drafts, section indexes and anything else in the tree that is not a page worth sharing. Without it, mapping frontmatter means an image for every markdown file there is.

An explicit props block still wins, field by field

Section titled “An explicit props block still wins, field by field”

A post that wants a different subtitle writes just that:

---
title: Colophon 2.3.0
description: Autogenerated release notes
meta_img_props:
subtitle: Per-size config, frontmatter mapping
---

The title still comes from the mapper, and only the subtitle is overridden.

A post declaring a block is never skipped, even where the mapper would have skipped it. Asking for an image outright is the stronger signal.

A slug in frontmatter wins over whatever the slug strategy would have derived from the path, which is usually what you want for an SEO-friendly filename.

It has to stay inside the content tree. A derived slug cannot be absolute or contain . or .. segments by construction, as it comes from a relative path. A hand-written frontmatter slug is validated and rejected if it is absolute or contains . or .. segments. Slugs are resolved from the content root, so it takes fewer .. segments to leave the tree than you might expect.