Stackbit + Contentlayer Tutorial

We can demonstrate how this works through a simple example. In this scenario, we have a Page model with a required title field.

The content lives in a content/pages directory, and we want to use each page's file path as the URL path to that page, which we'll store in a computed urlPath property on the compiled data (via the Contentlayer build process).

Let's assume:

  • The content is stored in markdown files in a content/pages directory. (Note that only files-source is supported by this approach.)
  • We're using Next.js as the site framework, which is the primary framework for which Contentlayer is optimized.

Setup

First, make sure the dependencies are installed in the project:

npm install contentlayer next-contentlayer @contentlayer/experimental-source-files-stackbit

Stackbit Configuration

In Stackbit, document type definitions are referred to as models and are defined using the models property.

A simple Stackbit config might look something like this:

// stackbit.config.ts

import type * as Stackbit from '@stackbit/sdk'

const stackbitConfig: Stackbit.RawConfig = {
  stackbitVersion: '~0.6.0',
  cmsName: 'git',
  ssgName: 'nextjs',
  nodeVersion: '16',
  dataDir: 'content/data',
  pagesDir: 'content/pages',
  models: {
    Page: {
      type: 'page',
      hideContent: true,
      urlPath: '/{slug}',
      fields: [
        {
          type: 'string',
          name: 'title',
          default: 'This is a new page',
          required: true,
        },
      ],
    },
  },
}

export default stackbitConfig

Note that best practice generally leads to breaking up each object in the models property into individual files, but are combined here for context.

Extend Models

In the Contentlayer configuration file, we can import the Stackbit config, and then add our computed urlPath property.

import { stackbitConfigToDocumentTypes } from '@contentlayer/experimental-source-files-stackbit'
import stackbitConfig from './stackbit.config.js'

const documentTypes = stackbitConfigToDocumentTypes(stackbitConfig, {
  documentTypes: {
    Page: {
      computedFields: {
        url: {
          type: 'string',
          resolve: (doc) => doc._raw.flattenedPath.replace(/^pages\/?/, '/'),
        },
      },
    },
  },
})

Notice that we didn't have to define the title field. We also didn't have to define properties like name or filePathPattern on the models, as they were already inferred by this function.

Configure the Source

At this point, we have everything we need to call makeSource and start using Contentlayer build output from Stackbit configuration.

import { makeSource } from '@contentlayer/source-files'
import { stackbitConfigToDocumentTypes } from '@contentlayer/experimental-source-files-stackbit'
import stackbitConfig from './stackbit.config.js'

const documentTypes = stackbitConfigToDocumentTypes(stackbitConfig, {
  // document type extensions ...
})

export default makeSource({ contentDirPath: 'content', documentTypes })

Now you can build files by running contentlayer build in your project!

We recommend using withContentlayer when using Next.js to run contentlayer dev in sync with next dev.


Was this article helpful to you?
Provide feedback

Last edited on May 24, 2023.
Edit this page