Is this really that great to build a site with GatsbyJS?

Dmytro Chumak
Dmytro Chumak
9 min read

After months of struggling I am excited to announce my site built using GatsbyJS. I had an amazing journey with this framework and I invite you to read my story.

TL;DR

This article will be useful for those who consider using GatsbyJS to build a site. Although, Gatsby has a lot of advantages and awesome features, bad things happen too.

Is GatsbyJS really that great to build a site?

Well, let's read the main slogan of GatsbyJS:

... framework based on React that helps developers build blazing fast websites and apps.

Sounds promising, but WDTM in details?

GatsbyJS is a static site generator. It performs pre-build and returns static files (html, css, js) as a result. This means that backend do server-side job once on build stage (besides cases when client in browser asks API). Because of this, TTFB cannot be badly affected by server-side calculations on each GET request.

Despite the fact that TTFB of static files is fast, consider the next:

  • Correct nginx web server configuration can speed up a static files serving.
  • CDNs (CloudFlare, CloudFront) can also be helpful to improve TTFB.

Stop talking, prove it!

Moving from theory to the real world let's check Lighthouse report of webman.pro:

lighthouse audit webman.pro

Awesome, isn't it? Looking at Lighthouse audit I can define GatsbyJS framework as a tool that satisfied most of my needs.

Good Bad GatsbyJS

However, I want to show you not only the result, but what has been going on behind the scene. I would like to highlight my good and bad experience with gatsby.js.

Documentation

Good

I really appreciate author's work and documentation they brought. Although there is a ton of information in the docs, it's really easy to get up with the project.

Community

Good

GatsbyJS has a really big community (over 2,400 contributors). It helps GatsbyJS to grow at the speed of light. The most popular channels to join the community:

CLI

Good

GatsbyJS command line is a full-featured tool:

gatsby develop Start development server. Watches files, rebuilds, and hot reloads if something changes
gatsby build Build a Gatsby project.
gatsby serve Serve previously built Gatsby site.
gatsby info Get environment information for debugging and issue reporting
gatsby clean Wipe the local gatsby environment including built assets and cache
gatsby repl Get a node repl with context of Gatsby environment, see (https://www.gatsbyjs.org/docs/gatsby-repl/)
gatsby new [rootPath] [starter] Create new Gatsby project.
gatsby plugin Useful commands relating to Gatsby plugins
gatsby telemetry Enable or disable Gatsby anonymous analytics collection.

I should allocate gatsby new among other features. It allows to initiate a project using specific boilerplate - really helpful.

Full control

I was really exited about the fact that framework gives full control over the application. In short, you can customize:

  • Core HTML template by adding html.js to ./src folder
  • Site's configuration using gatsby-config.js
  • I used gatsby-browser.js to add some components needed to be rendered only in a browser, to import global CSS and JS
  • In root gatsby-ssr.js file you can specify stuff for server side rendering
  • gatsby-node.js is intended to control your GraphQL site's data It's possible to create a custom GraphQL field or resolver

GraphQL and GatsbyJS

Good

GatsbyJS is about GraphQL all over the place. You can:

Bad

First issue I found touches:

Both features are missed in framework core. But because GraphQL in GatsbyJS runs only in build time and needs only to query all data sources to pre-build page, this gives a reason why they did not implement this.

But what if you still need Mutation or Subscription features? The most popular suggestion is to integrate Apollo. Check this issue for more details.

The second ugly issue I was faced with was the variables limitations. Let's look at an example:

As a developer who respects DRY I wanted to create reusable <Image name="avatar.jpg" /> component using <StaticQuery />:

const imageQuery = graphql`
query Image {
// highlight-next-line
fileName: file(relativePath: { eq: "images/avatar.jpg" }) {
childImageSharp {
fluid(maxWidth: 400, maxHeight: 250) {
...GatsbyImageSharpFluid
}
}
}
}
export default props => (
<StaticQuery
query={imageQuery}
render={data => <Img fluid={data.fileName.childImageSharp.fluid} />}
/>

As you can see I had to replace "images/avatar.jpg" by variable, that’s it. I did not even realise that it is impossible with <StaticQuery /> in GatsbyJS v2:

export interface StaticQueryProps<T = any> {
query: any;
render?: RenderCallback<T>;
children?: RenderCallback<T>;
}

First question: why does not such a popular framework have it? Check the discussion about this issue to get more insight.

An interesting solution that can solve the issue is a new feature called "useQuery". Unfortunately, it is work in progress, but looks promising.

Is it possible to pass variables into query in GatsbyJS at all?

Yes, but only for page level query. For example, to generate pages based on a template you can add custom createPages function in gatsby-node.js:

exports.createPages = async function ({ actions, graphql }) {
const { data } = await graphql(`
query {
allMarkdownRemark {
edges {
node {
fields {
slug
}
}
}
}
}
`);
data.allMarkdownRemark.edges.forEach((edge) => {
const { slug } = edge.node.fields;
actions.createPage({
path: slug,
component: require.resolve(`./src/templates/blog-post.js`),
// highlight-next-line
context: { slug },
});
});
};

In this example I put slug as variable using context prop. Then in blog-post.js you can define query which has access to context variables:

export const query = graphql`
query($slug: String!) {
...
}
`;

The second possibility is to define variable accessible by any page query. Declare onCreatePage function in gatsby-node.js for that:

exports.onCreatePage = ({ page, actions }) => {
const { createPage, deletePage } = actions;
deletePage(page);
createPage({
...page,
context: {
...page.context,
id: 1,
},
});
};

Now, a page query can consume id as a variable:

export const query = graphql`
query($id: Int!) {
...
}
`;

Plugins

Good

I really love an idea to split core functionality and features. GatsbyJS follows this concept by delivering plugins library. All official plugins are parts of github repo and maintained by authors. It gives more confidence about packages quality.

Before you decide to implement any functionality by yourself, check the plugins library.

Bad

I saw badly documented plugins, some of them have functional limitations.

Security in Gatsby

Good

Site build with GatsbyJS is secure.

To be honest, I heard that from few of my colleagues and I was curious why they thought so. I strongly believe that sooner or later everything can be hacked. It does not matter if we deal with static or dynamic site.

Well, what really can be secured with GatsbyJS is:

  • Maybe DDoS attacks (e.g. setup CloudFlare with DDoS Mitigation)
  • Database attacks
  • CMS attacks
  • API attacks

It makes no sense to expose services used only for pre-build stage for outside world. That is why hackers have problem with finding and attacking any of your services.

Bad

We can be sure that potential security risk of static site is low, but it still exists. We cannot predict what hackers are going to do. If you wonder how many options they have just look at "OWASP top 10".

Let's consider few examples:
  1. Imagine that you have search input on site. Such input calls API. In its turn, API service communicates with MYSQL Database. Potential hacker can be interested to do a SQL injection attack. To prevent this attack you should provide an input sanitization on backend/frontend to prevent this attack. Gatsby has nothing to do with it.

  2. Hacker got info that your site uses GatsbyJS (it's not too hard). It gives him already a lot, because he can search for vulnerabilities Gatsby.js packages have.

More about Gatsby and security

Typescript

Some developers have mixed filings about Typescript. I don't want to assure you of using it, but for those who know the power of TS I am going to say the following:

Good

Gatsby supports Typescript! Now, plugins library contains two plugins:

I use gatsby-plugin-typescript. It sounds more reasonable to me to use plugin recommended and supported by GatsbyJS team. Moreover, it is used by thousands of people, so all bugs can be discovered and fixed faster.

Bad

First of all, gatsby-plugin-typescript does not cover API files such as gatsby-config, gatsby-node etc. Possible fix:

babel-node --presets @babel/preset-typescript --extensions '.ts,.tsx' gatsby develop

Also, it does not do type checking - details. The lack of this feature can cost a lot. Possible fixes:

Comments system

The main reason why there are no comments on my site is that I have no time for administrating. But for those who has time and needs this feature, the following info might be useful:

Good

There are a lot of options how to setup comments on site.

Bad

Most of solutions are based on embedding technique which can cause some issues:

  • Customization
  • No SSR (not SEO-friendly)
  • Page loading can be dramatically slow
  • GDPR (some privacy implications, because of storing some data by plugin)

If I could chose, the only solution that would really satisfy me is staticman. The idea is based on creating Merge/Pull Request on Github. This solution can solve all issues mentioned above. But when I had been investigating staticman they had a huge problems:

Incremental builds support

For the moment GatsbyJS does not allow to build specific page if only this page was changed.

Good

  • Lack of this feature is a minor issue for small sites
  • GatsbyJS team did the first real step towards solving this issue

Bad

  • Build process of huge websites can be dramatically slow
  • There is no clear information when it can be fixed (Last update).

Note that build on Netlify can be much faster if you are using the latest version of GatsbyJS.

Conclusions

GatsbyJS is about blazing performance, better security, cheaper to scale, nice development experience.

Kyle Mathews (GatsbyJS founder) said the following about static site generator:

They have real limitations in real-world use cases — they can’t handle frequent content updates and can’t scale to large and complex sites.

I think GatsbyJS perfectly fits small sites. I also believe that incremental builds support can change this soon.

As an alternative for big projects I strongly recommend using Next.js framework.

Do you like the article or have some remarks? Let's discuss it!

Join the Newsletter

Subscribe to be up to date by email.
Cool content and no spam.

tridenttridentGlory to Ukraine!