# How to Configure Gatsby Plugins with Custom Options and Available Configuration Patterns

> Learn to configure Gatsby plugins with custom options using gatsby-config.js. Explore patterns like environment variables and conditional loading for flexible site builds.

- Repository: [Gatsby/gatsby](https://github.com/gatsbyjs/gatsby)
- Tags: how-to-guide
- Published: 2026-03-06

---

**Configure Gatsby plugins by exporting a `plugins` array from [`gatsby-config.js`](https://github.com/gatsbyjs/gatsby/blob/main/gatsby-config.js) using either a string for simple plugins or an object with `resolve` and `options` fields for custom configuration, leveraging patterns like environment variables, conditional loading, and schema validation.**

Gatsby plugins extend the functionality of static sites built with the `gatsbyjs/gatsby` repository. Understanding how to pass custom options and utilize advanced configuration patterns ensures you can tailor plugin behavior to your specific build requirements without modifying core package code.

## Basic Plugin Configuration in gatsby-config.js

The [`gatsby-config.js`](https://github.com/gatsbyjs/gatsby/blob/main/gatsby-config.js) file resides in the project root and exports a configuration object. The `plugins` array accepts entries that are either **strings** representing package names or **objects** containing `resolve` and `options` properties.

When Gatsby initializes, the bootstrap process in [`packages/gatsby/src/bootstrap/index.js`](https://github.com/gatsbyjs/gatsby/blob/main/packages/gatsby/src/bootstrap/index.js) loads the site configuration via `loadConfig` and extracts the plugin definitions from `config?.plugins` before processing them through the plugin resolution pipeline.

### Simple String Plugins

For plugins requiring no custom settings, add the package name directly to the array:

```javascript
module.exports = {
  plugins: [
    `gatsby-plugin-react-helmet`,
    `gatsby-plugin-sitemap`,
  ],
}

```

### Object-Style Configuration with Options

To pass custom options, use the object syntax where `resolve` specifies the plugin name or path and `options` contains the configuration object:

```javascript
module.exports = {
  plugins: [
    {
      resolve: `gatsby-plugin-google-analytics`,
      options: {
        trackingId: "UA-12345678-1",
        head: true,
        anonymize: true,
      },
    },
  ],
}

```

## Option Validation with pluginOptionsSchema

Gatsby v4 and later support runtime validation of plugin options through the `pluginOptionsSchema` API. Plugin authors export a function using **Joi** to define type constraints, required fields, and default values. Gatsby validates user-supplied options against this schema before invoking lifecycle methods like `onPreInit` or `createSchemaCustomization`.

If a plugin provides a schema, invalid configurations will fail during the bootstrap phase with descriptive error messages, preventing runtime crashes in the build process.

## Available Configuration Patterns

Beyond basic object syntax, [`gatsby-config.js`](https://github.com/gatsbyjs/gatsby/blob/main/gatsby-config.js) supports several advanced patterns for dynamic and complex setups.

### Local Plugin Paths

You can reference local plugins using absolute or relative paths resolved from the site root:

```javascript
module.exports = {
  plugins: [
    {
      resolve: `${__dirname}/plugins/my-local-plugin`,
      options: { greeting: "Hello from local plugin" },
    },
  ],
}

```

Gatsby resolves plugins in this order: absolute paths first, then relative paths from the site root, finally node modules lookup.

### Environment Variable Injection

Since [`gatsby-config.js`](https://github.com/gatsbyjs/gatsby/blob/main/gatsby-config.js) executes in a Node.js context, you can inject environment variables for secrets or environment-specific settings:

```javascript
module.exports = {
  plugins: [
    {
      resolve: `gatsby-source-contentful`,
      options: {
        spaceId: process.env.CONTENTFUL_SPACE_ID,
        accessToken: process.env.CONTENTFUL_ACCESS_TOKEN,
      },
    },
  ],
}

```

**Warning:** Values passed via `options` become part of the static bundle unless the plugin keeps them server-only. Never expose sensitive tokens to the client side inadvertently.

### Conditional and Dynamic Plugin Loading

Leverage JavaScript logic to conditionally include plugins based on environment or other runtime checks. Filter out falsy values to prevent Gatsby from attempting to load undefined entries:

```javascript
const isProd = process.env.NODE_ENV === "production"

module.exports = {
  plugins: [
    isProd && {
      resolve: `gatsby-plugin-google-gtag`,
      options: { trackingIds: ["G-ABCDEF123"] },
    },
  ].filter(Boolean),
}

```

This pattern is essential for analytics or error tracking that should only execute in production builds.

### Nested Objects and Arrays

Complex plugins accept nested configurations or arrays of objects. For example, feed generators often require multiple query configurations:

```javascript
module.exports = {
  plugins: [
    {
      resolve: `gatsby-plugin-feed`,
      options: {
        feeds: [
          {
            query: `
              {
                site {
                  siteMetadata { title }
                }
              }
            `,
            output: "/rss.xml",
          },
        ],
      },
    },
  ],
}

```

### Theme Configuration with Sub-Plugins

Gatsby themes are plugins that can bundle their own `plugins` array. When configuring a theme, you pass options to the theme itself, which may then configure sub-plugins internally:

```javascript
module.exports = {
  plugins: [
    {
      resolve: `gatsby-theme-minimal`,
      options: {
        basePath: `/blog`,
      },
    },
  ],
}

```

## Plugin Resolution Mechanism

According to the `gatsbyjs/gatsby` source code, specifically in [`packages/gatsby/src/bootstrap/index.js`](https://github.com/gatsbyjs/gatsby/blob/main/packages/gatsby/src/bootstrap/index.js), Gatsby extracts the plugins array and processes each entry through a resolution algorithm. The system attempts resolution as an absolute file system path first, then as a relative path from the site root, and finally via standard Node.js module resolution in `node_modules`.

This three-tier resolution allows seamless switching between installed npm packages, local workspace plugins, and absolute path references without changing the configuration syntax.

## Summary

- **Configure plugins** in [`gatsby-config.js`](https://github.com/gatsbyjs/gatsby/blob/main/gatsby-config.js) by exporting a `plugins` array containing strings or objects with `resolve` and `options` fields.
- **Validate options** automatically when plugins export a `pluginOptionsSchema` using Joi constraints.
- **Use local paths** by providing absolute or relative paths in the `resolve` field, resolved from the site root.
- **Inject environment variables** via `process.env` inside the options object, keeping in mind security implications for client-side bundles.
- **Load conditionally** by constructing the plugins array dynamically and filtering falsy values to enable environment-specific plugin sets.
- **Resolve order** follows absolute path → relative path → node module, as implemented in the bootstrap phase.

## Frequently Asked Questions

### How do I pass different options to the same plugin in multiple instances?

Export multiple object entries in the `plugins` array, each with a unique `resolve` value pointing to the same plugin name but with distinct `options` objects. Gatsby treats each object as a separate plugin instance.

### Can I use TypeScript for gatsby-config.js to get type checking for plugin options?

Yes. Rename the file to [`gatsby-config.ts`](https://github.com/gatsbyjs/gatsby/blob/main/gatsby-config.ts) and use TypeScript exports. Gatsby v4+ supports TypeScript configuration files natively, providing autocompletion and type safety for plugin options when types are available.

### What happens if I provide invalid options to a plugin?

If the plugin exports a `pluginOptionsSchema`, Gatsby validates your options against the Joi schema during the bootstrap phase and throws a descriptive error before the build starts. If no schema exists, the plugin receives the raw options and may fail at runtime or silently ignore invalid keys.

### How do I configure a plugin differently for development versus production?

Use conditional logic within [`gatsby-config.js`](https://github.com/gatsbyjs/gatsby/blob/main/gatsby-config.js) to check `process.env.NODE_ENV` and return different options objects or exclude the plugin entirely using the array filter pattern. This ensures development builds remain fast while production builds include analytics or optimization plugins.