This episode breaks down Gatsby configuration: the roles of gatsby-config.js and gatsby-node.js, environment variables and the GATSBY_ prefix convention, source and transformer plugins, data schema customization, and how to manage secrets and per-environment settings.

As a project grows, configuration and environment management become decisive for smooth operations. Gatsby provides two main configuration files plus an environment variables system with clear rules.
Episode 8 breaks down gatsby-config.js and gatsby-node.js, the Gatsby environment variable conventions, the role of source and transformer plugins, schema customization, and how to manage secrets safely.
gatsby-config.js: declarative configuration — siteMetadata, the plugins list, and flags.gatsby-node.js: imperative logic — creating pages with createPages, modifying nodes with onCreateNode, and changing the schema.Both run in the Node.js environment at build time, so they can use any Node API and the entire process.env.
gatsby-node.js exports lifecycle functions. One of the most frequently used:
exports.createPages = async ({ actions }) => {
const { createPage } = actions
createPage({
path: "/halaman-kustom",
component: require.resolve("./src/templates/halaman.js"),
context: {},
})
}createPage creates a new page with path, component, and context that can be passed on to queries. Full details on programmatic page creation are covered in episode 14.
Gatsby automatically reads .env.development and .env.production files when the related command is run. The key rule: only variables prefixed with GATSBY_ can be used in client code (React components). For example:
GATSBY_API_URL=https://api.example.com
SITE_TITLE=Gatsby BelajarIn gatsby-config.js, all variables can be used — including those without the prefix:
module.exports = {
siteMetadata: {
title: process.env.SITE_TITLE || "Gatsby Belajar",
},
plugins: [
{
resolve: "gatsby-source-filesystem",
options: {
name: "content",
path: `${__dirname}/content`,
},
},
],
}process.env.SITE_TITLE is available in the configuration because this file runs in Node. However, in React components, process.env.GATSBY_API_URL is the only way to access env — only GATSBY_ variables are injected at build time.
Source plugins create raw nodes (files, CMS content), and transformers turn them into queryable types (MarkdownRemark, ImageSharp). The two always work as a pair for local data.
Sometimes you need to control Gatsby's data types. Use createSchemaCustomization with GraphQL SDL:
exports.createSchemaCustomization = ({ actions }) => {
const { createTypes } = actions
const typeDefs = `
type MarkdownRemark implements Node {
frontmatter: Frontmatter
}
type Frontmatter {
title: String!
published: Boolean
tags: [String!]
}
`
createTypes(typeDefs)
}createTypes with SDL type definitions gives your schema certainty — for example, published is of type Boolean and tags must be an array of strings.
Sensitive data such as server API keys and CMS tokens should only be used in gatsby-config.js and gatsby-node.js. Never put a secret with the GATSBY_ prefix, because it will be bundled into the JavaScript sent to the browser.
.env* files to .gitignore.process.env in the plugin options that run at build time.Warning
Once a secret leaks into the client bundle, there is no safe way to hide it. Restrict token access to the build side only, and rotate tokens if a leak occurs.
A common pattern: separate env files for development and production. Gatsby picks automatically based on the command: gatsby develop loads .env.development, gatsby build loads .env.production. If you need different values for staging, name them according to the platform and override them in the deployment settings.
With this separation, dev and production behavior can differ — for example, a different API URL and a debug mode enabled only during development.
Episode 8 completed configuration: the roles of gatsby-config.js and gatsby-node.js, the environment variable convention with the GATSBY_ prefix, schema customization, and safe secret management.
Key takeaways:
gatsby-config for declarations; gatsby-node for build logic.GATSBY_ are available in client code.createTypes is used to control the data schema.GATSBY_ prefix..env.development and .env.production are loaded automatically per command..gitignore must cover all .env* files.In the next episode, episode 9, we'll discuss content management and CMS integration — sourcing Markdown and MDX, integrating headless CMSs like Contentful and Strapi, preview mode, and content modeling with query optimization.