Gatsby playground

Published on January 11th, 2020

The more you use Gastby, the more you realize that this is more than just a static site generator: it is a full blown application server.

Bare bone Gatsby installation

For instance, you can install a bare bone version of Gatsby, without any starter, without any theme and not even any content:

$ mkdir gatsby-playground
$ cd gatsby-playground
$ yarn init -y
$ yarn add gatsby react react-dom

Then you edit your package.json file to add the scripts to start Gatsby:

{
  "name": "gatsby-playground",
  "version": "1.0.0",
  "main": "index.js",
  "license": "MIT",
  "scripts": {
    "build": "gatsby build",
    "clean": "gatsby clean",
    "develop": "gatsby develop"
  },
  "dependencies": {
    "gatsby": "^2.18.21",
    "react": "^16.12.0",
    "react-dom": "^16.12.0"
  }
}  

and even though this directory is empty of any Gatsby specific file:

$ ls -l
total 856
drwxr-xr-x  999 pcarion  staff   31968 Jan 11 15:20 node_modules
-rw-r--r--    1 pcarion  staff     312 Jan 11 15:20 package.json
drwxr-xr-x    5 pcarion  staff     160 Jan 11 15:20 public
-rw-r--r--    1 pcarion  staff  431798 Jan 11 15:20 yarn.lock

You can still start Gatsby:

yarn run develop
yarn run v1.21.1
$ gatsby develop
success open and validate gatsby-configs - 0.013s
success load plugins - 0.045s
success onPreInit - 0.002s
success initialize cache - 0.010s
success copy gatsby files - 0.054s
success onPreBootstrap - 0.009s
success createSchemaCustomization - 0.002s
success source and transform nodes - 0.034s
success building schema - 0.163s
success createPages - 0.002s
success createPagesStatefully - 0.038s
success onPreExtractQueries - 0.002s
success update schema - 0.030s
success extract queries from components - 0.078s
success write out requires - 0.009s
success write out redirect data - 0.002s
success onPostBootstrap - 0.002s
⠀
info bootstrap finished - 3.721 s
⠀
success run queries - 0.041s - 1/1 24.26/s
⠀
You can now view gatsby-playground in the browser.
⠀
  http://localhost:8000/
⠀
View GraphiQL, an in-browser IDE, to explore your site's data and schema
⠀
  http://localhost:8000/___graphql
⠀
Note that the development build is not optimized.
To create a production build, use gatsby build
⠀
success Building development bundle - 2.612s
success Re-building development bundle - 0.046s

As expected, the Gatsby rendered site, at the URL http://localhost:8000/ is kind of empty:

The GraphiQL explorer

The interesting part is with the GraphiQL explorer at http://localhost:8000/___graphql

You see that Gatsby has already a GraphQL server ready to return some data, like the time at which the site was started (buildTime).

The GraphiQL explorer is the perfect tool to have a sneak peek in the internal data structure of Gatsby.

For instance, you can see the files being generated by Gatsby through the allSitePage root:

query MyQuery {
  allSitePage {
    edges {
      node {
        componentPath
        path
        pluginCreator {
          name
        }
      }
    }
  }
}

and you can see that it only generated the 404 page and that this page was generated by a plugin called dev-404-page:

{
  "data": {
    "allSitePage": {
      "edges": [
        {
          "node": {
            "componentPath": ".../gatsby-playground/.cache/dev-404-page.js",
            "path": "/dev-404-page/",
            "pluginCreator": {
              "name": "dev-404-page"
            }
          }
        }
      ]
    }
  }
} 

Gatsby plugins

Talking about plugins, you also have a quick access to the list of plugins:

query MyQuery {
  allSitePlugin {
    edges {
      node {
        name
      }
    }
  }
}

and you see that there are already quite a few of them:

{
  "data": {
    "allSitePlugin": {
      "edges": [
        {
          "node": {
            "name": "dev-404-page"
          }
        },
        {
          "node": {
            "name": "load-babel-config"
          }
        },
        {
          "node": {
            "name": "internal-data-bridge"
          }
        },
        {
          "node": {
            "name": "prod-404"
          }
        },
        {
          "node": {
            "name": "webpack-theme-component-shadowing"
          }
        },
        {
          "node": {
            "name": "gatsby-plugin-page-creator"
          }
        },
        {
          "node": {
            "name": "gatsby-plugin-page-creator"
          }
        },
        {
          "node": {
            "name": "gatsby-plugin-page-creator"
          }
        },
        {
          "node": {
            "name": "gatsby-plugin-page-creator"
          }
        },
        {
          "node": {
            "name": "gatsby-plugin-page-creator"
          }
        },
        {
          "node": {
            "name": "default-site-plugin"
          }
        },
        {
          "node": {
            "name": "gatsby-plugin-page-creator"
          }
        }
      ]
    }
  }
}

The plugins are the mechanism by which you can extend Gatsby to either add new static pages or add a single page application to the generated site.

You may notice that the gatsby-plugin-page-creator appear multiple times, but it is instantiated with different options.

That's again something you can explore with GraphQL:

query MyQuery {
  allSitePlugin(filter: {name: {eq: "gatsby-plugin-page-creator"}}) {
    edges {
      node {
        name
        pluginOptions {
          path
        }
      }
    }
  }
}

that tells you where this plugin is looking to generate static pages:

{
  "data": {
    "allSitePlugin": {
      "edges": [
        {
          "node": {
            "name": "gatsby-plugin-page-creator",
            "pluginOptions": {
              "path": ".../gatsby-playground/node_modules/gatsby/dist/internal-plugins/dev-404-page/src/pages"
            }
          }
        },
        {
          "node": {
            "name": "gatsby-plugin-page-creator",
            "pluginOptions": {
              "path": ".../gatsby-playground/node_modules/gatsby/dist/internal-plugins/load-babel-config/src/pages"
            }
          }
        },
        {
          "node": {
            "name": "gatsby-plugin-page-creator",
            "pluginOptions": {
              "path": ".../gatsby-playground/node_modules/gatsby/dist/internal-plugins/internal-data-bridge/src/pages"
            }
          }
        },
        {
          "node": {
            "name": "gatsby-plugin-page-creator",
            "pluginOptions": {
              "path": ".../gatsby-playground/node_modules/gatsby/dist/internal-plugins/prod-404/src/pages"
            }
          }
        },
        {
          "node": {
            "name": "gatsby-plugin-page-creator",
            "pluginOptions": {
              "path": ".../gatsby-playground/node_modules/gatsby/dist/internal-plugins/webpack-theme-component-shadowing/src/pages"
            }
          }
        },
        {
          "node": {
            "name": "gatsby-plugin-page-creator",
            "pluginOptions": {
              "path": ".../gatsby-playground/src/pages"
            }
          }
        }
      ]
    }
  }
}

The most important directory being the last one: this is where you can start writing your first page!

Gatsby-config file

You can add you configure the plugins you want to run with Gatsby in a gatsby-config.js file.

This file allows you also to provide some meta information about your site like, for example:

module.exports = {
  siteMetadata: {
    title: 'Pierre Carion',
    description: 'because the world needs another one of those blogs.',
    meaningOfTheUniverse: 42,
  },
  plugins: [],
};

If you restart your server, the GraphiQL explorer will show that there is now a new siteMetaData property available in the Site root.

As usual, you can retrieve the data using GraphQL:

query MyQuery {
  site {
    siteMetadata {
      meaningOfTheUniverse
      description
      title
    }
  }
}

Et voilà:

{
  "data": {
    "site": {
      "siteMetadata": {
        "meaningOfTheUniverse": 42,
        "description": "because the world needs another one of those blogs.",
        "title": "Pierre Carion"
      }
    }
  }
}