Skip to content

5starwebdesign/gatsby

Repository files navigation

Travis CI Build Status npm package gatsby channel on discord Twitter Follow

Gatsby

Transform plain text into dynamic blogs and websites using the latest web technologies. A React.js static site generator.

Supports Markdown, HTML, and React.js pages out of the box. Easy to add support for additional files types.

Leverages React Router's "nested component hierarchy" to make templating incredibly intuitive.

All templates, css, and content are hot reloadable — powered by Webpack.

Build sites like it's 1995. Files are translated into HTML pages at the same position within the file system. Add a markdown file at /docs/index.md and it'll be converted to /docs/index.html.

live-reloading example

Goals

  • No-reload page transitions
  • Hot reload editing. Tweak your pages, templates, and styles and see changes in real time.
  • Make React.js component model and ecosystem available for building static sites
  • Intuitive directory-based URLs. The URL of a page is derived from its spot on the file system.
  • Support "Starters" — install starter sites directly from Github. Use open sourced starters or build your own.

Sites built with Gatsby

Videos and blogs

Why use Gatsby instead of other Static Site Generators

  • No-refresh page transitions
  • The awesome React.js component model
  • Live editing on every part of your site. Dramatically speed development.

I'm already building a server-rendered React.js site, is Gatsby a good fit?

If your site falls closer to the site end of the app<---->site spectrum then yes.

Gatsby is an excellent fit for blogs, marketing sites, docs sites, etc. Proper web apps should probably remain as normal web apps (though I'd love to be proved wrong!).

Warning!

Gatsby is not yet stable. APIs will break. Functionality is missing. It's usable but if you plan on building with it, expect a rocky road for some time.

Contributions welcome!

Getting started

Install

npm install -g gatsby

Usage

  1. Create new Gatsby site gatsby new my-test-gatsby-site This creates the directory for your Gatsby project and adds the minimal files needed.
  2. cd my-test-gatsby-site
  3. gatsby develop — Gatsby will start a hot-reloading development server accessible at localhost:8000
  4. See the tutorial below for more.

Gatsby Starters

The Gatsby cli tool lets you install "starters". These are partially built sites preconfigured to help you get moving faster on creating a certain type of site.

When creating a new site, you can optionally specify a starter to base your new site on e.g. gatsby new [SITE_DIRECTORY] [URL_OF_STARTER]

For example, to quickly create a blog using Gatsby, you could install the Gatsby Starter Blog by running:

gatsby new blog https://github.com/gatsbyjs/gatsby-starter-blog

This downloads the files and initializes the site by running npm install

If you don't specify a custom starter, your site will created from the default starter.

There are several starters that have been created. Create a PR to include yours!

Tutorial: Building a documentation site from the Gatsby Documentation Starter

  1. Install gatsby npm install -g gatsby
  2. Install documentation site starter gatsby new docs-site gh:gatsbyjs/gatsby-starter-documentation
  3. type cd docs-site
  4. type gatsby develop
  5. Open site in browser at localhost:8000. Verify clicking on links works.
  6. Try editing the site's config file config.toml. Change the siteTitle key. The site's title should change shortly after saving.
  7. Next try editing a doc page. Open /pages/docs/getting-started/index.md and edit it. Again any saved changes should load without refreshing in the browser.
  8. Add a new markdown page to the documentation. Copy the getting-started directory to some-additional-steps. Then edit the markdown file within the new directory. If you're familiar with other static site generation software, you'll be familiar with the "frontmatter" at the top of the file. Edit the title there + change the order to "5". Save this. Ideally this new file would be hot reloaded like other changes but I haven't figured out how to make this happen yet (help appreciated here). So to see your new page, restart gatsby develop and then refresh your browser.
  9. Build your site gatsby build. The site is built to the /public directory. Test that the build worked by running gatsby serve-build which serves the contents of the /public directory.

How Gatsby works

How files become pages

The process is file --> Webpack loader --> React.js wrapper component --> static html page.

Gatsby leverages Webpack extensively. Webpack is a sophisticated module bundler that can turn any sort of file into a commonjs module. Webpack uses "Loaders" to convert a file into a module. These loaded modules are then wrapped inside a react.js component that's specific to a given file type. Gatsby then generates a static html page from this component.

Gatsby ships with default loaders and wrappers for HTML, Markdown, and JSX/CJSX but for most projects you'll want to write your own loaders and wrappers (very easy to do).

As an example of how this process works, let's walk quickly through converting a markdown file into an html page.

The default Gatsby markdown loader parses the markdown into HTML and uses Highlight.js to syntax highlight code blocks.

Our markdown file.

---
title: This is a title
---

# Hi friends.
This is a markdown file.

When loaded and required, the resulting javascript object looks like the following:

{
  file: {
    // Information about file on disk e.g. extension, directory path, etc.
  },
  data: {
    title: "This is a title",
    body: "<h1>Hi friends.</h1><p>This is a markdown file</p>"
  }
}

Now Gatsby wraps the markdown file in this very simple React.js component.

module.exports = React.createClass({
  displayName: "MarkdownWrapper",

  render: function() {
    var post = this.props.route.page.data

    return <div className="markdown">
      <h1>{post.title}</h1>
      <div dangerouslySetInnerHTML={{__html: post.body}}/>
    </div>
  }
})

Structure of a Gatsby site

  • config.toml - Core application configuration is stored here. Available via a require or import of 'config'. Values:
    • noProductionJavascript - set to a truthy value to prevent generation of bundle.js (containing your client-side Single Page App) during a gatbsy build. You'll need to update your top-level html.js file so that it doesn't pull in bundle.js in production, but you'll want to keep it for gatsby develop mode.
  • /pages - All pages go here. Everything is turned into a page except files which start with an underscore:
  • (optional) post-build.js - a function(pages, cb) you can provide to do final processing on all generated content.
  • (optional) gatsby-browser.js - a way to hook into key application events. Export onRouteChange of type function(location) to be notified whenever React-Router navigates.
  • (optional) gatsby-node.js - a way to hook into events during build and development.

How to use your own webpack loaders

Gatsby uses webpack-configurator to make changing the webpack loaders easy. The default set of loaders is organized by key.

Gatsby uses gatsby-node.js to pass control to the user before resolving the final webpack configuration. gatsby-node.js should live in the root of your project and export a function which accepts a webpack-configurator config object and an environment string. The environment string will be one of develop, static or production.

Create a gatsby-node.js in the root of your project:

exports.modifyWebpackConfig = function(config, env) {
  // edit loaders here
  return config;
}

Consider the following example which removes the default css loader and replaces it with a loader that uses css-modules.

exports.modifyWebpackConfig = function(config, env) {
  config.removeLoader('css');
  config.loader('css', function(cfg) {
    cfg.test = /\.css$/;
    cfg.loader = 'style!css?modules'
    return cfg
  })
  return config;
};

Each loader (cfg in the above example) can be a valid webpack loader and there are a host of preexisting loaders which you can use to enhance Gatsby.

It is also possible to write your own loaders.

Gatsby includes some default loaders that you can also override.

To write your own loader or override a Gatsby loader, make a loaders directory at the root of your site that contains directories for custom loaders.

e.g. loaders/markdown-loader/index.js will take precedence over the markdown-loader that Gatsby includes.

See an example of a custom loader in the default starter.

How to use your own webpack plugins

Similar to the loaders, plugins are handled via webpack-configurator and gatsby-node.js.

Note: the following example is now redundant since ExtractTextWebpackPlugin is now setup by default but you can still use it as an example of how to modify the Webpack plugins.

If we wanted to extract all of the css in our project into a since styles.css file for production, we could add the ExtractTextWebpackPlugin. To do this, we need to modify the loader and add the plugin when generating the static html for our site.

var ExtractTextPlugin = require("extract-text-webpack-plugin");

exports.modifyWebpackConfig = function(config, env) {
  if(env === 'static') {
    config.removeLoader('css');
    config.loader('css', function(cfg) {
      cfg.test = /\.css$/;
      cfg.loader = ExtractTextPlugin.extract('css?minimize');
      return cfg
    })
    config.plugin('extract-css',
                  ExtractTextPlugin,
                  ["styles.css", { allChunks: true }]);
  }
}

Each plugin (extract-css in the above example) can be a valid webpack plugin and there are a host of preexisting plugins which you can use to enhance Gatsby.

It is also possible to write your own plugins.

How to write your own wrappers

  • Coming...

FAQ

I added a new page and it's not showing up!

Webpack doesn't currently support hot-reloading new files added to a context. When you add a new file, restart the gatsby develop process and your new page will show up.

Configuring Babel

For Webpack loaded code you can't modify Babel's behavior as normal by modifying the .babelrc in your site's root directory.

Instead you'll need to modify the Webpack babel loader as described above.

Deploying to Github Pages (and other hosts where your site's links need prefixes)

Gatsby supports automatically prefixing links with its prefixLink helper function.

To use simply import the function and run all links in your site thorough it e.g.

import { prefixLink } from 'gatsby-helpers'

prefixLink('/')
// During development this will return "/"
// When deployed to example.github.io/your-project/ this will return "/your-project/"

Set the prefix in your config file e.g. linkPrefix = '/your-project'

Then finally when building your site run gatsby build --prefix-links

The built site is now in /public. These files need copied to your gh-pages branch and committed and pushed. You can do this manually or use the handy gh-pages cli tool.

Both the sample sites are deployed to github pages and use link prefixing. Read their source for more help: documentation/blog.

I have an existing site in (Wordpress|Drupal|Blogger|Tumblr|*), how do I convert it to Gatsby?

Jekyll has a comprehensive import tool for these and many other tools. Once your pages are converted to markdown, change the file extensions to .md from the .markdown the tool outputs and then use them in your site.