Skip to main content

Recipes

Craving a happy medium between full-length tutorials and crawling the docs? Here’s a cookbook of guiding recipes on how to build things, Gatsby style.

1. Pages and Layouts

Project structure

Inside a Gatsby project, you may see some or all of the following folders and files:

|-- /.cache
|-- /plugins
|-- /public
|-- /src
|-- /pages
|-- /templates
|-- html.js
|-- /static
|-- gatsby-config.js
|-- gatsby-node.js
|-- gatsby-ssr.js
|-- gatsby-browser.js

Some notable files and their definitions:

  • gatsby-config.js — configure options for a Gatsby site, with metadata for project title, description, plugins, etc.
  • gatsby-node.js — implement Gatsby’s Node.js APIs to customize and extend default settings affecting the build process
  • gatsby-browser.js — customize and extend default settings affecting the browser, using Gatsby’s browser APIs
  • gatsby-ssr.js — use Gatsby’s server-side rendering APIs to customize default settings affecting server-side rendering

Additional resources

Creating pages automatically

Gatsby core automatically turns React components in src/pages into pages with URLs. For example, components at src/pages/index.js and src/pages/about.js would automatically create pages from those filenames for the site’s index page (/) and /about.

Prerequisites

Directions

  1. Create a directory for src/pages if your site doesn’t already have one.
  2. Add a component file to the pages directory:
src/pages/about.js
import React from "react"
const AboutPage = () => (
<main>
<h1>About the Author</h1>
<p>Welcome to my Gatsby site.</p>
</main>
)
export default AboutPage
  1. Run gatsby develop to start the development server.
  2. Visit your new page in the browser: http://localhost:8000/about

Additional resources

Linking between pages

Routing in Gatsby relies on the <Link /> component.

Prerequisites

  • A Gatsby site with two page components: index.js and contact.js
  • The Gatsby <Link /> component
  • The Gatsby CLI to run gatsby develop

Directions

  1. Open the index page component (src/pages/index.js), import the <Link /> component from Gatsby, add a <Link /> component above the header, and give it a to property with the value of "/contact/" for the pathname:
src/pages/index.js
import React from "react"
import { Link } from "gatsby"
export default () => (
<div style={{ color: `purple` }}>
<Link to="/contact/">Contact</Link>
<p>What a world.</p>
</div>
)
  1. Run gatsby develop and navigate to the index page. You should have a link that takes you to the contact page when clicked!

Note: Gatsby’s <Link /> component is a wrapper around @reach/router’s Link component. For more information about Gatsby’s <Link /> component, consult the API reference for <Link />.

Creating pages with createPage

Using Gatsby’s createPages API, you can create pages dynamically from a variety of data sources, including Markdown or Wordpress content.

This recipe shows how to create pages from Markdown files on your local filesystem using Gatsby’s GraphQL data layer.

Prerequisites

Directions

  1. In gatsby-config.js, configure gatsby-transformer-remark along with gatsby-source-filesystem to pull in Markdown files from a source folder. This would be in addition to any previous gatsby-source-filesystem entries, such as for images:
gatsby-config.js
module.exports = {
plugins: [
`gatsby-transformer-remark`,
{
resolve: `gatsby-source-filesystem`,
options: {
name: `content`,
path: `${__dirname}/src/content`,
},
},
]
  1. Add a Markdown post to src/content, including frontmatter for the title, date, and path, with some initial content for the body of the post:
src/content/my-first-post.md
---
title: My First Post
date: 2019-07-10
path: /my-first-post
---
This is my first Gatsby post written in Markdown!
  1. Add the JavaScript code to generate pages from Markdown posts at build time with a GraphQL query in gatsby-node.js:
gatsby-node.js
const path = require(`path`)
exports.createPages = async ({ actions, graphql }) => {
const { createPage } = actions
const blogPostTemplate = path.resolve(`src/templates/post.js`)
const result = await graphql(`
{
allMarkdownRemark(
sort: { order: DESC, fields: [frontmatter___date] }
limit: 1000
) {
edges {
node {
frontmatter {
path
}
}
}
}
}
`)
if (result.errors) {
console.log(result.errors)
throw new Error("Things broke, see console output above")
}
result.data.allMarkdownRemark.edges.forEach(({ node }) => {
createPage({
path: node.frontmatter.path,
component: blogPostTemplate,
context: {}, // additional data can be passed via context
})
})
}
  1. Add a post template in src/templates, including a GraphQL query for generating pages dynamically from Markdown content at build time:
src/templates/post.js
import React from "react"
import { graphql } from "gatsby"
export default function Template({ data }) {
const { markdownRemark } = data // data.markdownRemark holds your post data
const { frontmatter, html } = markdownRemark
return (
<div className="blog-post">
<h1>{frontmatter.title}</h1>
<h2>{frontmatter.date}</h2>
<div
className="blog-post-content"
dangerouslySetInnerHTML={{ __html: html }}
/>
</div>
)
}
export const pageQuery = graphql`
query($path: String!) {
markdownRemark(frontmatter: { path: { eq: $path } }) {
html
frontmatter {
date(formatString: "MMMM DD, YYYY")
path
title
}
}
}
`
  1. Run gatsby develop to start the development server. View your post in the browser: http://localhost:8000/my-first-post

Additional resources

Creating pages from data without GraphQL

You can use the node createPages API to pull unstructured data directly into Gatsby sites rather than through GraphQL and source plugins. In this recipe, you’ll create dynamic pages from data fetched from the PokéAPI’s REST endpoints. The full example can be found on GitHub.

Prerequisites

  • A Gatsby Site with a gatsby-node.js file
  • The Gatsby CLI installed
  • The axios package installed through npm

Directions

  1. In gatsby-node.js, add the JavaScript code to fetch data from the PokéAPI and programmatically create an index page:
gatsby-node.js
const axios = require("axios")
const get = endpoint => axios.get(`https://pokeapi.co/api/v2${endpoint}`)
const getPokemonData = names =>
Promise.all(
names.map(async name => {
const { data: pokemon } = await get(`/pokemon/${name}`)
return { ...pokemon }
})
)
exports.createPages = async ({ actions: { createPage } }) => {
const allPokemon = await getPokemonData(["pikachu", "charizard", "squirtle"])
// Create a page that lists Pokémon.
createPage({
path: `/`,
component: require.resolve("./src/templates/all-pokemon.js"),
context: { allPokemon },
})
}
  1. Create a template to display Pokémon on the homepage:
src/templates/all-pokemon.js
import React from "react"
export default ({ pageContext: { allPokemon } }) => (
<div>
<h1>Behold, the Pokémon!</h1>
<ul>
{allPokemon.map(pokemon => (
<li key={pokemon.id}>
<img src={pokemon.sprites.front_default} alt={pokemon.name} />
<p>{pokemon.name}</p>
</li>
))}
</ul>
</div>
)
  1. Run gatsby develop to fetch the data, build pages, and start the development server.
  2. View your homepage in a browser: http://localhost:8000

Additional resources

Creating a layout component

It’s common to wrap pages with a React layout component, which makes it possible to share markup, styles, and functionality across multiple pages.

Prerequisites

  • A Gatsby Site

Directions

  1. Create a layout component in src/components, where child components will be passed in as props:
src/components/layout.js
import React from "react"
export default ({ children }) => (
<div style={{ margin: `0 auto`, maxWidth: 650, padding: `0 1rem` }}>
{children}
</div>
)
  1. Import and use the layout component in a page:
src/pages/index.js
import React from "react"
import Layout from "../components/layout"
export default () => (
<Layout>
<Link to="/contact/">Contact</Link>
<p>What a world.</p>
</Layout>
)

Additional resources

2. Styling with CSS

There are so many ways to add styles to your website; Gatsby supports almost every possible option, through official and community plugins.

Using Styled Components

Prerequisites

Directions

  1. Inside your gatsby-config.js file add gatsby-plugin-styled-components
gatsby-config.js
module.exports = {
plugins: [`gatsby-plugin-styled-components`],
}
  1. Open the index page component (src/pages/index.js) and import the styled-components package

  2. Style components by creating style blocks for each element type

  3. Apply to the page by including styled components in the JSX

src/pages/index.js
import React from "react"
import styled from "styled-components"
const Container = styled.div`
margin: 3rem auto;
max-width: 600px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
`
const Avatar = styled.img`
flex: 0 0 96px;
width: 96px;
height: 96px;
margin: 0;
`
const Username = styled.h2`
margin: 0 0 12px 0;
padding: 0;
`
const User = props => (
<UserWrapper>
<Avatar src={props.avatar} alt={props.username} />
<Username>{props.username}</Username>
</UserWrapper>
)
export default () => (
<Container>
<h1>About Styled Components</h1>
<p>Styled Components is cool</p>
<User
username="Jane Doe"
avatar="https://s3.amazonaws.com/uifaces/faces/twitter/adellecharles/128.jpg"
/>
<User
username="Bob Smith"
avatar="https://s3.amazonaws.com/uifaces/faces/twitter/vladarbatov/128.jpg"
/>
</Container>
)
  1. Run gatsby develop to see the changes

Adding a Local Font

Prerequisites

Directions

  1. Copy a font file into your Gatsby project, such as src/fonts/fontname.woff2.
src/fonts/fontname.woff2
  1. Import the font asset into a CSS file to bundle it into your Gatsby site:
src/css/typography.css
@font-face {
font-family: "Font Name";
src: url("../fonts/fontname.woff2");
}

Note: Make sure the font name is referenced from the relevant CSS, e.g.:

src/components/layout.css
body {
font-family: "Font Name", sans-serif;
}

By targeting the HTML body element, your font will apply to most text on the page. Additional CSS can target other elements, such as button or textarea.

Additional resources

Using Google Fonts

Hosting your own Google fonts locally within a project means they won’t have to be fetched over the network when your site loads, increasing your site’s speed index by up to ~300 milliseconds on desktop and 1+ seconds on 3G. It’s also recommended to limit custom font usage to only the essential for performance.

Prerequisites

Directions

  1. Run npm install --save yourchosenfont, replacing yourchosenfont with the name of the font you want to install from the typefaces project.

  2. Add import "yourchosenfont" to a layout template, page component, or gatsby-browser.js.

src/components/layout.js
import "yourchosenfont"
  1. Once it’s imported, you can reference the font name in a CSS stylesheet, CSS module, or CSS-in-JS.
src/components/layout.css
body {
font-family: yourchosenfont;
}

Additional Resources

3. Working with starters

Starters are boilerplate Gatsby sites maintained officially, or by the community.

Using a starter

Prerequisites

Directions

  1. Find the starter you’d like to use. (The Starter Library is a good place to look!)

  2. Generate a new site based on the starter. In the terminal, run:

gatsby new {your-project-name} {link-to-starter}

Don’t run the above command as-is — remember to replace {your-project-name} and {link-to-starter}!

  1. Run your new site:
cd {your-project-name}
gatsby develop

Additional resources

4. Working with themes

A Gatsby theme abstracts Gatsby configuration (shared functionality, data sourcing, design) into an installable package. This means that the configuration and functionality isn’t directly written into your project, but rather versioned, centrally managed, and installed as a dependency. You can seamlessly update a theme, compose themes together, and even swap out one compatible theme for another.

Creating a new site using a theme starter

Creating a site based on a starter that configures a theme follows the same process as creating a site based on a starter that doesn’t configure a theme. In this example we’ll use the starter for creating a new site that uses the official Gatsby blog theme.

Prerequisites

Directions

  1. Generate a new site based on the blog theme starter:
gatsby new {your-project-name} https://github.com/gatsbyjs/gatsby-starter-blog-theme
  1. Run your new site:
cd {your-project-name}
gatsby develop

Additional resources

Building a new theme

Video hosted on egghead.io.

Prerequisites

Directions

  1. Generate a new theme workspace using the Gatsby theme workspace starter:
gatsby new {your-project-name} https://github.com/gatsbyjs/gatsby-starter-theme-workspace
  1. Run the example site in the workspace:
yarn workspace example develop

Additional resources

5. Sourcing data

Data sourcing in Gatsby is plugin-driven; Source plugins fetch data from their source (e.g. the gatsby-source-filesystem plugin fetches data from the file system, the gatsby-source-wordpress plugin fetches data from the WordPress API, etc). You can also source the data yourself.

Creating source nodes

Directions

  1. In gatsby-node.js use sourceNodes() and actions.createNode() to create and export nodes to be able to query the data.
gatsby-node.js
exports.sourceNodes = ({ actions, createNodeId, createContentDigest }) => {
const pokemons = [
{ name: "Pikachu", type: "electric" },
{ name: "Squirtle", type: "water" },
]
pokemons.forEach(pokemon => {
const node = {
name: pokemon.name,
type: pokemon.type,
id: createNodeId(`Pokemon-${pokemon.name}`),
internal: {
type: "Pokemon",
contentDigest: createContentDigest(pokemon),
},
}
actions.createNode(node)
})
}
  1. Run gatsby develop.

    Note: After making changes in gatsby-node.js you need to re-run gatsby develop for the changes to take effect.

  2. Query the data (in GraphiQL or in your components).

query MyPokemonQuery {
allPokemon {
nodes {
name
type
id
}
}
}

Additional resources

6. Querying data

Using a Page Query

You can use the graphql tag to query data in the pages of your Gatsby site. This gives you access to anything included in Gatsby’s data layer, such as site metadata, source plugins, images, and more.

Deploying to Netlify

Use netlify-cli to deploy your Gatsby application without leaving the command line interface.

Prerequisites

Directions

  1. Build your gatsby application using gatsby build

  2. Login into netlify using netlify login

  3. Run the command netlify build. Select the “Create & configure a new site” option.

  4. Choose a custom website name if you want or press enter to receive a random one.

  5. Choose your Team.

  6. Change the deploy path to public/

  7. Make sure that everything looks fine before deploying to production using netlify deploy --prod

Additional resources

Querying data

Directions

  1. Import graphql from gatsby.

  2. Export a constant named query and set its value to be a graphql template with the query between two backticks.

  3. Pass in data as a prop to the component.

  4. The data variable holds the queried data and can be referenced in JSX to output HTML.

src/pages/index.js
import React from "react"
import { graphql } from "gatsby"
import Layout from "../components/layout"
export const query = graphql`
query HomePageQuery {
site {
siteMetadata {
title
}
}
}
`
const IndexPage = ({ data }) => (
<Layout>
<h1>{data.site.siteMetadata.title}</h1>
</Layout>
)
export default IndexPage

Additional resources

The StaticQuery Component

StaticQuery is a component for retrieving data from Gatsby’s data layer in non-page components, such as a header, navigation, or any other child component.

Directions

  1. The StaticQuery Component requires two render props: query and render.
src/components/NonPageComponent.js
import React from "react"
import { StaticQuery, graphql } from "gatsby"
const NonPageComponent = () => (
<StaticQuery
query={graphql`
query NonPageQuery {
site {
siteMetadata {
title
}
}
}
`}
render={(
data
) => (
<h1>
Querying title from NonPageComponent with StaticQuery:
{data.site.siteMetadata.title}
</h1>
)}
/>
)
export default NonPageComponent
  1. You can now use this component as you would any other component by importing it into a larger page of JSX components and HTML markup.

Querying data with the useStaticQuery hook

Since Gatsby v2.1.0, you can use the useStaticQuery hook to query data with a JavaScript function instead of a component. The syntax removes the need for a <StaticQuery> component to wrap everything, which some people find simpler to write.

The useStaticQuery hook takes a GraphQL query and returns the requested data. It can be stored in a variable and used later in your JSX templates.

Prerequisites

  • You’ll need React and ReactDOM 16.8.0 or later (keeping Gatsby updated handles this)
  • Recommended reading: the Rules of React Hooks

Directions

  1. Import useStaticQuery and graphql from gatsby in order to use the hook query the data.

  2. In the start of a stateless functional component, assign a variable to the value of useStaticQuery with your graphql query passed as an argument.

  3. In the JSX code returned from your component, you can reference that variable to handle the returned data.

src/components/NonPageComponent.js
import React from "react"
import { useStaticQuery, graphql } from "gatsby"
const NonPageComponent = () => {
const data = useStaticQuery(graphql`
query NonPageQuery {
site {
siteMetadata {
title
}
}
}
`)
return (
<h1>
Querying title from NonPageComponent: {data.site.siteMetadata.title}{" "}
</h1>
)
}
export default NonPageComponent

Additional resources

Limiting with GraphQL

When querying for data with GraphQL, you can limit the number of results returned with a specific number. This is helpful if you only need a few pieces of data or need to paginate data.

To limit data, you’ll need a Gatsby site with some nodes in the GraphQL data layer. All sites have some nodes like allSitePage and sitePage created automatically: more can be added by installing source plugins like gatsby-source-filesystem in gatsby-config.js.

Prerequisites

Directions

  1. Run gatsby develop to start the development server.
  2. Open a tab in your browser at: http://localhost:8000/___graphql.
  3. Add a query in the editor with the following fields on allSitePage to start off:
{
allSitePage {
edges {
node {
id
path
}
}
}
}
  1. Add a limit argument to the allSitePage field and give it an integer value 3.
{
allSitePage(limit: 3) {
edges {
node {
id
path
}
}
}
}
  1. Click the play button in the GraphiQL page and the data in the edges field will be limited to the number specified.

Additional resources

Sorting with GraphQL

The ordering of your results can be specified with the GraphQL sort argument. You can specify which fields to sort by and the order to sort in.

For this recipe, you’ll need a Gatsby site with a collection of nodes to sort in the GraphQL data layer. All sites have some nodes like allSitePage created automatically: more can be added by installing source plugins.

Prerequisites

  • A Gatsby site
  • Queryable fields prefixed with all, e.g. allSitePage

Directions

  1. Run gatsby develop to start the development server.
  2. Open the GraphiQL explorer in a browser tab at: http://localhost:8000/___graphql
  3. Add a query in the editor with the following fields on allSitePage to start off:
{
allSitePage {
edges {
node {
id
path
}
}
}
}
  1. Add a sort argument to the allSitePage field and give it an object with the fields and order attributes. The value for fields can be a field or an array of fields to sort by (this example uses the path field), the order can be either ASC or DESC for ascending and descending respectively.
{
allSitePage(sort: {fields: path, order: ASC}) {
edges {
node {
id
path
}
}
}
}
  1. Click the play button in the GraphiQL page and the data returned will be sorted ascending by the path field.

Additional resources

Filtering with GraphQL

Queried results can be filtered down with operators like eq (equals), ne (not equals), in, and regex on specified fields.

For this recipe, you’ll need a Gatsby site with a collection of nodes to filter in the GraphQL data layer. All sites have some nodes like allSitePage created automatically: more can be added by installing source and transformer plugins like gatsby-source-filesystem and gatsby-transformer-remark in gatsby-config.js to produce allMarkdownRemark.

Prerequisites

  • A Gatsby site
  • Queryable fields prefixed with all, e.g. allSitePage or allMarkdownRemark

Directions

  1. Run gatsby develop to start the development server.
  2. Open the GraphiQL explorer in a browser tab at: http://localhost:8000/___graphql
  3. Add a query in the editor using a field prefixed by ‘all’, like allMarkdownRemark (meaning that it will return a list of nodes)
{
allMarkdownRemark {
edges {
node {
frontmatter {
title
categories
}
}
}
}
}
  1. Add a filter argument to the allMarkdownRemark field and give it an object with the fields you’d like to filter by. In this example, Markdown content is filtered by the categories attribute in frontmatter metadata. The next value is the operator: in this case eq, or equals, with a value of ‘magical creatures’.
{
allMarkdownRemark(filter: {frontmatter: {categories: {eq: "magical creatures"}}}) {
edges {
node {
frontmatter {
title
categories
}
}
}
}
}
  1. Click the play button in the GraphiQL page. The data that matches the filter parameters should be returned, in this case only sourced Markdown files tagged with a category of ‘magical creatures’.

Additional resources

GraphQL Query Aliases

You can rename any field in a GraphQL query with an alias.

If you would like to run two queries on the same datasource, you can use an alias to avoid a naming collision with two queries of the same name.

Directions

  1. Run gatsby develop to start the development server.
  2. Open the GraphiQL explorer in a browser tab at: http://localhost:8000/___graphql
  3. Add a query in the editor using two fields of the same name like allFile
{
allFile {
totalCount
}
allFile {
pageInfo {
currentPage
}
}
}
  1. Add the name you would like to use for any field before the name of the field in your GraphQL schema, separated by a colon. (E.g. [alias-name]: [original-name])
{
fileCount: allFile {
totalCount
}
filePageInfo: allFile {
pageInfo {
currentPage
}
}
}
  1. Click the play button in the GraphiQL page and 2 objects with alias names you provided should be output.

Additional resources

GraphQL Query Fragments

GraphQL fragments are shareable chunks of a query that can be reused.

You might want to use them to share multiple fields between queries or to colocate a component with the data it uses.

Directions

  1. Declare a graphql template string with a Fragment in it. The fragment should be made up of the keyword fragment, a name, the GraphQL type it is associated with (in this case of type Site, as demonstrated by on Site), and the fields that make up the fragment:
export const query = graphql`
fragment SiteInformation on Site {
title
description
}
`
  1. Now, include the fragment in a query for a field of the type specified by the fragment. This includes those fields without having to declare them all independently:
export const pageQuery = graphql`
query SiteQuery {
site {
- title
- description
+ ...SiteInformation
}
}
`

Note: Fragments don’t need to be imported in Gatsby. Exporting a query with a Fragment makes that Fragment available in all queries in your project.

Fragments can be nested inside other fragments, and multiple fragments can be used in the same query.

Additional Resources

7. Working with images

Import an image into a component with webpack

Images can be imported right into a JavaScript module with webpack. This process automatically minifies and copies the image to your site’s public folder, providing a dynamic image URL for you to pass to an HTML <img> element like a regular file path.

Prerequisites

  • A Gatsby Site with a .js file exporting a React component
  • an image (.jpg, .png, .gif, .svg, etc.) in the src folder

Directions

  1. Import your file from its path in the src folder:
src/pages/index.js
import React from "react"
// Tell webpack this JS file uses this image
import FiestaImg from "../assets/fiesta.jpg"
  1. In index.js, add an <img> tag with the src as the name of the import you used from webpack (in this case FiestaImg), and add an alt attribute describing the image:
src/pages/index.js
import React from "react"
import FiestaImg from "../assets/fiesta.jpg"
export default () => (
// The import result is the URL of your image
<img src={FiestaImg} alt="A dog smiling in a party hat" />
)
  1. Run gatsby develop to start the development server.
  2. View your image in the browser: http://localhost:8000/

Additional resources

Reference an image from the static folder

As an alternative to importing assets with webpack, the static folder allows access to content that gets automatically copied into the public folder when built.

This is an escape route for specific use cases, and other methods like importing with webpack are recommended to leverage optimizations made by Gatsby.

Prerequisites

  • A Gatsby Site with a .js file exporting a React component
  • An image (.jpg, .png, .gif, .svg, etc.) in the static folder

Directions

  1. Ensure that the image is in your static folder at the root of the project. Your project structure might look something like this:
├── gatsby-config.js
├── src
│ └── pages
│ └── index.js
├── static
│ └── fiesta.jpg
  1. In index.js, add an <img> tag with the src as the relative path of the file from the static folder, and add an alt attribute describing the image:
src/pages/index.js
import React from "react"
export default () => (
<img src={`fiesta.jpg`} alt="A dog smiling in a party hat" />
)
  1. Run gatsby develop to start the development server.
  2. View your image in the browser: http://localhost:8000/

Additional resources

Optimizing and querying local images with gatsby-image

The gatsby-image plugin can relieve much of the pain associated with optimizing images in your site.

Gatsby will generate optimized resources which can be queried with GraphQL and passed into Gatsby’s image component. This takes care of the heavy lifting including creating several image sizes and loading them at the right time.

Prerequisites

  • The gatsby-image, gatsby-transformer-sharp, and gatsby-plugin-sharp packages installed and added to the plugins array in gatsby-config
  • Images sourced in your gatsby-config using a plugin like gatsby-source-filesystem

Directions

  1. First, import Img from gatsby-image, as well as graphql and useStaticQuery from gatsby
import { useStaticQuery, graphql } from "gatsby" // to query for image data
import Img from "gatsby-image" // to take image data and render it
  1. Write a query to get image data, and pass the data into the <Img /> component:

Choose any of the following options or a combination of them.

a. a single image queried by its file path (Example: images/corgi.jpg)

const data = useStaticQuery(graphql`
query {
file(relativePath: { eq: "corgi.jpg" }) {
childImageSharp {
fluid {
base64
aspectRatio
src
srcSet
sizes
}
}
}
}
`)
return (
<Img fluid={data.file.childImageSharp.fluid} alt="A corgi smiling happily" />
)

b. using a GraphQL fragment, to query for the necessary fields more tersely

const data = useStaticQuery(graphql`
query {
file(relativePath: { eq: "corgi.jpg" }) {
childImageSharp {
fluid {
...GatsbyImageSharpFluid
}
}
}
}
`)
return (
<Img fluid={data.file.childImageSharp.fluid} alt="A corgi smiling happily" />
)

c. several images from a directory (Example: images/dogs) filtered by the extension and relativeDirectory fields, and then mapped into Img components

const data = useStaticQuery(graphql`
query {
allFile(
filter: {
extension: { regex: "/(jpg)|(png)|(jpeg)/" }
relativeDirectory: { eq: "dogs" }
}
) {
edges {
node {
base
childImageSharp {
fluid {
...GatsbyImageSharpFluid
}
}
}
}
}
}
`)
return (
<div>
{data.allFile.edges.map(image => (
<Img
fluid={image.node.childImageSharp.fluid}
alt={image.node.base.split(".")[0]} // only use section of the file extension with the filename
/>
))}
</div>
)

Note: This method can make it difficult to match images with alt text for accessibility. This example uses images with alt text included in the filename, like dog in a party hat.jpg.

d. an image of a fixed size using the fixed field instead of fluid

const data = useStaticQuery(graphql`
query {
file(relativePath: { eq: "corgi.jpg" }) {
childImageSharp {
fixed(width: 250, height: 250) {
...GatsbyImageSharpFixed
}
}
}
}
`)
return (
<Img fixed={data.file.childImageSharp.fixed} alt="A corgi smiling happily" />
)

e. an image of a fixed size with a maxWidth

const data = useStaticQuery(graphql`
query {
file(relativePath: { eq: "corgi.jpg" }) {
childImageSharp {
fixed(maxWidth: 250) {
...GatsbyImageSharpFixed
}
}
}
}
`)
return (
<Img fixed={data.file.childImageSharp.fixed} alt="A corgi smiling happily" />
)

f. an image filling a fluid container with a max width (in pixels) and a higher quality (the default value is 50 i.e. 50%)

const data = useStaticQuery(graphql`
query {
file(relativePath: { eq: "corgi.jpg" }) {
childImageSharp {
fluid(maxWidth: 800, quality: 75) {
...GatsbyImageSharpFluid
}
}
}
}
`)
return (
<Img fluid={data.file.childImageSharp.fluid} alt="A corgi smiling happily" />
)
  1. (Optional) Add inline styles to the <Img /> like you would to other components
<Img
fluid={data.file.childImageSharp.fluid}
alt="A corgi smiling happily"
style={{ border: "2px solid rebeccapurple", borderRadius: 5, height: 250 }}
/>
  1. (Optional) Force an image into a desired aspect ratio by overriding the aspectRatio field returned by the GraphQL query before it is passed into the <Img /> component
<Img
fluid={{
...data.file.childImageSharp.fluid,
aspectRatio: 1.6, // 1280 / 800 = 1.6
}}
alt="A corgi smiling happily"
/>
  1. Run gatsby develop, to generate images from files in the filesystem (if not done already) and cache them

Additional Resources

Optimizing and querying images in post frontmatter with gatsby-image

For use cases like a featured image in a blog post, you can still use gatsby-image. The Img component needs processed image data, which can come from a local (or remote) file, including from a URL in the frontmatter of a .md or .mdx file.

To inline images in markdown (using the ![]() syntax), consider using a plugin like gatsby-remark-images

Prerequisites

  • The gatsby-image, gatsby-transformer-sharp, and gatsby-plugin-sharp packages installed and added to the plugins array in gatsby-config
  • Images sourced in your gatsby-config using a plugin like gatsby-source-filesystem
  • Markdown files sourced in your gatsby-config with image URLs in frontmatter
  • Pages created from Markdown using createPages

Directions

  1. Verify that the Markdown file has an image URL with a valid path to an image file in your project
post.mdx
---
title: My First Post
featuredImage: ./corgi.png
---
Post content...
  1. Verify that a unique identifier (a slug in this example) is passed in context when createPages is called in gatsby-node.js, which will later be passed into a GraphQL query in the Layout component
gatsby-node.js
exports.createPages = async ({ graphql, actions }) => {
const { createPage } = actions
// query for all markdown
result.data.allMdx.edges.forEach(({ node }) => {
createPage({
path: node.fields.slug,
component: path.resolve(`./src/components/markdown-layout.js`),
context: {
slug: node.fields.slug,
},
})
})
}
  1. Now, import Img from gatsby-image, and graphql from gatsby into the template component, write a pageQuery to get image data based on the passed in slug and pass that data to the <Img /> component:
markdown-layout.jsx
import React from "react"
import { graphql } from "gatsby"
import Img from "gatsby-image"
export default ({ children, data }) => (
<main>
<Img
fluid={data.markdown.frontmatter.image.childImageSharp.fluid}
alt="A corgi smiling happily"
/>
{children}
</main>
)
export const pageQuery = graphql`
query PostQuery($slug: String) {
markdown: mdx(fields: { slug: { eq: $slug } }) {
id
frontmatter {
image {
childImageSharp {
fluid {
...GatsbyImageSharpFluid
}
}
}
}
}
}
`
  1. Run gatsby develop, which will generate images for files sourced in the filesystem

Additional Resources

8. Transforming data

Transforming data in Gatsby is plugin-driven. Transformer plugins take data fetched using source plugins, and process it into something more usable (e.g. JSON into JavaScript objects, and more). gatsby-transformer-plugin can transform Markdown files to HTML.

Prerequisites

  • A Gatsby site with gatsby-config.js and an index.js page
  • A Markdown file saved in your Gatsby site src directory
  • A source plugin installed, such as gatsby-source-filesystem
  • The gatsby-transformer-remark plugin installed

Directions

  1. Add the transformer plugin in your gatsby-config.js:
gatsby-config.js
plugins: [
// not shown: gatsby-source-filesystem for creating nodes to transform
`gatsby-transformer-remark`
],
  1. Add a GraphQL query to the index.js file of your Gatsby site to fetch MarkdownRemark nodes:
src/pages/index.js
export const query = graphql`
query {
allMarkdownRemark {
totalCount
edges {
node {
id
frontmatter {
title
date(formatString: "DD MMMM, YYYY")
}
excerpt
}
}
}
}
`
  1. Restart the development server and open GraphiQL at http://localhost:8000/___graphql. Explore the fields available on the MarkdownRemark node.

Additional resources

9. Deploying your site

Showtime. Once you are happy with your site, you are ready to go live with it!

Preparing for deployment

Prerequisites

Directions

  1. Stop your development server if it is running (Ctrl + C on your command line in most cases)

  2. For the standard site path at the root directory (/), run gatsby build using the Gatsby CLI on the command line. The built files will now be in the public folder.

gatsby build
  1. To include a site path other than / (such as /site-name/), set a path prefix by adding the following to your gatsby-config.js and replacing yourpathprefix with your desired path prefix:
gatsby-config.js
module.exports = {
pathPrefix: `/yourpathprefix`,
}

There are a few reasons to do this—for instance, hosting a blog built with Gatsby on a domain with another site not built on Gatsby. The main site would direct to example.com, and the Gatsby site with a path prefix could live at example.com/blog.

  1. With a path prefix set in gatsby-config.js, run gatsby build with the --prefix-paths flag to automatically add the prefix to the beginning of all Gatsby site URLs and <Link> tags.
gatsby build --prefix-paths
  1. Make sure that your site looks the same when running gatsby build as with gatsby develop. By running gatsby serve when you build your site, you can test out (and debug if necessary) the finished product before deploying it live.
gatsby build && gatsby serve

Additional Resources


Edit this page on GitHub
Docs
Tutorials
Plugins
Blog
Showcase