Prehistory
At the dawn of Web when every page markup consisted of tables, ids have been used for styling and smooth dropdown programming takes many hours... When jQuery came in dreams to bearded old men... in those time we had only one way of sites making.
Then due to natural evolution jQuery was made to simplify development process and that was first step for transformation from classic approach to only Javascript using within development. And yes, first successful applications have been based on jQuery. Before ECMAScript 2015 or ES6 as it calls using native Javascript was too long and too expensive respectively.
The first framework [Angular] for SPA was made by Google in 2010, October 20, then was breakpoint of Web development transformation. Followed by Google, the next giant in IT branch Facebook released React.js in 2013, May 29 and has started huge PR company to promote own product and illuminating all Angular disanvantages. Angular.js has lost and when Google present Angular 2, Facebook with their React were far ahead. While Google competed with Facebook web developers received a gift from China in the form of Vue.js with advantages of both Angular and React and lower threshold of entry unlike previous two but that's another story...
One of the most important disadvantages of SPA that's content rendering by Javascript after HTML is loaded. That's doesn't let SEO crawlers parse page correctly and read all required data for analysing and ranking in search output.
That issue has been resolved in two ways:
- SSR (Server Side Render)
- SSG (Static Sites Generators)
SSR provided by libraries (Next.js, Nuxt.js etc.) based on one of the existing frameworks / libraries (React.js, Vue.js etc.), working with it directly and generates static files for SEO crawlers dynamically. That approach pays off when content updating a lot and often, otherwise it's redundant.
SSG is most easy way to get static content based on HTML, CSS and pure Javascript on output from source based on different platforms (Gatsby.js [React.js], Hugo, Jekyll etc.)
What is Gatsby.js and with what it's eaten
Gatsby.js is Open Source static sites generator based on React.js and GraphQL under webpack management.
Another words Gatsby.js provides generating from source: React + SCSS + ... to well known HTML, CSS and Javascript.
Gatsby.js has restrictions solved with a lot of plugins for different taste from Typescript, PostCSS and Markdown files reader until SEO and headless CMS connection. All plugins could be found in Gatsby Plugins List
How to start with Gatsby.js
Gatsby.js using requires few additional tools:
- Node.js
- Git
- IDE: VS Code, Sublime Text or similar
Then install Gatsby CLI (Comand Line Interface) to manage Gatsby.js application from terminal
npm install -g gatsby-cli
To check it's istalled successfull, run
gatsby --help
as result you'll see
First Gatsby.js project installation and run
To install first Gatsby.js project run
npm init gatsby
Follow the instructions to let Gatsby.js be as comfortable for future development as possible. Then go to installed Gatsby.js project
cd my-gatsby-project
and start development build of your first project
npm run develop
After development build has been finished main project will be accessible by the address: http://localhost:8000
and GraphQL builder for current project by the adress: http://localhost:8000/___graphql
Recommended Gatsby.js project structure
|-- /.cache
|-- /plugins
|-- /public
|-- /src
|-- /assets
|-- /images
|-- /sass
|-- /static
|-- /components
|-- /layouts
|-- /pages
|-- /templates
|-- gatsby-config.js
|-- gatsby-node.js
|-- gatsby-ssr.js
|-- gatsby-browser.js
Configuration files
Gatsby.js is flexible and powerful if it using correct. Extension, rendering, client side observing are configurable parts of Gatsby.js
gatsby-config.js
Regular using of that file are plugins connection and setting site meta data as site author, site name etc.
More Gatsby Config API with examples could be found in documentation
Example below demonstrates base condig with site metadata and few connected plugins.
module.exports = {
siteMetadata: {
title: `My site`,
description: `Description of my site`,
author: `Selfish Me`,
...
},
plugins: [
`gatsby-plugin-react-helmet`,
`gatsby-plugin-image`,
{
resolve: `gatsby-plugin-sass`,
options: {
implementation: require("node-sass"),
},
},
...
]
}
gatsby-node.js
That file provides access to Gatsby’s Node.js APIs for customizing and extending default settings affecting the build process.
More Gatsby Config API with examples could be found in documentation
Example below demonstrates page building from template dynamically.
exports.createPages = async ({ graphql, actions }) => {
const casesPages = await graphql(`
query {
allMarkdownRemark(filter: { fileAbsolutePath: { regex: "/(cases)/" } }) {
nodes {
frontmatter {
slug
title
}
}
}
}
`)
const cases = casesPages.data.allMarkdownRemark.nodes.map(node => {
return { slug: node.frontmatter.slug, title: node.frontmatter.title }
})
casesPages.data.allMarkdownRemark.nodes.forEach(node => {
const { slug } = node.frontmatter
if (!slug) return
const index = cases.findIndex(item => item.slug === slug)
const linksData = {
prev: index - 1 >= 0 ? cases[index - 1] : cases[cases.length - 1],
next: index + 1 < cases.length ? cases[index + 1] : cases[0],
}
actions.createPage({
path: `/cases/${slug}`,
component: path.resolve(__dirname, "./src/templates/case.tsx"),
context: {
slug,
linksData,
screenshots: `/assets/images/cases/${slug}/screenshots/`,
},
})
})
gatsby-browser.js
That file lets respond to Gatsby-specific events within the browser. Gatsby Browser API gives many options for interzcting with the client side of Gatsby.js
More Gatsby Browser API with examples could be found in documentation
gatsby-ssr.js
That file lets set new conditions of page(s) rendering with embeed hooks.
More Gatsby Browser API with examples could be found in documentation
Example below from official documentation demonstrates setting new class to body tag within onRenderBody hook.
exports.onRenderBody = ({ setBodyAttributes }, pluginOptions) => {
setBodyAttributes({
className: "my-body-class",
})
}