Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs: improve documentation for plugin authors #4272

Merged
merged 12 commits into from
Mar 1, 2018
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ Looking to speak about Gatsby? We'd love to review your talk abstract/CFP! You c

### Creating your own plugins and loaders

If you create a loader or plugin, we would <3 for you to open source it, and put it on npm.
If you create a loader or plugin, we would <3 for you to open source it, and put it on npm. For more information on creating custom plugins, please see the documentation for [plugins](/docs/plugins/) and the [API specification](/docs/api-specification/).

### Contributing to the repo

Expand Down
68 changes: 68 additions & 0 deletions docs/docs/plugin-authoring.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
---
title: Plugin Authoring
---

Creating custom plugins in Gatsby is a breeze with our straightforward authoring process.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We've been following @robwierzbowski's suggestion to avoid indicating something is "easy" as that can intimidate newer developers for whom everything is complicated

#3159

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed. Another way to word this could be:

The Gatsby API is open and flexible and the number of plugins created by community members is growing. Follow these steps to create a custom plugin in Gatsby.

I don't know if that is gobbledygook language since I'm not a programmer. The essence would be to emphasize how Gatsby is meant to be open to plugins. It was built to expect them. Or something like that. Just a tone that invites people to experiment and realize that there is a lot of potential for an awesome plugin ecosystem.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey, thanks for remembering! My two cents:

Gatsby is designed to be extensible. One of the best ways to add functionality to Gatsby is through our plugin system. (maybe some examples of what is a good fit for a plugin...)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good call. I'm leaning toward @robwierzbowski's wording, and I'll work in some examples of good candidates for plugins.


## Core Concepts

- Every Gatsby plugin is a standalone npm package
- At minimum, a `package.json` is required
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove "At minimum"

- Plugins can be used locally (see [local plugins](#local-plugins) below) or published to npm as packages
Copy link
Contributor

@m-allanson m-allanson Feb 28, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this concept conflict with the first concept "Every Gatsby plugin is a standalone npm package"?

Maybe the first concept could be something like "A Gatsby plugin is a set of files that can modify Gatsby's behaviour"?

- A plugin has access to the the Gatsby [Node](/docs/node-apis/), [SSR](/docs/ssr-apis/), and [browser](/docs/browser-apis/) APIs
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd put it "Plugins implement Gatsby APIs for [Node]..."


## Plugin naming conventions

There are four standard plugin naming conventions for Gatsby:

- **`gatsby-source-*`** — a source plugin loads data from a given source (e.g. WordPress, MongoDB, the file system). Use this plugin type if you are connecting a new source of data to Gatsby.
- Example: `gatsby-source-contentful`
- **`gatsby-transformer-*`** — a transformer plugin converts data from one format to another (e.g. CSV to JSON). Use this naming convention
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"A transformer plugin converts data from one format into JavaScript objects"

I can't think of any reason why a transformer plugin wouldn't ever transform data directly into JavaScript objects. It could happen but it's unlikely.

- Example: `gatsby-transformer-yaml`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible to add a bit more info on when you'd create a transformer vs a source plugin? Maybe this isn't the right place to write about that, but it's something that's a bit of a grey area to me.

- **`gatsby-[plugin-name]-*`** — if a plugin is a plugin for another plugin 😅, it should be prefixed with the name of the plugin it extends (e.g. if it adds emoji to the output of `gatsby-transformer-remark`, call it `gatsby-remark-add-emoji`). Use this naming convention whenever your plugin will be included as a plugin in the `options` object of another plugin.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm guessing plugin creators will get this, and possibly I'm just the one who is confused. Because it sounds like if you just keep adding something to the end of all applicable prefixes, wouldn't it be gatsby-transformer-remark-add-emoji? I mean, that's insanely long, but these instructions would have made me think that was correct without the helpful example. Does that make sense?

- Example: `gatsby-remark-images`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The examples should link to their package page.

- **`gatsby-plugin-*`** — this is the most general plugin type. Use this naming convention if your plugin doesn’t meet the requirements of any other plugin types.
- Example: `gatsby-plugin-sass`

## What files does Gatsby look for in a plugin?

- `package.json` — [required] used to find the `name` and `version` fields (both optional)
- this can be an empty object (`{}`) for local plugins
- `gatsby-browser.js` — usage details are in the [browser API reference](/docs/browser-apis/)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it worth being explicit that these three files are optional? Similar to the [required] note on package.json

- `gatsby-node.js` — usage details are in the [Node API reference](/docs/node-apis/)
- `gatsby-ssr.js` — usage details are in the [SSR API reference](/docs/ssr-apis/)

## Local plugins

When you want to work on a new plugin, or maybe write one that is only relevant
to your specific use-case, a locally defined plugin is more convenient than
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

*because a locally defined

having to create an NPM package for it.

You can place the code in the `plugins` folder in the root of your project like
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove "can"

this:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hey hey! Nice use of a full sentence before a colon. I'm not a grammar tight wad (hopefully) but did find it interesting to learn last year that I had been using colons ineffectively for years. They are most effective after full sentences and hardly anyone does that


```
plugins
└── my-own-plugin
└── package.json
```

**NOTE:** You still need to add the plugin to your `gatsby-config.js` like for plugins
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

like reads a bit strangely to me. Would any of the following work better? the same as, similarly to, as you would, or something else?

installed from NPM.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

*like you would for plugins


At a minimum, each plugin requires a package.json file, but the minimum content is just an
empty object `{}`. The `name` and `version` fields are read from the package
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The first sentence mentions that "the minimum content is just an empty object". The following sentence then explains what is read from package.json. I find this a little confusing—first it's "okay to be empty", but then "things are read" only fully makes sense to me after advancing to the following paragraphs. I think an addition to the second sentence would help (me ;-)), but I'm not sure if the following is the best way to go:

If present, the name and version fields are read from the package file.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point — let me add what the default values are.

file. The name is used to identify the plugin when it mutates the GraphQL data
structure. The version is used to clear the cache when it changes.

For local plugins it is best to leave the version field empty. Gatsby will
generate an md5-hash from all `gatsby-*` file contents and use that as the
version. This way the cache is automatically flushed when you change the code of
your plugin.

If the name is empty it is inferred from the plugin folder name.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

*empty,


Like all `gatsby-*` files, the code is not being processed by Babel. If you want
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

*is not processed

Kill "being"

to use JavaScript syntax which isn't supported by your version of Node.js, you
can place the files in a `src` subfolder and build them to the plugin folder
root.
36 changes: 2 additions & 34 deletions docs/docs/plugins.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,41 +40,9 @@ Plugins can take options. Note that plugin options will be stringified by Gatsby
See each plugin page below for more detailed
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just for less redundancy, perhaps: "see the links below for instructions on how to use each plugin"

documentation on using each plugin.

## Locally defined plugins
## Creating your own plugins

When you want to work on a new plugin, or maybe write one that is only relevant
to your specific use-case, a locally defined plugin is more convenient than
having to create an NPM package for it.

You can place the code in the `plugins` folder in the root of your project like
this:

```
plugins
└── my-own-plugin
├── gatsby-node.js
└── package.json
```

You still need to add the plugin to your `gatsby-config.js` like for plugins
installed from NPM.

Each plugin requires a package.json file, but the minimum content is just an
empty object `{}`. The `name` and `version` fields are read from the package
file. The name is used to identify the plugin when it mutates the GraphQL data
structure. The version is used to clear the cache when it changes.

For local plugins it is best to leave the version field empty. Gatsby will
generate an md5-hash from all gatsby-\* file contents and use that as the
version. This way the cache is automatically flushed when you change the code of
your plugin.

If the name is empty it is inferred from the plugin folder name.

Like all gatsby-\* files, the code is not being processed by Babel. If you want
to use JavaScript syntax which isn't supported by your version of Node.js, you
can place the files in a `src` subfolder and build them to the plugin folder
root.
If you’d like to create a custom Gatsby plugin, check out the [plugin authoring guide](/docs/plugin-authoring/).

## Official plugins

Expand Down
2 changes: 2 additions & 0 deletions www/src/pages/docs/doc-links.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@
link: /docs/migrating-from-v0-to-v1/
- title: Path Prefix
link: /docs/path-prefix/
- title: Plugin Authoring
link: /docs/plugin-authoring/
- title: Proxying API Requests
link: /docs/api-proxy/
- title: Using CSS-in-JS library Glamor
Expand Down