init

The init method is responsible for initializing the content source instance.

This is a good place to create and initialize API clients using the options provided to the constructor, which can be utilized throughout the content source instance's lifespan.

If your content source module uses webhooks to monitor content changes, you can create them within this method.

InitOptions

The init methods is called with a single options object of the InitOptions type. You can use the InitOptions type included in the @stackbit/types to introspect its properties. This type uses the generic types defined on your content source and includes the following properties.

logger: Logger

A logger object used to log messages to the terminal console. Any messages logged with this object will appear in the console when running stackbit dev.

Use this logger to debug the content source when working with it locally. To change the logging level use the --log-level argument:

  • 1
stackbit dev --log-level debug

userLogger: Logger

A logger object used to log messages to the "log" panel in the Netlify Create client application.

You can use this logger to display important messages to the user working with the Netlify Create UI.

localDev: boolean

A boolean flag indicating if the content source is running in local development mode using the stackbit dev command (true), or if it is running in a Netlify Create cloud project (false).

webhookUrl: string

A string representing a Netlify Create webhook URL that the content source module may use to create webhooks between the content source and Netlify Create.

The webhooks only need to be created once. You may use predefined webhook names to verify whether the webhook with the same name has been already created. Alternatively, you can utilize the webhookUrl to check whether a webhook with the same URL exists.

When localDev is set to true, this parameter remains empty. To debug webhooks locally, you will need to generate a public URL that forwards external webhooks to stackbit dev's internal port: localhost:8090.

You may use a tool like ngrok to create a public URL that forwards webhooks to your local stackbit dev instance by executing the following command

  • 1
ngrok http 8090

Ngrok will print the public https URL it created (e.g. https://xyz.ngrok.app).

Set this URL to the --csi-webhook-url argument when running stackbit dev:

  • 1
stackbit dev --csi-webhook-url=https://xyz.ngrok.io/_stackbit/onWebhook

Netlify Create will append additional path segments to the URL you provide to identify the content source and pass it to the init method. Afterward, you may use the webhookUrl to call your content source APIs and create a webhook.

cache: Cache

The Cache object provides methods to interact with Netlify Create's internal cache.

Logger

  • createLogger(options: { label: string }): Logger: creates a new logger with a label that will be used to prefix log messages: [{label}] {message}.
  • error(message: string, ...meta: any[]): logs an error level message.
  • warn(message: string, ...meta: any[]): logs a warning level message.
  • info(message: string, ...meta: any[]): logs an info level message.
  • debug(message: string, ...meta: any[]): logs a debug level message.

Example

Initializing a content source with an API client using options passed to the constructor and creating a webhook if one has not already been created.

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
import { MyAPIClient, MyAPIUser } from 'MyContentSource'
import type {
  ContentSourceInterface,
  InitOptions,
  Logger,
  Cache,
} from '@stackbit/types'

// the options passed to the content source contstructor
export interface ContentSourceOptions {
  projectId: string
  apiKey: string
}

// define the generic types for your content source
interface UserContext {
  /* ... */
}
interface SchemaContext {
  /* ... */
}
interface DocumentContext {
  /* ... */
}
interface AssetContext {
  /* ... */
}

export class MyContentSource
  implements
    ContentSourceInterface<
      UserContext,
      SchemaContext,
      DocumentContext,
      AssetContext
    >
{
  private readonly projectId: string
  private readonly apiKey: string
  private logger: Logger
  private userLogger: Logger
  private cache: Cache
  private apiClient: MyAPIClient
  private users: MyAPIUser

  constructor(options: ContentSourceOptions) {
    this.projectId = options.projectId
    this.apiKey = options.apiKey
  }

  async init({
    logger,
    userLogger,
    localDev,
    webhookUrl,
    cache,
  }: InitOptions<SchemaContext, DocumentContext, AssetContext>): Promise<void> {
    this.logger = logger.createLogger({ label: 'my-content-source' })
    this.userLogger = userLogger.createLogger({ label: 'my-content-source' })
    this.cache = cache

    // Initialize the API client
    this.apiClient = new MyAPIClient({
      projectId: this.projectId,
      apiKey: this.apiKey,
    })

    // Create a webhook to monitor content and schema changes
    // if one wasn't already created
    if (webhookUrl) {
      const webhooks = await this.apiClient.getWebhooks()
      const stackbitWebhook = webhooks.find(
        (webhook) => webhook.url === webhookUrl,
      )
      if (!stackbitWebhook) {
        await this.apiClient.createWebhook({
          url: webhookUrl,
        })
      }
    }

    // perform other necessary initialization operations ...
    this.users = await this.apiClient.getUsers()
  }

  // other methods ...
}