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.

Usage

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);

Reading from 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 reader.collections.post.read(slug);

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 reader.collections.blog.all();

Reading from singletons

You can get the data for a specific singleton with:

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

// Example
const navigation = await reader.singletons.navigation.read();

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

Data from linked files

If your collection or singleton contains a document field, that field will be returned as an asynchronous function that you'll need to call to get the data:

// The `posts` collection has a `document` field named `content`
const post = await reader.collections.posts.read(slug);

// Get the content data
const content = await post.content()

If you'd rather get the document field data immediately, you can pass resolvedLinkedFiles: true as an option when reading the entry:

await reader.collections.posts.read(slug, { resolvedLinkedFiles: true });

Using TypeScript

The Reader API exports an Entry type, which is useful when you need to define what props a UI component should receive:

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

type MovieProps = Entry<typeof keystaticConfig['collections']['movies']>

export function Movie(props: MovieProps) {
  // ...
}

If your data was read using the resolvedLinkedFiles option, you can use the EntryWithResolvedLinkedFiles type instead:

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

type MovieProps = EntryWithResolvedLinkedFiles<typeof keystaticConfig['collections']['movies']>

Rendering content from the document field

The document field returns a JSON object with complex 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: https://docsmill.dev/npm/@keystatic/core@latest#/.reader.Reader