Building a Simple JAMstack Site With Gridsome [2021 Guide]

May 29, 2020 · Updated January 23, 2021 · 7 min read

Silver MacBook turned on Photo by Fabian Grohs on Unsplash

This is part one of a series on building a file-based blog from scratch with Gridsome. Find the full series here.

So, what is Gridsome?

Gridsome is a modern static site generator based on Vue. It has functionality that allows easy development of fast websites, and loading data from various sources.

Gridsome is inspired by Gatsby, a similar framework based on React.

To be more precise, Gridsome builds static progressive web apps. The major benefit of frameworks like Gridsome are the speed benefit for your website visitors, and the ease of development. Only the essential pre-rendered HTML, CSS and JS are loaded at first. When the entire website is rendered, Gridsome sites hydrate into a fully functional Vue.js app in the background. You also get “code splitting, asset optimization, progressive images, and link prefetching” out of the box.

There are plenty of options to load data for your website from. You can load, e.g., JSON or Markdown files from the local filesystem. With this, you can already build a Git-based blog (like this one!). Other data sources include most of the (headless) CMS out there, like Forestry, Contentful, Drupal, Sanity.io, and (yes) even Wordpress. Gridsome can also load data easily from databases, AirTable, and any other API.

Hosting options are plentiful, because all you need to do is to serve the static files generated by Gridsome. You host these files wherever you can serve static files. It’s possible to just put them behind nginx on a VPS. But static sites really shine when hosted on a global CDN, because of the decreased latency, increased download speeds, and the massive scalability. Static sites on CDN are also “set-and-forget”. You won’t need to update servers, or fix security bugs.

Popular options to host static sites are CDN-based solutions like Netlify (which I use), Vercel (formerly Zeit now), Surge.sh, AWS Amplify, or Google Firebase. You can also use the static file hoster of your choice and add a CDN like Cloudfront. Most have a free plan, so try them and find out what works best for you.

Why not use Wordpress?

Dynamic sites like Wordpress update automatically when you change your data. This is because each time a user requests your website, Wordpress looks into the database and retrieves the latest version of that site. (That’s simplified, because Wordpress sites can use caching at various layers.)

Static sites on the other hand need to be rebuilt when the content changes. Every time you add a blog post, fix a typo, or add an image you need to

Wordpress works for many people and is still a valid default option for your run-off-the-mill websites. You can even build many complex projects with Wordpress. The eco-system of themes and plugins is amazing. (And yes, you can even export your Wordpress as a static site.)

But for many use cases, static sites are a great option.

Static sites give your website visitor the fastest experience, because there is no dynamic rendering of the website on the server-side.

How does JAMstack relate to static sites?

JAMstack sites are a subtype of static sites.

They consist of client-side JavaScript, reusable APIs, and pre-built Markup.

For me, JAMstack is:

  • Pre-rendered HTML
    Most front-end frameworks offer server-side rendering by now. This means we can pre-render all static parts of an application, resulting in faster load times for the website visitor.
  • Static hosting on a CDN
    CDNs store your web app data on a globally distributed cache, so your website visitors have maximum download speed and minimum latency. Most CDNs also do cache invalidation for you, so visitors always get the newest version. (JAMstack doesn’t require the use of a CDN, but CDN’s let JAMstack really shine.)
  • Using APIs for dynamic content
    Dynamic in this context when content changes happen frequently and non-predictably, like with comments. For example, you can use an external service like commento for website comments.

Why Gridsome?

Gridsome is a modern way to build static websites. As explained above, you get an optimized, pre-rendered static site that hydrates into a fully Vue.js-powered SPA. This means you get the full power of Vue.js, with the download and render speed of a static site.

Gridsome sites get nearly perfect Google Lighthouse Scores out-of-the-box. This is the score for my blog: Near-Perfect Google Lighthouse Score

I only spent minimal time optimizing the accessibility, mainly by adding Aria labels and getting the color contrasts right.

These results tell you how Google perceives your site. A higher ranking on these measures (Performance, Accessibility, Best Practices, and SEO) can improve your ranking in Google search results.

One other thing I love about Gridsome is that you can load data from many sources with ease. You load data from any data source into a collection. A collection can be Posts, Products, Members, or any other dataset you want to display on your site. The data in these collections is stored as a flat list of nodes, with any number of nested properties you want. You then use GraphQL to load your data in your application.

How to create a basic Gridsome site

Let’s get started with a basic Gridsome project. We’ll use the Gridsome CLI. Install it with the following command:

yarn global add @gridsome/cli

Then we’ll create our project and start it:

gridsome create awesome-blog
cd awesome-blog
gridsome develop

This is what we’re greeted with: Gridsome starter websites. Contains example texts, a home page and an about page.

What does the default Gridsome starter contain?

Now let us look at the folder structure: Gridsome folder structure.

On the top level, we have some standard files and folders: package.json, README.md, .gitignore, yarn.lock, and the node_modules folder.

We can also find two Gridsome config files: gridsome.config.js and gridsome.server.js.

  • The gridsome.config.js file contains Gridsome specific configuration like the site name, and any plugins you want to enable. Plugins like a site map, data-loader or RSS plugins, or CSS loaders.
  • You can use the gridsome.server.js file to hook into the life cycle of Gridsome and load data or mutate collections.

Finally, there are two top-level folders: src and static.

  • The static folder is for all files you want to be copied as-is into the dist folder (the result of gridsome build).
  • In the src folder, you can find several more files and folders:

    • main.js: contains the initial Vue component
    • favicon.png: your favicon
    • components: a place for your Vue components that you’ll use on your site
    • layouts: are Vue components that wrap other Vue components and templates. Layouts should contain the headers, footers, and sidebars that you use on your site.
    • pages: are separate pages like your home page (Index.vue) or your about page (About.vue). These pages will be rendered under your-site/page, like mannes.tech/about. They will be rendered inside the specified layout component.
    • templates: these components are the blueprints for all dynamically created pages, like blog posts.

When you run gridsome develop, you can see changes to your site instantly. Go ahead and change that Lorem Ipsum text!

Exploring the GraphQL API

Gridsome exposes a GraphQL API for you to explore the data. You can find the URL to the GraphQL explorer (Playground) in the output of the gridsome develop command (most likely http://localhost:8080/___explore).

At the moment there is not much data, but you can explore the GraphQL schema (click on the DOCS tab on the right). Explore all pages with this command:

query {
  allPage {
    path
    context
  }
}

The result will look like this:

{
  “data”: {
    “allPage”: [
      {
        “path”: “/404/“,
        “context”: {}
      },
      {
        “path”: “/“,
        “context”: {}
      },
      {
        “path”: “/about/“,
        “context”: {}
      }
    ]
  }
}

This tells you that you get the index page, an about page and a 404 page out of the box.

Creating a new page

As a final step, let’s create a new page and link to it from the Index page. We’ll add a “pages” page that links to all the pages (because our pages are something we can query).

First, create a new file in the src/pages folder called Pages.vue

Basic Vue components consist of three parts: <template>, <script>, and <style>. The template contains your HTML template for that component (with Vue specific syntax). The script part defines the JavaScript for that component (this is also where you import other components). And the style contains your CSS/SASS/LESS rules, which are scoped to that component.

Gridsome enhances this with the <page-query>. With a page query you can interact with the GraphQL API and load data from it. This data is then available inside of your component’s script and template.

The final Pages.vue file looks like this:

<template>
  <Layout>
    <h1>Pages</h1>
    
    <ul>
      <li v-for="page in $page.pages" :key="page.path">
        <g-link :to="page.path">{{ page.path }}</g-link>
      </li>
    </ul>
  </Layout>
</template>

<page-query>
query Pages {
  pages: allPage {
    path
  }
}
</page-query>

<script>
export default {
  metaInfo: {
    title: ‘Pages’
  }
}
</script>

You can now add a link to it in your src/pages/Index.vue template:

<g-link to="/pages">Pages</g-link>

(Add it somewhere within the template > Layout HTML section)

Next part: loading markdown files as blog posts

That’s it for this introductory post on JAMstack with Gridsome. Find out how to create a markdown-based blog in the next part of this series.