Skip to content

Gatsby Source Plugins — Fetching Data from CMS, APIs, and Files

DodaTech Updated 2026-06-28 4 min read

In this tutorial, you will learn about Gatsby Source Plugins. We cover key concepts, practical examples, and best practices to help you master this topic.

Gatsby source plugins pull data from external sources like CMS, APIs, databases, and local files into Gatsby's unified GraphQL data layer.

What You'll Learn

By the end of this tutorial, you'll understand how Gatsby source plugins work, how to configure popular source plugins, how to create custom source plugins, and how to combine multiple data sources.

Why It Matters

A static site is only as good as its content pipeline. Source plugins determine what data is available during build, how often it updates, and how easily your team can publish content.

Real-World Use

A documentation site pulls content from three sources: WordPress for blog posts, a GitHub repo for API docs, and a headless CMS for product documentation. Gatsby source plugins unify all three into one GraphQL schema.

Source Plugin Architecture

graph TD
    A[Gatsby Source Plugins] --> B[gatsby-source-filesystem]
    A --> C[gatsby-source-wordpress]
    A --> D[gatsby-source-contentful]
    A --> E[gatsby-source-shopify]
    A --> F[Custom Source Plugin]
    B --> G[Local files
Markdown, images, data] C --> H[WordPress REST or
GraphQL API] D --> I[Contentful
CMS API] E --> J[Shopify
Storefront API] F --> K[Any external
API or database] G --> L[Gatsby GraphQL
Data Layer] H --> L I --> L J --> L K --> L L --> M[gatsby-transformer plugins] M --> N[Transformed nodes] style A fill:#4a90d9,color:#fff style L fill:#e67e22,color:#fff style N fill:#27ae60,color:#fff

WordPress Source Plugin

// gatsby-config.js — WordPress source
module.exports = {
    plugins: [
        {
            resolve: 'gatsby-source-wordpress',
            options: {
                url: 'https://example.com/graphql',
                schema: {
                    perPage: 100,
                    requestConcurrency: 5,
                    previewRequestConcurrency: 2
                },
                develop: {
                    hardCacheMediaFiles: true
                },
                production: {
                    hardCacheMediaFiles: true
                }
            }
        }
    ]
};

Contentful Source Plugin

// gatsby-config.js — Contentful source
module.exports = {
    plugins: [
        {
            resolve: 'gatsby-source-contentful',
            options: {
                spaceId: process.env.CONTENTFUL_SPACE_ID,
                accessToken: process.env.CONTENTFUL_ACCESS_TOKEN,
                host: process.env.CONTENTFUL_HOST || 'cdn.contentful.com',
                environment: process.env.CONTENTFUL_ENVIRONMENT || 'master',
                downloadLocal: true,
                forceFullSync: false
            }
        }
    ]
};

// Query CMS content in pages
// src/pages/products.js
export const query = graphql`
    query {
        allContentfulProduct(sort: { name: ASC }) {
            nodes {
                id
                name
                price
                slug
                description {
                    description
                }
                image {
                    gatsbyImageData(
                        width: 400
                        placeholder: BLURRED
                    )
                }
            }
        }
    }
`;

Custom Source Plugin

// plugins/gatsby-source-airtable/gatsby-node.js
// Custom source plugin for Airtable
const axios = require('axios');

exports.sourceNodes = async (
    { actions, createNodeId, createContentDigest },
    pluginOptions
) => {
    const { createNode } = actions;
    const { apiKey, baseId, tableName } = pluginOptions;

    try {
        const response = await axios.get(
            `https://api.airtable.com/v0/${baseId}/${tableName}`,
            {
                headers: { Authorization: `Bearer ${apiKey}` }
            }
        );

        response.data.records.forEach(record => {
            const node = {
                id: createNodeId(`airtable-${record.id}`),
                ...record.fields,
                internal: {
                    type: 'AirtableRecord',
                    content: JSON.stringify(record.fields),
                    contentDigest: createContentDigest(record)
                }
            };
            createNode(node);
        });

        console.log(`Sourced ${response.data.records.length} Airtable records`);
    } catch (error) {
        console.error('Airtable source error:', error.message);
    }
};

Combining Multiple Sources

// gatsby-config.js — Multiple source plugins
module.exports = {
    plugins: [
        // Local files for content
        {
            resolve: 'gatsby-source-filesystem',
            options: {
                name: 'blog',
                path: `${__dirname}/content/blog`
            }
        },
        {
            resolve: 'gatsby-source-filesystem',
            options: {
                name: 'docs',
                path: `${__dirname}/content/docs`
            }
        },

        // CMS sources
        {
            resolve: 'gatsby-source-wordpress',
            options: {
                url: process.env.WP_GRAPHQL_URL
            }
        },

        // E-commerce
        {
            resolve: 'gatsby-source-shopify',
            options: {
                shopName: process.env.SHOPIFY_SHOP_NAME,
                accessToken: process.env.SHOPIFY_ACCESS_TOKEN
            }
        },

        // Transformers
        'gatsby-transformer-remark',
        'gatsby-transformer-sharp',
        'gatsby-transformer-json'
    ]
};

Common Mistakes

  1. Exposing API tokens in the frontend. Source plugin tokens are environment variables. Never hardcode them. Use .env files with proper prefixes.
  2. Over-fetching data from API sources. WordPress or Contentful can return large payloads. Use field selection in GraphQL to request only needed fields.
  3. Not configuring concurrent request limits. Source plugins that make many API calls can rate-limit. Set requestConcurrency to avoid bans.
  4. Ignoring incremental builds for source data. Each full build re-fetches all data. Configure Caching or use Gatsby Cloud for incremental sourcing.
  5. Forgetting to restart gatsby develop after config changes. Changes to gatsby-config.js require a restart. Hot reload doesn't pick up source plugin changes.

Practice Questions

  1. What is the purpose of a Gatsby source plugin?
  2. How do transformer plugins differ from source plugins?
  3. How can you combine data from multiple source plugins?
  4. What environment variables are typically needed for CMS source plugins?
  5. How does a custom source plugin create nodes in Gatsby's data layer?

Challenge: Build a site with three data sources: markdown files for blog content, a Contentful CMS for product data, and a custom source plugin for testimonials from a Google Sheets API. Combine all in a unified GraphQL query.

FAQ

Do source plugins work with Gatsby Cloud incremental builds?

Most official source plugins support incremental builds. Check the plugin documentation. Content changes trigger rebuilds only of affected pages.

Can I write a source plugin for a private API?

Yes. Create a local plugin in plugins/ directory. Use gatsby-node.js sourceNodes API to fetch and create nodes from any HTTP API.

How do source plugins handle media files?

Some plugins download media locally (downloadLocal: true). Others reference remote URLs. Local copies improve build reliability but increase storage.

What happens when a source plugin fails during build?

The build fails. Wrap API calls in try-catch blocks in custom plugins. Official plugins handle errors gracefully with clear messages.

Can I use multiple instances of the same source plugin?

Yes. Configure multiple instances with different names and paths. For example, two gatsby-source-filesystem instances for blog and docs directories.

Mini Project

Create a Gatsby site with three data sources: local markdown files for blog posts, Contentful CMS for product pages, and a custom REST API source plugin for user testimonials. Combine all in the GraphQL layer and display on separate pages.

What's Next

You've mastered Gatsby source plugins. Now dive into Gatsby GraphQL to write advanced queries, fragments, and optimize your data layer.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro