-
Notifications
You must be signed in to change notification settings - Fork 10.3k
chore(docs): Adapters #38233
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
Merged
Merged
chore(docs): Adapters #38233
Changes from 6 commits
Commits
Show all changes
16 commits
Select commit
Hold shift + click to select a range
59d1ebc
initial
LekoArts b1ff8fb
more progress
LekoArts dc9ae2c
more
LekoArts 81dfcac
add missing --verbose mention
LekoArts cf87397
finish creating guide
LekoArts d2095bd
http headers docs
LekoArts ba5aa99
Apply suggestions from code review
LekoArts af76ac2
Update docs/docs/how-to/previews-deploys-hosting/adapters.md
LekoArts 80ff8ca
review comments
LekoArts 11a7fb7
add trailingSlash and pathPrefix information
LekoArts ea9f439
add config to adapter API
LekoArts 5798146
add testing note
LekoArts b6682ff
Merge branch 'master' into docs/gatsby-adapters
LekoArts 7610cce
update version note to 5.12
LekoArts 2a62429
add supports to config hook
LekoArts 703e731
add pluginsToDisable config field
pieh File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,48 @@ | ||
| --- | ||
| title: Adapters | ||
| --- | ||
|
|
||
| ## Introduction | ||
|
|
||
| Adapters are responsible for taking the production output from Gatsby and turning it into something your deployment platform understands. They make it easier to build and deploy Gatsby on any deployment platform. | ||
|
|
||
| Gatsby has different [rendering options](/docs/conceptual/rendering-options/) and features like DSG and SSR require more setup than classic SSG. Users can also set [HTTP headers](/docs/how-to/previews-deploys-hosting/headers/) or create [redirects](/docs/reference/config-files/actions/#createRedirect). Gatsby passes all the required information during the build to its adapters so that they can _adapt_ these outputs for deployment. | ||
LekoArts marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| This feature was added in `[email protected]`. | ||
|
|
||
LekoArts marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| ## Finding adapters | ||
|
|
||
| You can use these official adapters: | ||
|
|
||
| - [gatsby-adapter-netlify](https://github.com/gatsbyjs/gatsby/tree/master/packages/gatsby-adapter-netlify) for [Netlify](https://www.netlify.com/) | ||
|
|
||
| You can [search npm for `gatsby-adapter`](https://www.npmjs.com/search?q=gatsby-adapter-) to find additional community adapters. Didn't find an adapter for your platform? Consider [creating an adapter](/docs/how-to/previews-deploys-hosting/creating-an-adapter/). | ||
LekoArts marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| ## Using adapters | ||
|
|
||
| Use the `adapter` option inside `gatsby-config`: | ||
|
|
||
| ```js:title=gatsby-config.js | ||
| const adapter = require("gatsby-adapter-foo") | ||
|
|
||
| module.exports = { | ||
| adapter: adapter() | ||
| } | ||
| ``` | ||
|
|
||
| If your adapter is accepting custom options, you can set them like so: | ||
LekoArts marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| ```js:title=gatsby-config.js | ||
| const adapter = require("gatsby-adapter-foo") | ||
|
|
||
| module.exports = { | ||
| adapter: adapter({ | ||
| // Adapter options | ||
| }) | ||
| } | ||
| ``` | ||
|
|
||
| ## Additional resources | ||
|
|
||
| - [Zero-Configuration Deployments](/docs/how-to/previews-deploys-hosting/zero-configuration-deployments/) | ||
| - [Creating an Adapter](/docs/how-to/previews-deploys-hosting/creating-an-adapter/) | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
262 changes: 262 additions & 0 deletions
262
docs/docs/how-to/previews-deploys-hosting/creating-an-adapter.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,262 @@ | ||
| --- | ||
| title: Creating an Adapter | ||
| examples: | ||
| - label: gatsby-adapter-netlify | ||
| href: "https://github.com/gatsbyjs/gatsby/tree/master/packages/gatsby-adapter-netlify" | ||
| --- | ||
|
|
||
| import Collapsible from "@components/collapsible" | ||
|
|
||
| ## Introduction | ||
|
|
||
| If an [adapter](/docs/how-to/previews-deploys-hosting/adapters/) for your preferred deployment platform doesn't exist yet, you can build your own. While the specifics of the adapter depend on the deployment platform and its requirements, the initial setup is the same for every adapter. | ||
|
|
||
| By the end of this guide you should be able to create and publish an adapter. | ||
|
|
||
| The adapters feature was added in `[email protected]`. | ||
|
|
||
| ## Authoring | ||
|
|
||
| An adapter's entrypoint has to have the following API: | ||
LekoArts marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| ```js | ||
| /** | ||
| * @type {import("gatsby").AdapterInit} | ||
| */ | ||
| const createAdapterFoo = adapterOptions => { | ||
| return { | ||
| name: `gatsby-adapter-foo`, | ||
| cache: { | ||
| restore({ directories, reporter }) { | ||
| // Cache restore implementation | ||
| }, | ||
| store({ directories, reporter }) { | ||
| // Cache store implementation | ||
| }, | ||
| }, | ||
| adapt({ routesManifest, functionsManifest, reporter }) { | ||
| // Adapt implementation | ||
| }, | ||
| } | ||
| } | ||
|
|
||
| module.exports = createAdapterFoo | ||
| ``` | ||
|
|
||
| <Collapsible | ||
| summary={<em>TypeScript version</em>} | ||
| > | ||
| Gatsby makes a `AdapterInit` type available which you can use to author your adapter. It also accepts a generic for the adapter options: | ||
LekoArts marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| ```ts | ||
| import type { AdapterInit } from "gatsby" | ||
|
|
||
| type AdapterOptions = { | ||
| foo: boolean | ||
| } | ||
|
|
||
| const createAdapterFoo: AdapterInit<AdapterOptions> = ({ foo }) => { | ||
| return { | ||
| name: `gatsby-adapter-foo`, | ||
| cache: { | ||
| restore({ directories, reporter }) { | ||
| // Cache restore implementation | ||
| }, | ||
| store({ directories, reporter }) { | ||
| // Cache store implementation | ||
| }, | ||
| }, | ||
| adapt({ routesManifest, functionsManifest, reporter }) { | ||
| // Adapt implementation | ||
| }, | ||
| } | ||
| } | ||
|
|
||
| export default createAdapterFoo | ||
| ``` | ||
|
|
||
| You can find all TypeScript types [on GitHub](https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby/src/utils/adapter/types.ts). | ||
|
|
||
| </Collapsible> | ||
|
|
||
| The adapter has to export a function as a default export with these object keys: | ||
LekoArts marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| - `name`: Unique name of the adapter. Please follow the naming convention `gatsby-adapter-name` or `@scope/gatsby-adapter-name` as it'll make it easier for folks to discover your adapter. | ||
LekoArts marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| - `cache` (Optional): Both handlers receive `directories` which are the directories that should be cached/restored for a build. | ||
LekoArts marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| - `restore`: Hook to restore `directories` from previous builds. This is executed very early on in the build process. If `false` is returned Gatsby will skip its cache restoration. | ||
LekoArts marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| - `store`: Hook to store `directories` for the current build. Executed as one of the last steps in the build process. | ||
| - [`adapt`](#adapt): Hook to take Gatsby's output and prepare it for deployment on the adapter's platform. Executed as one of the last steps in the build process. | ||
LekoArts marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| If your adapter accepts custom options, consider setting default values (if reasonable). This will make it easier to use your adapter. | ||
LekoArts marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| `cache.restore`, `cache.store`, and `adapt` receive the [`reporter` instance](/docs/reference/config-files/node-api-helpers/#reporter), so you can output structured logs to the user’s terminal. **However**, please don’t overdo it and keep the output to a minimum. The user will already get information what adapter is used and can debug things further by running the CLI with the `--verbose` flag. | ||
LekoArts marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| ### adapt | ||
|
|
||
| The `adapt` hook takes Gatsby's output and prepares it for deployment on the adapter's platform. It receives the following inputs: | ||
|
|
||
| - `routesManifest`: Array of objects with three different types: `static`, `function`, and `redirect`. Each objects contains all necessary information to deploy and apply these routes. `static` routes will have default `headers` applied which users can extend/overwrite with the [HTTP headers](/docs/how-to/previews-deploys-hosting/headers/) option inside `gatsby-config`. | ||
LekoArts marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| - `functionsManifest`: Array of objects to give the adapter each function entrypoint and its required files. | ||
LekoArts marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| You can find the TypeScript types for these inputs on [on GitHub](https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby/src/utils/adapter/types.ts) to learn more. | ||
LekoArts marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| The `adapt` hook should do the following things: | ||
|
|
||
| - Apply HTTP headers to assets | ||
| - Apply redirects and rewrites. The adapter should can also create its own redirects/rewrites if necessary (e.g. mapping serverless functions to internal URLs). | ||
LekoArts marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| - Wrap serverless functions coming from Gatsby with platform-specific code (if necessary). Gatsby will produce [Express-like](https://expressjs.com/) handlers. | ||
LekoArts marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| - Possibly upload assets to CDN | ||
|
|
||
| ## Testing locally | ||
|
|
||
| If you want to test your adapter locally, you can use [npm link](https://docs.npmjs.com/cli/v9/commands/npm-link), [yarn link](https://yarnpkg.com/cli/link), or equivalent in other package managers. You'd use your adapter like so: | ||
|
|
||
| ```js:title=gatsby-config.js | ||
| // gatsby-adapter-foo would be your linked adapter | ||
| const adapter = require("gatsby-adapter-foo") | ||
|
|
||
| module.exports = { | ||
| adapter: adapter() | ||
| } | ||
| ``` | ||
|
|
||
| If you want to quickly prototype an adapter, you could also author your file(s) directly in an example project (before moving them to their own repository). Here's how: | ||
LekoArts marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| 1. Create an adapter file called `gatsby-adapter-foo.js` at the root of your project: | ||
|
|
||
| ```js:title=gatsby-adapter-foo.js | ||
| const createAdapterFoo = adapterOptions => { | ||
| return { | ||
| name: `gatsby-adapter-foo`, | ||
| // cache hooks... | ||
| adapt({ routesManifest, functionsManifest, reporter }) { | ||
| // Adapt implementation | ||
| reporter.info('gatsby-adapter-foo is working') | ||
| }, | ||
| } | ||
| } | ||
|
|
||
| module.exports = createAdapterFoo | ||
| ``` | ||
|
|
||
| 1. Import the adapter file into your `gatsby-config`: | ||
|
|
||
| ```js:title=gatsby-config.js | ||
| const adapter = require("./gatsby-adapter-foo") | ||
|
|
||
| module.exports = { | ||
| adapter: adapter() | ||
| } | ||
| ``` | ||
|
|
||
| 1. If it's all working, don't forget to [publish](#publishing) your adapter so that the community can benefit from it. | ||
LekoArts marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| ## Publishing | ||
|
|
||
| You'll need to publish your adapter to [npm](https://www.npmjs.com/) so that others can use it. If you have never published anything to npm, consider following their [guides](https://docs.npmjs.com/packages-and-modules/contributing-packages-to-the-registry). | ||
LekoArts marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| Once your adapter is out there and people are using it, you’ll also need to think about making changes responsibly (following [semver](https://docs.npmjs.com/about-semantic-versioning)) or automating some of the maintenance work. | ||
LekoArts marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| Be sure to go through this checklist before publishing your plugin for the first time: | ||
LekoArts marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| - Choose a clear name for your adapter following this naming convention: | ||
|
|
||
| ``` | ||
| gatsby-adapter-<name> | ||
| ``` | ||
|
|
||
| If you want/need to publish the adapter under a [scope](https://docs.npmjs.com/about-scopes) follow the convention: | ||
LekoArts marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| ``` | ||
| @scope/gatsby-adapter-<name> | ||
| ``` | ||
|
|
||
| - Your `README` should explain to the user in concise steps how to install, use, and configure your adapter (also see [How to write a plugin README](/contributing/docs-contributions/how-to-write-a-plugin-readme/)). The `README` will be the first thing a user sees so make sure that it's accessible to everyone. | ||
LekoArts marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| - Set `1.0.0` as your `version` field in your adapter's `package.json`. Afterwards follow [semantic versioning](https://docs.npmjs.com/about-semantic-versioning). | ||
LekoArts marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| ```json:title=package.json | ||
| { | ||
| "version": "1.0.0", | ||
| } | ||
| ``` | ||
|
|
||
| - Include a `keywords` field in your adapter's `package.json`, containing `gatsby`, `gatsby-plugin`, and `gatsby-adapter`. This way the adapter can be found through the [plugin library](/plugins/). | ||
|
|
||
| ```json:title=package.json | ||
| { | ||
| "keywords": [ | ||
| "gatsby", | ||
| "gatsby-plugin", | ||
| "gatsby-adapter" | ||
| ], | ||
| } | ||
| ``` | ||
|
|
||
| - Include a `peerDependencies` field in your adapter's `package.json`, containing the `gatsby` version range that your adapter is compatible with. | ||
|
|
||
| For example, if your adapter supports Gatsby 5 only (e.g. it uses an API only available in Gatsby 5), use: | ||
|
|
||
| ```json:title=package.json | ||
| { | ||
| "peerDependencies": { | ||
| "gatsby": "^5.0.0" | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| If now Gatsby comes out with a new major version and your adapter didn't use any APIs that needed changes, you could mark your adapter compatible with Gatsby 5 and Gatsby 6 like so: | ||
LekoArts marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| ```json:title=package.json | ||
| { | ||
| "peerDependencies": { | ||
| "gatsby": "^5.0.0 || ^6.0.0" | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| - Add a `build` script to your adapter's `package.json`. The `build` script should compile your source code to **CommonJS (CJS)** into a `dist` folder. If you're authoring the code in TypeScript, also consider generating type definitions. If you're authoring the code in CJS already there is no need for a `build` script. | ||
|
|
||
| Depending on your tooling (e.g. [microbundle](https://github.com/developit/microbundle), [Babel](https://babeljs.io/), [Parcel](https://parceljs.org/), [tsup](https://github.com/egoist/tsup)) adjust your build script: | ||
|
|
||
| ```json:title=package.json | ||
| { | ||
| "scripts": { | ||
| "build": "your-build-script", | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| Since your compiled information will be in the `dist` folder, you need to also add a `main` and `files` key to the `package.json`. | ||
|
|
||
| ```json:title=package.json | ||
| { | ||
| "main": "./dist/index.js", | ||
| "files": [ | ||
| "./dist/*" | ||
| ], | ||
| } | ||
| ``` | ||
|
|
||
| If you've generated TypeScript types, consider [adding a `types` key](https://www.typescriptlang.org/docs/handbook/declaration-files/publishing.html). | ||
|
|
||
| - Add a `prepare` script to your adapter's `package.json` that runs before `npm publish`. If your `build` script isn't automatically clearing the `dist` folder before doing a new build, add an additional `clean` script. This is to ensure that inside the `dist` folder no old artifacts are being published (e.g. you're renaming a file and without the `clean` the old file would still be published through `dist`). You could use [del-cli](https://www.npmjs.com/package/del-cli) to achieve this. It would look something like this: | ||
LekoArts marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| ```json:title=package.json | ||
| { | ||
| "scripts": { | ||
| "clean": "del-cli dist", | ||
| "build": "your-build-script", | ||
| "prepare": "npm run clean && npm run build" | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| - Follow the other recommendations from npm's [Creating a package.json file](https://docs.npmjs.com/creating-a-package-json-file) documentation, e.g. adding a `description` or `author` field. | ||
|
|
||
| ## Additional resources | ||
|
|
||
| - [gatsby-adapter-netlify source code](https://github.com/gatsbyjs/gatsby/tree/master/packages/gatsby-adapter-netlify) | ||
| - [Adapters](/docs/how-to/previews-deploys-hosting/adapters/) | ||
| - [Zero-Configuration Deployments](/docs/how-to/previews-deploys-hosting/zero-configuration-deployments/) | ||
| - [Gatsby Adapters RFC](#TODO) | ||
LekoArts marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.