Skip to content

Commit

Permalink
docs: add new guide and example site on plugin options (#21708)
Browse files Browse the repository at this point in the history
* add example for plugin options and a new guide on them

* add example site to guides resources

* Apply suggestions from code review

Co-Authored-By: LB <[email protected]>

* hopefully fix linting errors

* Apply suggestions from code review

Co-Authored-By: LB <[email protected]>

Co-authored-by: LB <[email protected]>
  • Loading branch information
gillkyle and LB authored Feb 26, 2020
1 parent e42d3ea commit bfe9c08
Show file tree
Hide file tree
Showing 13 changed files with 359 additions and 0 deletions.
59 changes: 59 additions & 0 deletions docs/docs/configuring-usage-with-plugin-options.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
---
title: 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"](/docs/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](/docs/node-apis/), [Browser](/docs/browser-apis/), and [SSR APIs](/docs/ssr-apis/). Consider the following `gatsby-config` with a plugin called `gatsby-plugin-console-log`:

```javascript:title=gatsby-config.js
module.exports = {
plugins: [
{
resolve: `gatsby-plugin-console-log`,
options: { optionA: true, optionB: false, message: "Hello world" },
},
],
}
```

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:

```javascript:title=plugins/gatsby-plugin-console-log/gatsby-node.js
exports.onPreInit = (_, pluginOptions) => {
console.log(
`logging: "${pluginOptions.message || `default message`}" to the console` // highlight-line
)
}
```

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`](/packages/gatsby-plugin-sharp/) |
| String | `/src/data/` | [`gatsby-source-filesystem`](/packages/gatsby-source-filesystem/) |
| Array | `["/about-us/", "/projects/*"]` | [`gatsby-plugin-offline`](/packages/gatsby-plugin-offline/) |
| Object | `{ default: "./src/layout.js" }` | [`gatsby-plugin-mdx`](/packages/gatsby-plugin-mdx/) |

**Note**: Themes (which are a type of plugin) are able to receive options from a site's `gatsby-config` to be used in its `gatsby-config` in order to allow themes to be composed together. This is done by exporting the `gatsby-config` as a function instead of an object. You can see an example of this in the [`gatsby-theme-blog`](https://github.com/gatsbyjs/gatsby/tree/master/packages/gatsby-theme-blog) and [`gatsby-theme-blog-core`](https://github.com/gatsbyjs/gatsby/tree/master/packages/gatsby-theme-blog-core) repositories. Plugins are not capable of this functionality.

## Additional resources

- [Example Gatsby site using plugin options with a local plugin](https://github.com/gatsbyjs/gatsby/tree/master/examples/using-plugin-options)
36 changes: 36 additions & 0 deletions examples/using-plugin-options/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Adding Options to Plugins

This is an example repository demonstrating how to add options to a plugin you've authored.

## Running the example

In this directory, be sure to install dependencies for Gatsby:

```sh
npm install
```

Then run `gatsby develop`:

```sh
gatsby develop
```

In your command line output, you should then see the text listed below. This text is showing how the code for each plugin is run sequentially thanks to the Node API implemented.

```sh
$ gatsby develop
success open and validate gatsby-configs - 0.034s
success load plugins - 0.050s
logging: "Hello world" to the console
logging: "default message" to the console
success onPreInit - 0.022s
```

## Understanding what is happening

If you refer to the `gatsby-config` in this example site, you'll see two plugins included in the plugins array. In actuality, it is the same plugin, `gatsby-plugin-console-log`, configured in two different ways. The plugin logs a message to the console when you run `gatsby develop`.

In the first instance, `gatsby-plugin-console-log` is configured with options passed in and will display the custom message.

The second configuration does not include options, so the plugin will log a default message. You can read about adding local plugins [in the Gatsby docs](https://www.gatsbyjs.org/docs/loading-plugins-from-your-local-plugins-folder/).
16 changes: 16 additions & 0 deletions examples/using-plugin-options/gatsby-config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
module.exports = {
siteMetadata: {
title: `Using plugin options`,
description: `An example Gatsby site using options with a local plugin`,
author: `@gatsbyjs`,
},
plugins: [
// including a plugin from the plugins folder with options
{
resolve: `gatsby-plugin-console-log`,
options: { message: "Hello world" },
},
// including the same plugin without any options, the plugin will use a default message
`gatsby-plugin-console-log`,
],
}
28 changes: 28 additions & 0 deletions examples/using-plugin-options/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"name": "using-plugin-optons",
"description": "An example with the default starter using a plugin with options",
"version": "0.1.0",
"dependencies": {
"gatsby": "^2.18.12",
"prop-types": "^15.7.2",
"react": "^16.12.0",
"react-dom": "^16.12.0",
"react-helmet": "^5.2.1"
},
"devDependencies": {
"prettier": "^1.19.1"
},
"keywords": [
"gatsby"
],
"license": "MIT",
"scripts": {
"build": "gatsby build",
"develop": "gatsby develop",
"format": "prettier --write \"**/*.{js,jsx,json,md}\"",
"start": "npm run develop",
"serve": "gatsby serve",
"clean": "gatsby clean",
"test": "echo \"Write tests! -> https://gatsby.dev/unit-testing\" && exit 1"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
exports.onPreInit = (_, pluginOptions) => {
// uses the plugin options from the gatsby-config and uses it, or a default value
console.log(
`logging: "${pluginOptions.message || `default message`}" to the console`
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
// noop
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"name": "gatsby-plugin-console-log",
"version": "1.0.0",
"description": "Log stuff in a Gatsby site's build process",
"main": "index.js",
"license": "MIT"
}
42 changes: 42 additions & 0 deletions examples/using-plugin-options/src/components/header.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { Link } from "gatsby"
import PropTypes from "prop-types"
import React from "react"

const Header = ({ siteTitle }) => (
<header
style={{
background: `rebeccapurple`,
marginBottom: `1.45rem`,
}}
>
<div
style={{
margin: `0 auto`,
maxWidth: 960,
padding: `1.45rem 1.0875rem`,
}}
>
<h1 style={{ margin: 0 }}>
<Link
to="/"
style={{
color: `white`,
textDecoration: `none`,
}}
>
{siteTitle}
</Link>
</h1>
</div>
</header>
)

Header.propTypes = {
siteTitle: PropTypes.string,
}

Header.defaultProps = {
siteTitle: ``,
}

export default Header
83 changes: 83 additions & 0 deletions examples/using-plugin-options/src/components/layout.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
html {
font-family: sans-serif;
-ms-text-size-adjust: 100%;
-webkit-text-size-adjust: 100%;
}
body {
margin: 0;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
h1 {
font-size: 2em;
margin: 0.67em 0;
}
html {
font: 112.5%/1.45em georgia, serif;
box-sizing: border-box;
overflow-y: scroll;
}
* {
box-sizing: inherit;
}
*:before {
box-sizing: inherit;
}
*:after {
box-sizing: inherit;
}
body {
color: hsla(0, 0%, 0%, 0.8);
font-family: georgia, serif;
font-weight: normal;
word-wrap: break-word;
font-kerning: normal;
-moz-font-feature-settings: "kern", "liga", "clig", "calt";
-ms-font-feature-settings: "kern", "liga", "clig", "calt";
-webkit-font-feature-settings: "kern", "liga", "clig", "calt";
font-feature-settings: "kern", "liga", "clig", "calt";
}
h1 {
margin-left: 0;
margin-right: 0;
margin-top: 0;
padding-bottom: 0;
padding-left: 0;
padding-right: 0;
padding-top: 0;
margin-bottom: 1.45rem;
color: inherit;
font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen,
Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
font-weight: bold;
text-rendering: optimizeLegibility;
font-size: 2.25rem;
line-height: 1.1;
}
h2 {
margin-left: 0;
margin-right: 0;
margin-top: 0;
padding-bottom: 0;
padding-left: 0;
padding-right: 0;
padding-top: 0;
margin-bottom: 1.45rem;
color: inherit;
font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen,
Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
font-weight: bold;
text-rendering: optimizeLegibility;
font-size: 1.62671rem;
line-height: 1.1;
}
p {
margin-left: 0;
margin-right: 0;
margin-top: 0;
padding-bottom: 0;
padding-left: 0;
padding-right: 0;
padding-top: 0;
margin-bottom: 1.45rem;
}
51 changes: 51 additions & 0 deletions examples/using-plugin-options/src/components/layout.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/**
* Layout component that queries for data
* with Gatsby's useStaticQuery component
*
* See: https://www.gatsbyjs.org/docs/use-static-query/
*/

import React from "react"
import PropTypes from "prop-types"
import { useStaticQuery, graphql } from "gatsby"

import Header from "./header"
import "./layout.css"

const Layout = ({ children }) => {
const data = useStaticQuery(graphql`
query SiteTitleQuery {
site {
siteMetadata {
title
}
}
}
`)

return (
<>
<Header siteTitle={data.site.siteMetadata.title} />
<div
style={{
margin: `0 auto`,
maxWidth: 960,
padding: `0 1.0875rem 1.45rem`,
}}
>
<main>{children}</main>
<footer>
© {new Date().getFullYear()}, Built with
{` `}
<a href="https://www.gatsbyjs.org">Gatsby</a>
</footer>
</div>
</>
)
}

Layout.propTypes = {
children: PropTypes.node.isRequired,
}

export default Layout
12 changes: 12 additions & 0 deletions examples/using-plugin-options/src/pages/404.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import React from "react"

import Layout from "../components/layout"

const NotFoundPage = () => (
<Layout>
<h1>NOT FOUND</h1>
<p>You just hit a route that doesn&#39;t exist... the sadness.</p>
</Layout>
)

export default NotFoundPage
16 changes: 16 additions & 0 deletions examples/using-plugin-options/src/pages/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import React from "react"

import Layout from "../components/layout"

const IndexPage = () => (
<Layout>
<h1>Hi people</h1>
<p>
This site is to demonstrate using plugin options, you should see output in
the terminal showing a message you passed in to the plugin options, or a
default Hello world message!
</p>
</Layout>
)

export default IndexPage
2 changes: 2 additions & 0 deletions www/src/data/sidebars/doc-links.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,8 @@
link: /docs/creating-a-source-plugin/
- title: Creating a Transformer Plugin
link: /docs/creating-a-transformer-plugin/
- title: Configuring Usage with Plugin Options
link: /docs/configuring-usage-with-plugin-options/
- title: Submit to Plugin Library
link: /contributing/submit-to-plugin-library/
- title: Pixabay Image Source Plugin Tutorial
Expand Down

0 comments on commit bfe9c08

Please sign in to comment.