Path configuration

You can define where Keystatic should store collection entries and singletons via the path property in the collection/singleton top-level options.

// Keystatic config
export default config({
  collections: {
    posts: collection({
      label: 'Posts',
      path: 'content/posts/*/',
      // ...
    })
  },
  singletons: {
    settings: singleton({
      label: 'Settings',
      path: 'content/posts/',
      // ...
   })
  }
})

The optional trailing slash / on that path has an impact on the content structure - read below for more details on collection paths and singleton paths.

Path wildcard for collections

The path property for collections must contain a * wildcard.

It represents the slug of an entry.

This wildcard gives you flexibility and control over your where your content is being output.

Nested folder output example

šŸ‘‰

path: 'packages/design-system/*/docs/'

Imagine a Design System inside a monorepo:

root
ā”œā”€ā”€ packages
  ā”œā”€ā”€ design-system
    ā”œā”€ā”€ button
      ā””ā”€ā”€ src
    ā”œā”€ā”€ dropdown
      ā””ā”€ā”€ src
ā””ā”€ā”€ apps
  ā””ā”€ā”€ docs(keystatic)

Your Keystatic site lives in apps/docs, but you want your documentation entries in packages/design-system/{component-name}/docs/, to collocate them with each component.

The following path will let you do exactly that:

path: 'packages/design-system/*/docs/'

Nested slug example

šŸ‘‰

path: 'content/posts/**'

There may be situations where you need the slug of an entry to be following a multi-folder structure.

Say you want the same collection to support this following tree structure:

content
ā”œā”€ā”€ posts
  ā”œā”€ā”€ en  
      ā””ā”€ā”€ post-1.mdoc
  ā”œā”€ā”€ fr  
      ā””ā”€ā”€ post-1.mdoc

You can enable this by using the ** wildcard in your path:

path: 'content/posts/**'

Since Keystatic slugs can contain / characters, you construct a multi-folder structure with slug field values like: en/post-1 and fr/post-1.