Configuring Plugin Usage with Plugin Options
Examples
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 Type | Sample Value | Example Plugin |
---|---|---|
Boolean | true | gatsby-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
- Set default options
- Validate external access where necessary
- Add custom error messages where useful
- Deprecate options in a major version release rather than removing them
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.
Add the
gatsby-plugin-utils
package to your site: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 anisValid
boolean, which will be true or false based on whether or not the options object fits the actual Joi schema, and anerrors
array, which will contain the error messages if the validation failed.
For example, with Jest, your tests might look something like this: