Gatsby gives plugins and site builders many APIs for building your site. Code in the file gatsby-node.js
/gatsby-node.ts
is run once in the process of building your site. You can use its APIs to create pages dynamically, add data into GraphQL, or respond to events during the build lifecycle. To use the Gatsby Node APIs, create a file named gatsby-node.js
/gatsby-node.ts
in the root of your site. Export any of the APIs you wish to use in this file.
You can author the file in JavaScript (CommonJS or ES Modules (ESM) syntax) or TypeScript.
Every Gatsby Node API gets passed a set of helper functions. These let you access several methods like reporting, or perform actions like creating new pages.
An example gatsby-node.js
file that implements two APIs, onPostBuild
, and createPages
.
The TypeScript and Gatsby documentation shows how to set up a gatsby-node
file in TypeScript.
Read the ES Modules (ESM) and Gatsby documentation if you don’t want to use CommonJS syntax.
Async vs. sync workIf your plugin performs async operations (disk I/O, database access, calling remote APIs, etc.) you must either return a promise (explicitly using Promise
API or implicitly using async
/await
syntax) or use the callback passed to the 3rd argument. Gatsby needs to know when plugins are finished as some APIs, to work correctly, require previous APIs to be complete first. See Debugging Async Lifecycles for more info.
If your plugin does not do async work, you can return directly.
Start building today on
Netlify!
APIsCreate pages dynamically. This extension point is called only after the initial sourcing and transformation of nodes plus creation of the GraphQL schema are complete so you can query your data in order to create pages.
You can also fetch data from remote or local sources to create pages.
See also the documentation for the action createPage
.
Promise<void>
No return value required, but the caller will await
any promise that’s returned
const path = require(`path`)
exports.createPages = ({ graphql, actions }) => {
const { createPage } = actions
const blogPostTemplate = path.resolve(`src/templates/blog-post.js`)
return graphql(`
query loadPagesQuery ($limit: Int!) {
allMarkdownRemark(limit: $limit) {
edges {
node {
frontmatter {
slug
}
}
}
}
}
`, { limit: 1000 }).then(result => {
if (result.errors) {
throw result.errors
}
result.data.allMarkdownRemark.edges.forEach(edge => {
createPage({
path: `${edge.node.frontmatter.slug}`,
component: blogPostTemplate,
context: {
},
})
})
})
}
Like createPages
but for plugins who want to manage creating and removing pages themselves in response to changes in data not managed by Gatsby. Plugins implementing createPages
will get called regularly to recompute page information as Gatsby’s data changes but those implementing createPagesStatefully
will not.
An example of a plugin that uses this extension point is the plugin gatsby-plugin-page-creator which monitors the src/pages
directory for the adding and removal of JS pages. As its source of truth, files in the pages directory, is not known by Gatsby, it needs to keep its own state about its world to know when to add and remove pages.
Add custom field resolvers to the GraphQL schema.
Allows adding new fields to types by providing field configs, or adding resolver functions to existing fields.
Things to note:
createTypes
action. In case of types added from third-party schemas, where this is not possible, overriding field types is allowed.filter
and sort
input types. Extend types defined with createTypes
if you need this.info.originalResolver
.createResolvers
API is called as the last step in schema generation. Thus, an intermediate schema is made available on the intermediateSchema
property. In resolver functions themselves, it is recommended to access the final built schema from info.schema
.context.nodeModel
. The node store can be queried directly with findOne
, getNodeById
and getNodesByIds
, while more advanced queries can be composed with findAll
.Query
type.source
in the example below, often also called parent
or root
), take care of the fact that field resolvers can be called more than once in a query, e.g. when the field is present both in the input filter and in the selection set. This means that foreign-key fields on source
can be either resolved or not-resolved.For fuller examples, see using-type-definitions
.
destructured object
intermediateSchema
GraphQLSchema
Current GraphQL schema
createResolvers
function
Add custom resolvers to GraphQL field configs
$1
object
resolvers
object
An object map of GraphQL type names to custom resolver functions
options
object
Optional createResolvers options
ignoreNonexistentTypes
object
Silences the warning when trying to add resolvers for types that don’t exist. Useful for optional extensions.
exports.createResolvers = ({ createResolvers }) => {
const resolvers = {
Author: {
fullName: {
resolve: (source, args, context, info) => {
return source.firstName + source.lastName
}
},
},
Query: {
allRecentPosts: {
type: [`BlogPost`],
resolve: async (source, args, context, info) => {
const { entries } = await context.nodeModel.findAll({ type: `BlogPost` })
return entries.filter(
post => post.publishedAt > Date.UTC(2018, 0, 1)
)
}
}
}
}
createResolvers(resolvers)
}
Customize Gatsby’s GraphQL schema by creating type definitions, field extensions or adding third-party schemas.
The createTypes
, createFieldExtension
and addThirdPartySchema
actions are only available in this API. For details on their usage please refer to the actions documentation.
This API runs immediately before schema generation. For modifications of the generated schema, e.g. to customize added third-party types, use the createResolvers
API.
destructured object
actions
object
createFieldExtension
object
addThirdPartySchema
object
exports.createSchemaCustomization = ({ actions }) => {
const { createTypes, createFieldExtension } = actions
createFieldExtension({
name: 'shout',
extend: () => ({
resolve(source, args, context, info) {
return String(source[info.fieldName]).toUpperCase()
}
})
})
const typeDefs = `
type MarkdownRemark implements Node @dontInfer {
frontmatter: Frontmatter
}
type Frontmatter {
title: String!
tagline: String @shout
date: Date @dateformat
image: File @fileByRelativePath
}
`
createTypes(typeDefs)
}
Let plugins extend/mutate the site’s Babel configuration by calling setBabelPlugin
or setBabelPreset
.
destructured object
stage
string
The current build stage. One of ‘develop’, ‘develop-html’, ‘build-javascript’, or ‘build-html’
options
object
The Babel configuration
exports.onCreateBabelConfig = ({ actions }) => {
actions.setBabelPlugin({
name: `babel-plugin-that-i-like`,
options: {}
})
}
Run when the gatsby develop
server is started. It can be used for adding proxies and Express middleware to the server.
exports.onCreateDevServer = ({ app }) => {
app.get('/hello', function (req, res) {
res.send('hello world')
})
}
Source
Called when a new node is created. Plugins wishing to extend or transform nodes created by other plugins should implement this API.
See also the documentation for createNode
and createNodeField
The Creating a Source Plugin tutorial demonstrates a way a plugin or site might use this API.
Exampleexports.onCreateNode = ({ node, actions }) => {
const { createNode, createNodeField } = actions
}
Called when a new page is created. This extension API is useful for programmatically manipulating pages created by other plugins e.g. if you want paths without trailing slashes.
There is a mechanism in Gatsby to prevent calling onCreatePage for pages created by the same gatsby-node.js to avoid infinite loops/callback.
See the guide Creating and Modifying Pages for more on this API.
SourceLet plugins extend/mutate the site’s webpack configuration. This method can be used by any Gatsby site, app, or plugin, not just plugins.
See also the documentation for setWebpackConfig
.
destructured object
stage
string
The current build stage. One of ‘develop’, ‘develop-html’, ‘build-javascript’, or ‘build-html’
getConfig
function
Returns the current webpack config
rules
object
A set of preconfigured webpack config rules
loaders
object
A set of preconfigured webpack config loaders
plugins
object
A set of preconfigured webpack config plugins
exports.onCreateWebpackConfig = ({
stage, getConfig, rules, loaders, actions
}) => {
actions.setWebpackConfig({
module: {
rules: [
{
test: 'my-css',
use: [loaders.style(), loaders.css()]
},
],
},
});
}
Lifecycle executed in each process (one time per process). Used to store actions etc for later use.
Examplelet createJobV2
exports.onPluginInit = ({ actions }) => {
createJobV2 = actions.createJobV2
}
Called at the end of the bootstrap process after all other extension APIs have been called.
The last extension point called after all other parts of the build process are complete.
Exampleexports.onPostBuild = ({ reporter, basePath, pathPrefix }) => {
reporter.info(
`Site was built with basePath: ${basePath} & pathPrefix: ${pathPrefix}`
);
};
Called once Gatsby has initialized itself and is ready to bootstrap your site.
The first extension point called during the build process. Called after the bootstrap has completed but before the build steps start.
The first API called during Gatsby execution, runs as soon as plugins are loaded, before cache initialization and bootstrap preparation.
Parametersexports.onPreInit = ({ actions }) => {
}
Run during the bootstrap phase. Plugins can use this to define a schema for their options using Joi to validate the options users pass to the plugin.
Parametersdestructured object
Joi
Joi
The instance of Joi to define the schema
exports.pluginOptionsSchema = ({ Joi }) => {
return Joi.object({
anonymize: Joi.boolean().required(),
})
}
Ask compile-to-js plugins to process source to JavaScript so the query runner can extract out GraphQL queries for running.
Lets plugins implementing support for other compile-to-js add to the list of “resolvable” file extensions. Gatsby supports .js
and .jsx
by default.
string[]
array of extensions
SourceCalled during the creation of the GraphQL schema. Allows plugins to add new fields to the types created from data nodes. It will be called separately for each type.
This function should return an object in the shape of GraphQLFieldConfigMap which will be appended to fields inferred by Gatsby from data nodes.
Note: Import GraphQL types from gatsby/graphql
and don’t add the graphql
package to your project/plugin dependencies to avoid Schema must contain unique named types but contains multiple types named
errors. gatsby/graphql
exports all builtin GraphQL types as well as the GraphQLJSON
type.
Many transformer plugins use this to add fields that take arguments.
adds an “excerpt” field where the user when writing their query can specify how many characters to prune the markdown source to.
gatsby-transformer-sharp
exposesmany image transformation options as GraphQL fields.
Parametersdestructured object
type
object
Object containing name
and nodes
import { GraphQLString } from "gatsby/graphql"
exports.setFieldsOnGraphQLNodeType = ({ type }) => {
if (type.name === `File`) {
return {
newField: {
type: GraphQLString,
args: {
myArgument: {
type: GraphQLString,
}
},
resolve: (source, fieldArgs) => {
return `Id of this node is ${source.id}.
Field was called with argument: ${fieldArgs.myArgument}`
}
}
}
}
return {}
}
Called before scheduling a onCreateNode
callback for a plugin. If it returns falsy then Gatsby will not schedule the onCreateNode
callback for this node for this plugin. Note: this API does not receive the regular api
that other callbacks get as first arg.
exports.shouldOnCreateNode = ({node}, pluginOptions) => node.internal.type === 'Image'
Extension point to tell plugins to source nodes. This API is called during the Gatsby bootstrap sequence. Source plugins use this hook to create nodes. This API is called exactly once per plugin (and once for your site’s gatsby-config.js
file). If you define this hook in gatsby-node.js
it will be called exactly once after all of your source plugins have finished creating nodes.
The Creating a Source Plugin tutorial demonstrates a way a plugin or site might use this API.
See also the documentation for createNode
.
exports.sourceNodes = ({ actions, createNodeId, createContentDigest }) => {
const { createNode } = actions
const myData = {
key: 123,
foo: `The foo field of my node`,
bar: `Baz`
}
const nodeContent = JSON.stringify(myData)
const nodeMeta = {
id: createNodeId(`my-data-${myData.key}`),
parent: null,
children: [],
internal: {
type: `MyNodeType`,
mediaType: `text/html`,
content: nodeContent,
contentDigest: createContentDigest(myData)
}
}
const node = Object.assign({}, myData, nodeMeta)
createNode(node)
}
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4