Content Sources Interface

API reference for bringing a custom content via Stackbit's Content Source Interface.

Early Access Feature

Content Source Interface is in early access and subject to breaking changes. To be informed of changes, contact us.

Stackbit's Content Source Interface provides a two-way syncing mechanism between the content source(s) and Stackbit's visual editor.

While some modules are supported natively by Stackbit, you can use this API reference to bring your own content source to Stackbit.

Overview

The following diagram illustrates the high-level architecture of the Stackbit Content Source Interface.

CSI High Level Architecture
CSI High Level Architecture
  • The diagram assumes local development flow. When working with Stackbit cloud projects, the flow is almost identical.
  • The code in stackbit.config.js instantiates the content source modules implementing the CSI. A Stackbit project can use different content source modules or multiple instances of the same content source module instantiated with a different configuration.
  • The content sources fetch the content models and the content from the content sources and convert the data into the unified Stackbit format. Stackbit uses the converted data to present user interface controls to edit the content.
  • When a content editor makes a content change, Stackbit sends an update operation to the content source module that converts it into a content source specific request and updates the content source.
  • The stackbit.config.js and the content source modules are loaded and consumed exclusively by Stackbit. The web framework that renders the website never relies on stackbit.config.js or the content source modules. In other words, removing stackbit.config.js with the content sources modules will not affect the production site.

Usage

Bringing your own content source involves two steps:

  • Create a JavaScript class that implements the methods of the Content Source Interface.
  • Create and configure an instance of your content source class and add it to the contentSources array in stackbit.config.js.

Content Source Configuration

To allow Stackbit to interact with your content source, create and configure an instance of your CSI class and put it into the contentSources property in stackbit.config.js.

You can use environment variables to configure the instantiation parameters of your CSI class. When working with Stackbit cloud projects, you will define the values for your environment variables in Stackbit's project settings. You can also use hard-coded values for non-critical data.

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
import { MyContentSource } from 'package-or-file-path'

export default {
  contentSources: [
    new MyContentSource({
      projectId: 'my-project-id',
      apiKey: process.env.MY_SOURCE_API_KEY,
    }),
  ],
  // ...
}

Each item in the contentSources array is a class implementing the Content-Source-Interface, containing the necessary instance methods for interacting with the data and schema in the content source. See below for a full reference of these methods.

CSI Module Class

Your content source class should implement all the necessary instance methods defined in the CSI to enable Stackbit to interact with the content source.

The class's constructor should accept configuration options such as project ID, API keys, and other configuration options specific to your content source:

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
export class MyContentSource {
  constructor(options) {
    this.projectId = options.projectId
    this.apiKey = options.apiKey

    // other instance properties ...
  }

  // CSI methods ...
}

CSI Module Lifecycle

The diagram below shows the lifecycle of the content source class, when Stackbit calls its methods, and when the content source instance should call Stackbit callbacks:

CSI Module Lifecycle
CSI Module Lifecycle

Initialization

  1. Stackbit loads stackbit.config.js.
  2. The code within stackbit.config.js is executed, and the content source modules are imported and instantiated.
  3. Stackbit iterates over the contentSources array and, for each content source, calls the following methods:
    1. getContentSourceType()
    2. getProjectId()
    3. init(options)
    4. getModels()
    5. getLocales()
    6. getDocuments(options)
    7. getAssets()
    8. startWatchingContentUpdates(options) at this point, the content source should begin listening for content and schema changes in the underlying content source and call one of the received callbacks onContentChange and onSchemaChange when such changes occur.

User Edits the Content

  1. The User edits the content via Stackbit, and Stackbit calls one of the write methods.
  2. The content source module converts Stackbit write operation into content source specific API and calls the content source to update the content.
  3. The content source notifies the content source module, via server-events, polling, webhooks, or other syncing mechanisms, that the content was updated and available for consumption via its API.
  4. The content source module notifies Stackbit via the onContentChange callback that the content was updated, passing it the updated content.

Managing State

CSI modules should be stateless in regards to the content and its schema, except some metadata that doesn't change frequently.

Do not cache content and schema returned from the read operation methods. Stackbit will cache this data for you and provide you with methods to get this data when needed.

Using TypeScript

Using TypeScript in CSI modules benefits both you by ensuring that you implement all necessary methods. It also benefits developers that using the module by making it easier to discover required options when instantiating the class in their configuration file.

CSI Module References

The following sections contain references to methods necessary to implement a CSI module, broken down into topic. These references are concerned only with the instance methods necessary (and optional) to implement within the CSI module's class.