Reader API

The Reader API is a Node.js API that lets you read Keystatic content from your file system.


The code can only run on the server, and not in the browser.


First, import the createReader function, as well as your Keystatic config file:

import { createReader } from '@keystatic/core/reader';
import keystaticConfig from '../../keystatic.config';

You can then create a new reader by calling createReader and passing it two arguments:

  1. Path to the root of your repository
  2. The Keystatic config

Here's an example:

const reader = createReader(process.cwd(), keystaticConfig);

The reader will now give you access to the following async functions:

For collections

You can get an array of slugs for a given collection with:

const slugs = await reader.collections.{collectionName}.list();

// Example
const slugs = await reader.collections.posts.list();

You can get the data for a specific collection entry with:

const entry = await reader.collections.{collectionName}.read(slug);

// Example
const post = await;

You can get an array of objects containing both slug and entry data for a collection with:

const entries = await reader.collections.{collectionName}.all();

// Example
const posts = await;

Filtering based on a field's value

A common use case is to filter the entries based on a field's value before rendering them in the UI. You can use Keystatic's reader functions along with standard JS array methods like .filter() and .sort() to achieve this pattern.

Let's say you're building a list page for blog posts, and you only want to display published posts. The collection schema for each entry defines a draft checkbox field, indicating a not-to-be-published post:

// keystatic.config.ts
blog: collection({
  // ...
  schema: {
    // ...
    draft: fields.checkbox({
      label: 'Convert to draft',
      description: 'Prevent publishing of this post. This can be changed later.',
      defaultValue: false,

Then before rendering the data, you can read and filter the entries to only render published posts (draft === false) like so:

// blog.ts
const posts = await;
const publishedPosts = posts.filter(post => !post.entry.draft);

For singletons

You can get the data for a specific singleton with:

const data = await reader.singletons.{singletonName}.read();

// Example
const navigation = await;

Remember: this code cannot run in the browser, as it's using some Node.js APIs.

Good places to use the Reader API are:

  • getStaticProps in Next.js (Pages Router)
  • The frontmatter in Astro files
  • The loader() function in Remix
  • ReactServer Components

The Document field's structured data

If you retrieve content from a document field in Keystatic, you will get a JSON object with structured data.

It can be a lot of work to turn this data object as HTML to render it on a page.

Luckily, Keystatic also provides a DocumentRenderer that does all the heavy lifting for you, and is highly customisable.

Type signature

Find the latest version of the Reader type signature at: