Configuring Plugin Usage with Plugin Options

Plugins loaded into a Gatsby site can have options passed in to customize how a plugin operates.

This guide refers to creating plugins, if you are looking for general information on using options with plugins refer to “Using a Plugin in Your Site”. If you are looking for options of a specific plugin, refer to its README.

Where to access plugin options

A Gatsby plugin with options included makes those options available in the second argument of Gatsby Node, Browser, and SSR APIs. Consider the following gatsby-config.js with a plugin called gatsby-plugin-console-log:

With the optionA, optionB, and message options passed into the plugin, the code for gatsby-plugin-console-log is able to access the values true, false, and "Hello world" by their keys.

For example, gatsby-plugin-console-log can access the message in order to log its value to the console inside of the onPreInit API:

The code above is called when gatsby develop or gatsby build is run. It takes the message from the options object in the config and logs it from pluginOptions.message when the onPreInit method is called.

The second argument passed into the function is where the options are held.

Like arguments in any JavaScript function, you can use a different (more specific) name like themeOptions if you are building a plugin that will be used as a theme.

What can be passed in as options

Any JavaScript data type can be passed in as an option.

The following table lists possible options values and an example plugin that makes use of them.

Data TypeSample ValueExample Plugin
Booleantruegatsby-plugin-sharp
String/src/data/gatsby-source-filesystem
Array["/about-us/", "/projects/*"]gatsby-plugin-offline
Object{ default: "./src/layout.js" }gatsby-plugin-mdx

Note: Themes (which are a type of plugin) are able to receive options from a site’s gatsby-config.js to be used in its gatsby-config.js in order to allow themes to be composed together. This is done by exporting the gatsby-config.js as a function instead of an object. You can see an example of this in the gatsby-theme-blog and gatsby-theme-blog-core repositories. Plugins are not capable of this functionality.

How to validate plugin options

To help users configure plugins correctly, a plugin can optionally define a schema to enforce a type for each option. Gatsby will validate that the options users pass match the schema to help them correctly set up their site.

How to define an options schema

You should use the pluginOptionsSchema API to define your plugins’ options schema. It gets passed an instance of Joi, which you use to return a Joi.object schema for the options you expect users to pass.

For example, imagine you were creating a plugin called gatsby-plugin-console-log. You decide you want users to configure your plugin using the following options:

You want users to pass in a boolean to optionA and a string to message, and they can optionally pass a boolean to optionB. To enforce these rules, you would create the following pluginOptionsSchema:

If users pass options that do not match the schema, the validation will show an error when they run gatsby develop and prompt them to fix their configuration.

For example, if an integer is passed into message (which is marked as a required string) this message would be shown:

Best practices for option schemas

The Joi API documentation is a great reference to use while working on a pluginOptionsSchema, as it shows all the available types and methods.

Here are some specific Joi best practices for pluginOptionsSchema:

Add descriptions

Make sure that every option and field has a .description() explaining its purpose. This is helpful for documentation as users can look at the schema and understand all the options. There might also be tooling in the future that auto-generates plugin option documentation from the schema.

Set default options

You can use the .default() method to set a default value for an option. For example, in the gatsby-plugin-console-log plugin above, you could have the message option default to "default message" if a user does not pass their own message value:

Accessing pluginOptions.message would then log "default message" in all plugin APIs if the user does not supply their own value.

Validate external access

Some plugins (particularly source plugins) query external APIs. With the .external() method, you can asynchronously validate that the user has access to the API, providing a better experience if they pass invalid secrets.

For example, this is how the Contentful source plugin might validate that the user has access to the space they are trying to query:

Add custom error messages

Sometimes you might want to provide more detailed error messages when validation fails for a specific field. Joi provides a .messages() method which lets you override error messages for specific error types (e.g. "any.required" when a .required() call fails).

For example, in the gatsby-plugin-console-log plugin above, this is how you would provide a custom error message if users do not specify optionA:

Deprecating options

While you can simply remove options from the schema in major versions, that causes cryptic error messages for users upgrading with existing configuration. Instead, deprecate them using the .forbidden() method in a major version release. Then, add a custom error message explaining how users should upgrade the functionality using .messages().

For example:

Unit testing an options schema

To verify that a pluginOptionsSchema behaves as expected, unit test it with different configurations using the gatsby-plugin-utils package.

  1. Add the gatsby-plugin-utils package to your site:

  2. Use the testPluginOptionsSchema function exported from the package in your test file. It takes two parameters, the plugin’s actual Joi schema and an example options object to test. It returns an object with an isValid boolean, which will be true or false based on whether or not the options object fits the actual Joi schema, and an errors array, which will contain the error messages if the validation failed.

For example, with Jest, your tests might look something like this:

Additional resources

Edit this page on GitHub