Posts

Posts are for a blog, news or notices: pages that carry a date and are listed newest first. A post is built from blocks like any other page. It also has a few facts of its own, which are its date, author, excerpt, cover image and tags. Every post is wrapped in a post template, so the title, byline and related posts look the same across the whole blog.

After this chapter you can write and publish a post, show posts on a page, change how every post looks and add a field of your own, such as a subtitle.

Write a post

  1. Open Content → Posts and press New post.
  2. Type a Title. The Slug follows it. A post lives under /blog by default, so the post “Spring news” becomes /blog/spring-news. Leave Template as it is unless you have made another one.
  3. Press Create. The editor opens with one paragraph to replace. Add blocks as you would on any page (Pages and blocks).
  4. Click an empty part of the preview, outside every block, to open the post's own fields on the right: Date, Author, Excerpt, Cover image and Tags. Type the date as YYYY-MM-DD and separate tags with commas. Fields marked with a star are required, and publishing checks them.
  5. Press Save draft, then Preview. Press Publish when it is ready.

A draft appears in no list until it is published. The same panel has the page fields for search results and who may open the post (Search engines). A post without its own description or image uses its excerpt and cover.

Show posts on a page

The Post list block, in the Posts group, shows the published posts as cards, newest first. The starter blog page has one.

  1. Open the page that should list posts, such as your blog page.
  2. Drag a Post list block onto it.
  3. Choose How many to show, the number of Columns and Columns on phones. To list only one subject, type a tag in Only posts tagged. Skip the newest leaves out the first few, which suits a “more posts” list under a featured one.
  4. Turn the details on or off with Show the cover, Show the date, Show the author, Show the excerpt and Show the tags.
  5. Save and publish the page.

A new post appears in the list as soon as it is published. If you want a card of your own design, use a List of… block with Posts as its Source instead, and build one card from blocks (Pages and blocks).

Change how every post looks

Each post is drawn inside a post template, which holds everything the posts share. The default has a Post hero with the title and facts, a Post info line with the date, author and tags, a Page content block where the post's own blocks go, and Related posts at the foot.

  1. Open Content → Templates and open Post.
  2. Edit it as you would a page. A picker at the top lets you preview it with any of your posts.
  3. Press Publish. Every post changes.

To give some posts a different frame, press New post template on the Templates tab, build it, and set a post's Template field to it. Post hero, Post info, Post field and Related posts belong in templates. Post list can go on any page.

Add a field of your own

A site can keep more than the five standard facts. A developer adds a field in site.config.ts. Posts is one entry in the features list, and its fields option takes a function that receives the standard fields and returns the list to use. List a new field after the defaults:

site.config.ts
features: [
  posts({
    fields: (defaults) => [
      ...defaults,
      { name: 'subtitle', type: 'text', label: 'Subtitle', required: false },
    ],
  }),
],

Restart the site. The field now appears in every post's own fields. A field's type is one of text, textarea, richtext, image, date, tags, select (with a list of options), boolean, number or url. Its name starts with a lowercase letter and uses letters, digits and underscores. It cannot be layout, template, title, description, ogImage or noindex.

To show the field, open the post template and add a Post field block. Under Field, pick it by its label. Label puts words before the value, such as “Reading time:”, and Hide when empty removes the block from posts that leave the field blank.

To make a standard field required, or optional, change it as you list the defaults. This example makes the author required:

site.config.ts
features: [
  posts({
    fields: (defaults) =>
      defaults.map((f) => (f.name === 'author' ? { ...f, required: true } : f)),
  }),
],

The date field, named publishedAt, must stay in the list.

Choose where posts live

Posts live under /blog unless the feature is given another path, such as posts({ path: '/news' }). Choose it before you write posts, because every post's address starts with it.

Add posts to a site that does not have them

Posts are an optional feature. A site that was made without them needs one extra package and one entry in its configuration. Install the package:

pnpm add @jamiemcconnell/cms-posts

Then import the feature and list it under features in site.config.ts, and restart the site. No migration is needed.

site.config.ts
import { posts } from '@jamiemcconnell/cms-posts';

// Inside defineConfig({ ... }):
features: [posts()],