Skip to content

Gatsby — Building Blazing Fast Static Sites with React

DodaTech Updated 2026-06-28 5 min read

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

Gatsby is a React-based static site generator that uses GraphQL to query data from multiple sources and pre-builds optimized static pages.

What You'll Learn

By the end of this tutorial, you'll understand the Gatsby architecture, its data layer powered by GraphQL, the plugin ecosystem, and how to build and deploy Gatsby static sites.

Why It Matters

Gatsby pioneered the modern SSG approach with its unique GraphQL data layer, image optimization pipeline, and massive plugin ecosystem. It remains one of the most popular choices for content-heavy static sites.

Real-World Use

A marketing team builds their company website with Gatsby, pulling content from WordPress, images from Cloudinary, and product data from Shopify. Gatsby's GraphQL layer unifies all data sources and generates a fully static site with optimized images.

Gatsby Architecture

graph TD
    A[Gatsby Build Process] --> B[Source Plugins]
    B --> C[gatsby-source-wordpress]
    B --> D[gatsby-source-filesystem]
    B --> E[gatsby-source-shopify]
    C --> F[Unified GraphQL
Data Layer] D --> F E --> F F --> G[gatsby-config.js] F --> H[gatsby-node.js] G --> I[Transformer Plugins] H --> J[Create Pages] I --> K[gatsby-transformer-remark] I --> L[gatsby-transformer-sharp] J --> M[Static HTML Pages] K --> M L --> M M --> N[gatsby build
→ public/] style B fill:#4a90d9,color:#fff style F fill:#e67e22,color:#fff style M fill:#27ae60,color:#fff

Gatsby Project Setup

// gatsby-config.js — Core configuration
module.exports = {
    siteMetadata: {
        title: 'My Gatsby Site',
        description: 'Built with Gatsby SSG',
        siteUrl: 'https://example.com',
        author: 'DodaTech'
    },
    plugins: [
        'gatsby-plugin-react-helmet',
        'gatsby-plugin-image',
        'gatsby-plugin-sharp',
        'gatsby-transformer-sharp',
        {
            resolve: 'gatsby-source-filesystem',
            options: {
                name: 'content',
                path: `${__dirname}/content`
            }
        },
        {
            resolve: 'gatsby-transformer-remark',
            options: {
                plugins: ['gatsby-remark-images']
            }
        }
    ]
};

Page Creation with GraphQL

// gatsby-node.js — Create pages from markdown
const path = require('path');

exports.createPages = async ({ graphql, actions }) => {
    const { createPage } = actions;

    // Query all markdown files
    const result = await graphql(`
        query {
            allMarkdownRemark {
                edges {
                    node {
                        frontmatter {
                            slug
                            title
                        }
                    }
                }
            }
        }
    `);

    // Create a page for each markdown file
    result.data.allMarkdownRemark.edges.forEach(({ node }) => {
        createPage({
            path: `/blog/${node.frontmatter.slug}`,
            component: path.resolve('./src/templates/blog-post.js'),
            context: {
                slug: node.frontmatter.slug
            }
        });
    });
};

GraphQL Data Fetching in Pages

// src/pages/index.js — Homepage with GraphQL query
import React from 'react';
import { graphql, Link } from 'gatsby';
import { GatsbyImage } from 'gatsby-plugin-image';

export default function HomePage({ data }) {
    const posts = data.allMarkdownRemark.edges;

    return (
        <div>
            <h1>{data.site.siteMetadata.title}</h1>
            <p>{data.site.siteMetadata.description}</p>
            <h2>Latest Posts</h2>
            <ul>
                {posts.map(({ node }) => (
                    <li key={node.id}>
                        <Link to={`/blog/${node.frontmatter.slug}`}>
                            {node.frontmatter.title}
                        </Link>
                        <small>{node.frontmatter.date}</small>
                    </li>
                ))}
            </ul>
        </div>
    );
}

export const pageQuery = graphql`
    query {
        site {
            siteMetadata {
                title
                description
            }
        }
        allMarkdownRemark(
            sort: { frontmatter: { date: DESC } }
            limit: 10
        ) {
            edges {
                node {
                    id
                    frontmatter {
                        title
                        slug
                        date(formatString: "MMMM DD, YYYY")
                    }
                    excerpt(pruneLength: 150)
                }
            }
        }
    }
`;

Image Optimization

// src/templates/blog-post.js — Optimized images
import React from 'react';
import { graphql } from 'gatsby';
import { GatsbyImage, getImage } from 'gatsby-plugin-image';

export default function BlogPost({ data }) {
    const post = data.markdownRemark;
    const image = getImage(post.frontmatter.featuredImage);

    return (
        <article>
            <h1>{post.frontmatter.title}</h1>
            <p>{post.frontmatter.date}</p>

            {image && (
                <GatsbyImage
                    image={image}
                    alt={post.frontmatter.title}
                    className="featured-image"
                />
            )}

            <div dangerouslySetInnerHTML={{ __html: post.html }} />
        </article>
    );
}

export const query = graphql`
    query($slug: String!) {
        markdownRemark(frontmatter: { slug: { eq: $slug } }) {
            html
            frontmatter {
                title
                date(formatString: "MMMM DD, YYYY")
                featuredImage {
                    childImageSharp {
                        gatsbyImageData(
                            width: 800
                            placeholder: BLURRED
                            formats: [AUTO, WEBP, AVIF]
                        )
                    }
                }
            }
        }
    }
`;

Common Mistakes

  1. Over-fetching in GraphQL queries. Request only the fields you need. Unused fields still get processed and slow down builds.
  2. Not using gatsby-plugin-image. The older gatsby-image is deprecated. Always use gatsby-plugin-image for better performance and modern formats.
  3. Forgetting to configure pathPrefix for subdirectory deployment. If deploying to example.com/blog/, set pathPrefix in gatsby-config.js.
  4. Ignoring build-time memory limits. Large Gatsby builds can exceed 2GB RAM. Configure NODE_OPTIONS=--max-old-space-size=4096 for large sites.
  5. Not optimizing queries with aliases and fragments. Repeating the same field selections increases query complexity. Use GraphQL fragments.

Practice Questions

  1. How does Gatsby's data layer unify multiple data sources?
  2. What is the role of gatsby-Node.js in page creation?
  3. How does Gatsby optimize images during the build Process?
  4. What are source plugins and transformer plugins?
  5. How do you create dynamic pages from markdown files in Gatsby?

Challenge: Build a Gatsby portfolio site with content from markdown files, optimized images using gatsby-plugin-image, a blog with at least 3 posts, and navigation between pages.

FAQ

Do I need to know GraphQL to use Gatsby?

Yes, for anything beyond basic pages. Gatsby uses GraphQL as its data layer. Knowing the basics (queries, fragments, variables) is essential.

How does Gatsby compare to Next.js SSG?

Gatsby has a richer plugin ecosystem and image pipeline. Next.js has ISR, smaller bundle sizes, and simpler data fetching. Choose Gatsby for content sites, Next.js for hybrid apps.

Can Gatsby use TypeScript?

Yes, since Gatsby v5. Gatsby supports .tsx files and tsconfig.json out of the box. Many plugins also include TypeScript definitions.

How do I handle environment variables in Gatsby?

Use .env files. Prefix with GATSBY_ for client-side variables. Server-only variables (API keys) are available in gatsby-node.js and gatsby-ssr.js.

Does Gatsby support incremental builds?

Yes, with Gatsby Cloud or gatsby-plugin-incremental. Incremental builds only rebuild changed pages, dramatically reducing build time for large sites.

Mini Project

Create a Gatsby blog: configure gatsby-source-filesystem to read markdown from content/ directory, use gatsby-transformer-remark for Markdown rendering, create pages dynamically in gatsby-node.js, add image optimization with gatsby-plugin-image, and build the site.

What's Next

You've built a Gatsby site. Now learn how to extend it with Gatsby Source Plugins to fetch data from CMS, APIs, and external sources.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro