Gatsby — Building Blazing Fast Static Sites with React
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
- Over-fetching in GraphQL queries. Request only the fields you need. Unused fields still get processed and slow down builds.
- Not using gatsby-plugin-image. The older gatsby-image is deprecated. Always use gatsby-plugin-image for better performance and modern formats.
- Forgetting to configure pathPrefix for subdirectory deployment. If deploying to example.com/blog/, set pathPrefix in gatsby-config.js.
- Ignoring build-time memory limits. Large Gatsby builds can exceed 2GB RAM. Configure NODE_OPTIONS=--max-old-space-size=4096 for large sites.
- Not optimizing queries with aliases and fragments. Repeating the same field selections increases query complexity. Use GraphQL fragments.
Practice Questions
- How does Gatsby's data layer unify multiple data sources?
- What is the role of gatsby-Node.js in page creation?
- How does Gatsby optimize images during the build Process?
- What are source plugins and transformer plugins?
- 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
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