Skip to main content

Gatsby React Framework

Gatsby is a React-based framework for building blazing-fast websites and applications with a rich plugin ecosystem and GraphQL data layer.

What is Gatsby?

Gatsby is a free, open-source framework based on React that helps developers build performant websites and applications.

Key Features:

  • ⚛️ React-Based - Component-driven development
  • GraphQL Data Layer - Unified data access
  • Rich Plugin Ecosystem - 2500+ plugins
  • 🖼️ Image Optimization - Automatic optimization
  • Performance - Pre-rendering and optimization
  • Progressive Web App - PWA out of the box
  • Security - No servers or databases to hack
  • SEO Friendly - Server-side rendering for crawlers

Installation

Prerequisites

  • Node.js 18.0 or higher
  • npm or yarn

Install Gatsby CLI

npm install -g gatsby-cli

Create New Site

# Create from starter
gatsby new my-site

# Create from specific starter
gatsby new my-blog https://github.com/gatsbyjs/gatsby-starter-blog

# Create minimal site
gatsby new my-site gatsbyjs/gatsby-starter-hello-world

Start Development

cd my-site
gatsby develop

Visit: http://localhost:8000

GraphiQL: http://localhost:8000/___graphql

Project Structure

my-site/
├── src/
│ ├── components/ # React components
│ │ ├── header.js
│ │ └── layout.js
│ ├── pages/ # Page components
│ │ ├── index.js
│ │ ├── about.js
│ │ └── 404.js
│ ├── templates/ # Template components
│ │ └── blog-post.js
│ ├── images/ # Images
│ └── styles/ # CSS/Styled components
├── static/ # Static files
├── gatsby-config.js # Site configuration
├── gatsby-node.js # Node APIs (create pages)
├── gatsby-browser.js # Browser APIs
├── gatsby-ssr.js # Server-side rendering APIs
└── package.json

Configuration

gatsby-config.js

module.exports = {
siteMetadata: {
title: 'My Gatsby Site',
description: 'A site built with Gatsby',
author: '@myusername',
siteUrl: 'https://example.com',
},
plugins: [
'gatsby-plugin-react-helmet',
'gatsby-plugin-image',
'gatsby-plugin-sharp',
'gatsby-transformer-sharp',
{
resolve: 'gatsby-source-filesystem',
options: {
name: 'images',
path: `${__dirname}/src/images`,
},
},
{
resolve: 'gatsby-source-filesystem',
options: {
name: 'blog',
path: `${__dirname}/content/blog`,
},
},
'gatsby-transformer-remark',
{
resolve: 'gatsby-plugin-manifest',
options: {
name: 'My Gatsby Site',
short_name: 'Gatsby Site',
start_url: '/',
background_color: '#663399',
theme_color: '#663399',
display: 'minimal-ui',
icon: 'src/images/icon.png',
},
},
],
};

Pages

Creating Pages

Create files in src/pages/:

// src/pages/index.js
import React from 'react';
import Layout from '../components/layout';

export default function Home() {
return (
<Layout>
<h1>Welcome to My Site</h1>
<p>This is built with Gatsby!</p>
</Layout>
);
}

Dynamic Routes

// src/pages/blog/{mdx.slug}.js
import React from 'react';
import { graphql } from 'gatsby';

export default function BlogPost({ data }) {
return (
<article>
<h1>{data.mdx.frontmatter.title}</h1>
<div dangerouslySetInnerHTML={{ __html: data.mdx.html }} />
</article>
);
}

export const query = graphql`
query($id: String) {
mdx(id: { eq: $id }) {
frontmatter {
title
date
}
html
}
}
`;

GraphQL Data Layer

Page Query

import React from 'react';
import { graphql } from 'gatsby';

export default function About({ data }) {
return (
<div>
<h1>{data.site.siteMetadata.title}</h1>
<p>{data.site.siteMetadata.description}</p>
</div>
);
}

export const query = graphql`
query {
site {
siteMetadata {
title
description
}
}
}
`;

Static Query (useStaticQuery Hook)

import React from 'react';
import { useStaticQuery, graphql } from 'gatsby';

export default function Header() {
const data = useStaticQuery(graphql`
query {
site {
siteMetadata {
title
}
}
}
`);

return <h1>{data.site.siteMetadata.title}</h1>;
}

GraphiQL Explorer

Access at http://localhost:8000/___graphql

query {
allMarkdownRemark(sort: { fields: [frontmatter___date], order: DESC }) {
edges {
node {
id
frontmatter {
title
date(formatString: "MMMM DD, YYYY")
}
excerpt
fields {
slug
}
}
}
}
}

Working with Markdown

Install Plugins

npm install gatsby-transformer-remark
npm install gatsby-source-filesystem

Configure

// gatsby-config.js
plugins: [
{
resolve: 'gatsby-source-filesystem',
options: {
name: 'blog',
path: `${__dirname}/content/blog`,
},
},
'gatsby-transformer-remark',
],

Create Markdown Files

---
title: "My First Post"
date: "2025-01-15"
author: "John Doe"
---

# My First Blog Post

This is my first post written in Markdown!

## Features

- Easy to write
- Clean syntax
- Supports code blocks

Query Markdown

export const query = graphql`
query {
allMarkdownRemark {
edges {
node {
frontmatter {
title
date
}
html
excerpt
}
}
}
}
`;

Images

Gatsby Image Plugin

npm install gatsby-plugin-image gatsby-plugin-sharp gatsby-transformer-sharp

Static Images

import { StaticImage } from 'gatsby-plugin-image';

export default function MyComponent() {
return (
<StaticImage
src="../images/hero.jpg"
alt="Hero image"
placeholder="blurred"
layout="constrained"
width={800}
/>
);
}

Dynamic Images (GraphQL)

import { GatsbyImage, getImage } from 'gatsby-plugin-image';
import { graphql } from 'gatsby';

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

return (
<article>
<GatsbyImage image={image} alt={data.mdx.frontmatter.title} />
<h1>{data.mdx.frontmatter.title}</h1>
</article>
);
}

export const query = graphql`
query($id: String) {
mdx(id: { eq: $id }) {
frontmatter {
title
featuredImage {
childImageSharp {
gatsbyImageData(width: 800)
}
}
}
}
}
`;

Creating Pages Programmatically

gatsby-node.js

const path = require('path');

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

const result = await graphql(`
query {
allMarkdownRemark {
edges {
node {
fields {
slug
}
}
}
}
}
`);

result.data.allMarkdownRemark.edges.forEach(({ node }) => {
createPage({
path: node.fields.slug,
component: path.resolve('./src/templates/blog-post.js'),
context: {
slug: node.fields.slug,
},
});
});
};

// Add slug field
exports.onCreateNode = ({ node, actions, getNode }) => {
const { createNodeField } = actions;

if (node.internal.type === 'MarkdownRemark') {
const slug = `/blog/${node.frontmatter.title.toLowerCase().replace(/\s+/g, '-')}/`;

createNodeField({
node,
name: 'slug',
value: slug,
});
}
};

Essential Plugins

SEO

npm install gatsby-plugin-react-helmet react-helmet
// src/components/seo.js
import React from 'react';
import { Helmet } from 'react-helmet';
import { useStaticQuery, graphql } from 'gatsby';

export default function SEO({ title, description }) {
const { site } = useStaticQuery(graphql`
query {
site {
siteMetadata {
title
description
}
}
}
`);

return (
<Helmet>
<title>{title} | {site.siteMetadata.title}</title>
<meta name="description" content={description || site.siteMetadata.description} />
</Helmet>
);
}

Styling

CSS Modules

import * as styles from './header.module.css';

export default function Header() {
return <h1 className={styles.title}>Hello</h1>;
}

Styled Components

npm install gatsby-plugin-styled-components styled-components babel-plugin-styled-components
import styled from 'styled-components';

const Title = styled.h1`
color: rebeccapurple;
font-size: 2rem;
`;

export default function Header() {
return <Title>Hello</Title>;
}

Tailwind CSS

npm install -D tailwindcss gatsby-plugin-postcss
npx tailwindcss init

Analytics

npm install gatsby-plugin-google-gtag
// gatsby-config.js
{
resolve: 'gatsby-plugin-google-gtag',
options: {
trackingIds: ['GA-TRACKING_ID'],
},
},

Content Sources

CMS Integration

Contentful

npm install gatsby-source-contentful
{
resolve: 'gatsby-source-contentful',
options: {
spaceId: process.env.CONTENTFUL_SPACE_ID,
accessToken: process.env.CONTENTFUL_ACCESS_TOKEN,
},
},

WordPress

npm install gatsby-source-wordpress
{
resolve: 'gatsby-source-wordpress',
options: {
url: 'https://your-wordpress-site.com/graphql',
},
},

Sanity

npm install gatsby-source-sanity
{
resolve: 'gatsby-source-sanity',
options: {
projectId: 'your-project-id',
dataset: 'production',
},
},

Build & Deployment

Build for Production

gatsby build

Output in public/ folder.

Serve Locally

gatsby serve

Environment Variables

# .env.development
CONTENTFUL_SPACE_ID=xxxxx
CONTENTFUL_ACCESS_TOKEN=xxxxx

# .env.production
CONTENTFUL_SPACE_ID=xxxxx
CONTENTFUL_ACCESS_TOKEN=xxxxx

Use in config:

require('dotenv').config({
path: `.env.${process.env.NODE_ENV}`,
});

Netlify

# netlify.toml
[build]
publish = "public"
command = "gatsby build"

[[plugins]]
package = "netlify-plugin-gatsby-cache"

Vercel

Vercel auto-detects Gatsby projects.

{
"buildCommand": "gatsby build",
"outputDirectory": "public"
}

GitHub Actions

name: Deploy

on:
push:
branches: [main]

jobs:
build-deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 18
- run: npm ci
- run: gatsby build
- uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./public

Performance Optimization

Image Optimization

  • Use gatsby-plugin-image
  • Lazy load images
  • Serve WebP format
  • Responsive images

Code Splitting

  • Dynamic imports
  • Route-based splitting
  • Component-based splitting
import React, { lazy, Suspense } from 'react';

const HeavyComponent = lazy(() => import('./HeavyComponent'));

export default function Page() {
return (
<Suspense fallback={<div>Loading...</div>}>
<HeavyComponent />
</Suspense>
);
}

Prefetching

import { Link } from 'gatsby';

// Automatically prefetches on hover
<Link to="/blog/">Blog</Link>

Best Practices

Performance

  • Optimize images with gatsby-plugin-image
  • Use lazy loading for heavy components
  • Minimize bundle size
  • Enable caching
  • Use CDN for static assets

SEO

  • Add meta tags with React Helmet
  • Generate sitemap
  • Add robots.txt
  • Use semantic HTML
  • Optimize for Core Web Vitals

Development

  • Use TypeScript for type safety
  • Implement error boundaries
  • Test with Jest and Testing Library
  • Use ESLint and Prettier
  • Version control with Git

Accessibility

  • Use semantic HTML elements
  • Add alt text to images
  • Ensure keyboard navigation
  • Test with screen readers
  • Maintain color contrast

Troubleshooting

Clear Cache

gatsby clean

Build Errors

Check Node version:

node --version  # Should be 18+

GraphQL Errors

Explore schema in GraphiQL:

gatsby develop
# Visit http://localhost:8000/___graphql

Memory Issues

Increase Node memory:

NODE_OPTIONS="--max-old-space-size=4096" gatsby build

Gatsby vs Other Frameworks

FeatureGatsbyNext.jsHugo
FrameworkReactReactGo
Data LayerGraphQLProps/APIFiles
Plugins2500+ManyThemes
Learning CurveModerateModerateEasy
Build SpeedSlowerFastVery Fast
SSRNoYesNo
Best ForContent sitesAppsBlogs

Resources

Quick Reference

# Install CLI
npm install -g gatsby-cli

# Create new site
gatsby new my-site

# Development
gatsby develop

# Build
gatsby build

# Serve production build
gatsby serve

# Clean cache
gatsby clean

# Get info
gatsby info