Joel Olawanle Frontend developer and technical writer.

Getting started with Gridsome

15 min read 4280

Quick Summary

Whenever you are running into performance issues with your single-page applications, you might consider using a static site generator to offload some performance overhead. There are hundreds of static site generators out there, and Gridsome is one of the most popular with over 7000 stars on Github. Gridsome is certainly worth a detailed look, so let’s get started.

Introduction

In this article, we will be taking a closer look at Gridsome: how it works, how to get started, how to use Gridsome to create websites and apps that are fast by default, and finally, learn how to fetch markdown content with GraphQL.

This tutorial is specifically for developers who want to get started with Gridsome and already use Vue.js. By the end of this tutorial, you will understand how to make use of Gridsome’s many functionalities — along with a few “gotchas” and things to keep in mind along the way.

To get started with Gridsome, you’ll need to make sure you have the following tools installed:

To confirm that you have Node installed, you can run node --version in the Terminal

  • npm (this comes packaged with Node) or Yarn
  • Basic understanding of how to use the Terminal
  • Basic knowledge of HTML, CSS, and Vue.js

Knowing how GraphQL works is a plus, though their documentation has plenty of examples for quick review.

Why Gridsome?

Gridsome is a free and open-source Vue-powered static site generator (SSG) for building fast, modern websites and apps

As a quick reminder, static site generators automate building individual HTML pages and get those pages ready to be served to users – people who visit/use your websites or apps. SSGs do so by building out fully-fledged, static HTML pages based on raw data (e.g., Markdown) and a set of templates.

Gridsome makes use of GraphQL to get data from different sources, then dynamically generates pages.

There are a few useful features that Gridsome provides out of the box. Gridsome works well on top of JAMStack. Like most static site generators, it supports Markdown and headless CMS. The final product is a folder containing static HTML files that you can deploy anywhere. You can put it in the /public_html folder on your server or deploy it to a CDN.

Gridsome also provides automatic routing. The Vue components that you create in the /src/pages folder are automatically mapped to a new page with vue-router without you having to do anything. For example, if you want to create an “About” page for your blog, all you have to do is create a new file called /src/pages/About.vue and you automatically have an http://localhost:8080/about page on your website. This is very similar to how Nuxt and Gatsby work; they have a defined folder where components are mapped to pages in the router, so you don’t need to configure them.

We made a custom demo for .
No really. Click here to check it out.

Additionally, Gridsome provides code-splitting and asset optimization. In Vue apps, when you create an internal link to another page, you use <router-link>. With Gridsome, you use <g-link> instead. It uses the same parameters with which you are probably familiar, but in addition, it provides in-viewport prefetching of pages in the background by prefetching assets and pages referenced as links in the current view. You need to approach this feature cautiously as it might create a performance overhead for users loading pages and assets that they will never actually use, but it can speed up the experience for simple pages.

Gridsome also has a built-in <g-image> component that outputs optimized compressed images. It also resizes and crops in real time while developing. It works like an <img> element, but <g-image> will also generate a compressed, blurry version of the original image as a placeholder. So when a user’s browser finally receives the image from the server, it replaces the placeholder with the actual image.

Gridsome and other static site generators

A chart comparing stars on Github between different Frameworks

Considering the fact that there are plenty of other Vue.js SSGs like Nuxt.js, VuePress, and saber, it’s worth exploring when Gridsome makes sense to use, and when it does not. Similar to Gatsby in React, Gridsome is a data-driven framework that uses a GraphQL layer to retrieve content from which it dynamically generates pages. Although it’s not yet as established as Nuxt.js and VuePress, Gridsome has some unique features which make it worth exploring for your next project.

Gridsome vs Nuxt.js vs VuePress

Nuxt.js is definitely a more complete framework, and it can do almost everything that Gridsome can. However, with Gridsome you can query data from the GraphQL data layer into any page, template or component without needing to use a module, as compared to Nuxt.js using Apollo Configuration.

If you’re planning to build a large scale application in which handling authentication is better suited to the server-side, Nuxt.js may be a better option.

If you want to set up a beautiful, blazing-fast documentation site that is SEO-friendly, and want to use Markdown with markdown-it and its extensive ecosystem, VuePress is the way to go.

If you want to connect your site with a headless CMS and build a JAMstack project, Gridsome is more powerful. I think that the GraphQL Data Layer is very handy and straightforward to use, because it allows you to build static content from data sources. In this case, Gridsome is the best choice.

Getting Started

A screenshot of the Gridsome website
Source: Gridsome website

Gridsome fetches data from data sources like CMSs (any headless CMS, Contentful, WordPress, Drupal, Sanity.io, etc.), local files, or external APIs and stores the data in a local database. GraphQL serves as a centralized data management system that gives you the ability to extract and use data within your Vue components.

You can then deploy your entire site or app to a CDN like Netlify, AWS Amplify, or Vercel. A Gridsome site can handle thousands to millions of hits without breaking – and with no expensive server costs.

Installation

Once you are sure you have Node and either npm or Yarn set up on your computer, you can now proceed to install Gridsome. As mentioned earlier, knowledge of how to use the Terminal is recommended for working with Grisome.

Step one is to install the Gridsome CLI tool:

  • Using Yarn:yarn global add @gridsome/cli
  • Using npm:npm install --global @gridsome/cli

You can now start creating your first Gridsome project! 🎉

  1. Run gridsome create first-gridsome-site to create a new project
  2. Move into the project directory with cd first-gridsome-site
  3. Run gridsome develop to start a local development server at http://localhost:8080

You can now launch the development server on your browser:

Screenshot of empty Gridsome website

Directory structure

Here is how a basic Gridsome project would be structured:

.
├── package.json
├── gridsome.config.js
├── gridsome.server.js
├── static/
└── src/
    ├── main.js
    ├── index.html
    ├── App.vue
    ├── layouts/
    │   └── Default.vue
    ├── pages/
    │   ├── Index.vue
    │   └── Blog.vue
    └── templates/
        └── BlogPost.vue

The root directory consists of 5 major files and folders.

  1. package.json is where all the dependencies for the project will be stored
  2. gridsome.config.js serves as a configuration file for the Gridsome site where you configure plugins
  3. gridsome.server.js is optional and is used to hook into various parts of the Gridsome server
  4. All files in /static directory will be copied directly to dist during build. For example, /static/robots.txt will be located at https://yoursite.com/robots.txt
  5. /src directory is where most of the code lives. In this folder, we have:

main.js, where you import global styles and scripts. This file contains all the application configurations such that it plugs other parts of the app into the Gridsome API.

layouts/, whose components are used to wrap pages. Layouts should contain components like headers, footers, or sidebars that will be used across the site. All layout components are located in the src/layouts folder and should be indicated as the global component or imported per page.

Working with layouts

Make a layout global

If you don’t want to import a layout into every individual page or template, you can make a global layout. To do that, go to src/main.js and import your layout file. Then make the layout global inside the export function.

For example:

// src/main.js

import Layout from '~/layouts/Default.vue'

export default function (Vue, { head, router, isServer }) {
  Vue.component('Layout', Layout)
}

You can now use <Layout> anywhere in your Gridsome project without importing it to every page:

<template>
  <layout>
    <!-- code comes here -->
  </layout>
</template>

Import layouts into specific pages

In a situation where a particular layout is not for all pages (for example, if the layout contains the navbar, which you don’t want on the sign in and sign up page), then you would have to import such layouts to only pages you need them.

When you have created a layout you need to import it to your pages and templates. This is done inside the <script> tag:

<!-- Page -->
<template>
  <navLayout>
    Add page content here
  </navLayout>
</template>

<script>
import navLayout from '~/layouts/navLayout.vue'

export default {
  components: {
    navLayout
  }
}
</script>

Every layout requires a <slot> component. This is where the content coming from pages and templates will be inserted. Layouts can have multiple slots:

<!-- Layout -->
<template>
  <div>
    <header />
    <slot></slot> <!-- Page content will be inserted here -->
    <footer />
  </div>
</template>

Every component in the pages/ directory becomes a page on the website. Each page will get its path based on the .vue file location. For instance, src/pages/Index.vue will become the homepage/ while src/pages/Blog.vue will be localhost:8080/blog or example.com/blog, which will be rendered as the blog page.

templates/ are used for single-post views to GraphQL collections. To add a template create a .vue file with the same name as a GraphQL collection to src/templates.

If you are importing an external data source, like posts from a WordPress blog, into your project, each post will look for a component in this directory for its template. The name of the component file must match the node type in your GraphQL schema.

Gridsome starter sites

Gridsome starter sites are prebuilt projects anyone can use to build his or her own websites. Gridsome has 40+ starter sites that cut across tons of platforms like Markdown, Strapi, WordPress, Auth0, and more. For this article, I will be installing the official Gridsome Blog Starter.

The Gridsome Blog Starter is a simple, hackable, and minimalist starter for Gridsome that uses Markdown for content. It also has a dark/light mode feature.

Here is what your site will look like after installing this starter site – https://gridsome-starter-blog.netlify.com/

Steps to install

First, install the Gridsome CLI tool: npm install --global @gridsome/cli.

If you are not sure if you have it, you can use gridsome -v to confirm if Gridsome CLI is already installed.

Next, install the starter site:

  1. Enter gridsome create my-blog https://github.com/gridsome/gridsome-starter-blog.git
  2. Run cd my-blog to move into the project directory
  3. Run gridsome develop to start a local dev server at http://localhost:8080

Congratulations, we have now set up a stater site for us to modify to our own taste! 🎉

Visit http://localhost:8080 to access this site:

Screenshot of a Gridsome blog starter site

You can now open vsCode or your preferred code editor to tweak this site to your liking. For example, you can create a new home page, convert this page to a blog, and use this as your portfolio website.

Gridsome plugins

Plugins enable additional functionalities that can be tied to your Gridsome app. Gridsome has a thriving ecosystem of plugins for complex integrations with many things. These are typically JavaScript libraries that you install using npm, and then configure to your project’s needs.

At the time of writing, Gridsome has 194 plugins, which you can access here. To install any Gridsome plugin, you can use npm or Yarn.

Any plugin that starts with @gridsome/ means it’s an official plugin from the creators of Gridsome. To install a plugin, all you have to do is visit the general plugins page, search for the desired plugin, then follow the installation steps.

Building a blog that fetches Markdown content

The first step to building a blog with Markdown is to create and set up a Gridsome project as explained earlier using gridsome create gridsome-blog.

In this tutorial, I will be making use of two plugins:

  1. @gridsome/source-filesystem plugin to transform files into content that can be fetched with GraphQL in your components
  2. @gridsome/transformer remark, a Markdown transformer for Gridsome with Remark

Markdown

Markdown is a lightweight markup language that you can use to add formatting elements to plaintext documents. Created by John Gruber in 2004, Markdown is now one of the world’s most popular markup languages. Markdown can be used for nearly everything, like websites, documents, notes, books, presentations, email messages, and technical documentation.

Installing plugins

As explained earlier, you can use either Yarn or npm to install plugins. Lets install both at once with npm using the following:

npm i -S @gridsome/source-filesystem @gridsome/transformer-remark

Once your installation is successful, you will need to configure the @gridsome/source-filesystem plugin within the gridsome.config.js file. This is so Gridsome looks for the blog folder and adds all posts to be queried later:

// gridsome.config.js

module.exports = {
  siteName: 'Gridsome',
  plugins: [
    {
      use: '@gridsome/source-filesystem',
      options: {
        typeName: 'BlogPost',
        path: './blog/**/*.md',
      },
    },
  ],
  templates: {
    BlogPost: '/blog/:title',
  },
};

The above configuration is what we need to set up the source-filesystem plugin.

  • typeName is the GraphQL type and template name

A .vue file in src/templates must match the typeName to have a template for it.

  • path is the location of the markdown content we’ll be consuming in the posts/blog
  • templates.BlogPost is the route every post will follow i.e., localhost:8080/blog/new-post

So this doesn’t get too complicated later, let’s create our Markdown files/posts. These will serve as dummy blog posts. First, create the blog folder which will contain our blog posts:

blog/welcome.md

---
title: 'Welcome to the blog'
date: 2020-04-20
---

## Welcome to the blog

This is the first post in this brand new blog.
Of course we have all the power of Markdown here,
so we can make things **bold** or _italic_.

blog/happy-easter.md

---
title: 'Happy Easter'
date: 2020-04-12
---

## Happy Easter

As it turns out I'm writing this on Easter,
so why not include a picture of a easter egg here.

!\[easter egg\](https://images.unsplash.com/photo-1457301353672-324d6d14f471?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=500&q=80)

To avoid confusion, this is what my file & folder structure looks like now:

Screenshot of an IDE

Whenever you make changes in your gridsome.config.js file or add new blog posts, you will need to hit (Ctrl + c) to restart the Gridsome development server so it picks up the new configuration and the files you have just created.

Querying data with GraphQL

There are so many ways to get data into your site in Gridsome, but a very popular and simple means is via GraphQL. Since we have set up the plugin and created dummy posts, let’s check out the GraphQL playground.

Data can be queried from the GraphQL data layer into any page, template or component. Queries are added with a <page-query> block in pages & templates or <static-query> block in components.

Run gridsome develop and navigate to http://localhost:8080/___explore:

# Write your query or mutation here
query {
  posts: allBlogPost {
    edges {
      node {
        id
        title
        date (format: "MMMM D, YYYY")
        path
      }
    }
  }
}

When you click the big Play button, we get the result below showing that the two blog posts we created as Markdown files are now available through the GraphQL endpoint:

{
  "data": {
    "posts": {
      "edges": [
        {
          "node": {
            "id": "46ea6f212d1378a5dcc360216e17dbc4",
            "title": "Welcome to the blog",
            "date": "April 20, 2020",
            "path": "/blog/welcome-to-the-blog/"
          }
        },
        {
          "node": {
            "id": "54c8892e9cf791f134c7ace95dcbcf5e",
            "title": "Happy Easter",
            "date": "April 12, 2020",
            "path": "/blog/happy-easter/"
          }
        }
      ]
    }
  }
}

The next step is to query and display the data in either our components or pages. Earlier on we created a file Blog.vue in our pages folder. Now that we have some content, let’s add it onto that page.

Let’s create a component BlogPostList in src/components/ to make our project easier to maintain and test. In the BlogPostList.vue file, use the code below:

// src/components/BlogPostList.vue

<template>
  <div class="post-list">
    <article class="post" v-for="post in posts" :key="post.node.id">
      <h4>{{post.node.title}}</h4>
      <p>Published on {{post.node.date}}</p>
      <g-link :to="post.node.path">Read article</g-link>
    </article>
  </div>
</template>

<script>
export default {
  props: ['posts']
}
</script>

<style>
.post-list {
  margin-top: 12px;
}

.post {
  padding: 12px 0;
}
</style>

This file is just receiving data as props from the Blog.vue file into which we are about to fetch our blog posts.

We will use <page-query> to get the list of blog posts from the GraphQL endpoint, as it’s a page:

// src/pages/Blog.vue

<template>
  <Layout>
    <h1>Blog</h1>
    <p>This is the blog page.</p>

    <BlogPostList :posts="$page.posts.edges"/>
  </Layout>
</template>

<script>
import BlogPostList from '~/components/BlogPostList.vue';

export default {
  metaInfo: {
    title: 'Blog'
  },
  components: {
    BlogPostList
  }
}
</script>

<page-query>
query {
  posts: allBlogPost {
    edges {
      node {
        id
        title
        date (format: "MMMM D, YYYY")
        path
      }
    }
  }
}
</page-query>

Now when you access the blog page via http://localhost:8081/blog/ we should see the list of blog posts:

Screenshot of empty Gridsome blog page

Creating a post page

Now it’s time to create a post page. At this point, if you try to click the read article link below each post it will refer you to a 404 error page. This is because we have not yet created a page for each individual blog post.

The 404 page can easily be customized.

As a reminder, the typeName is the GraphQL type and template name and a .vue file in src/templates must match the typeName to have a template for it.

To create single pages for nodes in a collection (in this case the collection is BlogPost), let’s create a new file, src/templates/BlogPost.vue, where we define how the blog posts should look.

We’ll need to add a page query again to get the post itself out of the GraphQL endpoint, this time we’ll also need the field content as it contains the body of the post in HTML:

// src/templates/BlogPost.vue

<template>
  <Layout>
    <article>
      <header>
      <h2>{{$page.post.title}}</h2>
      <p>Published on {{$page.post.date}}</p>

      <p><i>{{$page.post.timeToRead}}min to read</i></p>
      </header>

      <main class="content" v-html="$page.post.content"></main>
    </article>
  </Layout>
</template>

<style>
article > header {
  text-align: center;
}

.content {
  margin-top: 48px;
}
</style>

<page-query>
query Post ($path: String!) {
   post: blogPost (path: $path) {
    id
    title
    date (format: "MMMM D, YYYY")
    timeToRead
    content
  }
}
</page-query>

With these we have been able to create a blog that fetches Markdown content and files as posts. Feel free to add additional content and features to your website here.

You can find my source code here

Building a site for student profiles

In this tutorial, I will be using the gridsome/source-fakerplugin to get data for the site. This data will be queried using GraphQL.

Installing the plugin

As explained earlier, you can either make use of yarn or npm to run this installation:

yarn add @gridsome/source-faker

or

npm install @gridsome/source-faker

Once you are done with the installation, the next step is to register the plugin in gridsome.config.js:

export default {
  plugins: [
    {
      use: '@gridsome/source-faker',
      options: {
        numNodes: 100
      }
    }
  ]
}

Using TailwindCSS for styling

To make this site attractive, I will be using TailwindCSS. There are many options you can use to install TailwindCSS in Gridsome but I will be using their CDN.

In the main.js file, we will be adding the head metadata and then include the external CSS/CDN link:

import DefaultLayout from '~/layouts/Default.vue'
export default function (Vue, { router, head, isClient }) {
  // Set default layout as a global component
  Vue.component('Layout', DefaultLayout)
   head.link.push({
    rel: 'stylesheet',
    href: 'https://unpkg.com/[email protected]^2/dist/tailwind.min.css'
  })
}

Creating a profile page and linking

After successfully setting up the plugin and TailwindCSS, the next step is to create a new page and then link it in our default layout:

Screenshot of an IDE with profile.vue page circled

After creating the new page, go to layouts/Default.vue to include this new link in the navbar, knowing that Default.vue appears on all pages as it’s used to wrap page components:

<template>
  <div class="layout">
    <header class="header">
      <strong>
        <g-link to="/">{{ $static.metadata.siteName }}</g-link>
      </strong>
      <nav class="nav">
        <g-link class="nav__link" to="/">Home</g-link>
        <g-link class="nav__link" to="/profile/">Profile</g-link>
        <g-link class="nav__link" to="/about/">About</g-link>
      </nav>
    </header>
    <slot />
  </div>
</template>

To ensure that the new page makes use of defualt.vue, we will need to wrap our code with the name given to it in main.js, which is in layout as explained earlier.

Querying data with GraphQL

We’ve covered this topic earlier in this article, so you can follow along there for this part of the tutorial. You can find my source code here, and the live site here.

Deploying Live

When working with Gridsome, the best way to deploy your site is to make use of a Git-service like GitHub, then connect a deploy service (Netlify, AWS Amplify, Vercel, Github Pages, Surge.sh etc.) that builds your site from a selected repository. Some of these services (Vercel and Surge.sh, for example) let you deploy your static Gridsome site from the Terminal.

Gridsome comes with a set of useful commands, both for development and production purposes:

Command Description
create Scaffolding tool that will enable you to create a Gridsome app in seconds using gridsome create my-app
develop Start a local development server at http://localhost:8080/ with hot-reloading using gridsome develop
build This command generates a static site inside a dist directory of your project using gridsome build
explore To start the GraphQL Playground and explore your schema or data, go to http://localhost:8080/___explore
info Outputs information about the local environment using gridsome info

Deploying to Netlify

Two major things are needed to use Netlify to deploy you projects or websites:

  1. A GitHub account
  2. A Netlify account (you can use your GitHub details to sign up on Netlify)

If you have a GitHub and a Netlify account, then you can push your code to GitHub via Git.

Once you have pushed to GitHub, visit your Netlify dashboard via netlify.com and login:

Screenshot of Netlify page with New Site From Git button highlighted

Once you have logged in, you can now click the New site from Git button, then select GitHub as the Git provider where your site’s source code is hosted for continuous deployment:

Screenshot of create new site page on netlify

You can now search for the repository so you can begin to deploy your website as seen in the image above.

Screenshot of netlify Create New Site page with gridsome build in the build command line

Add the build command (gridsome build) for Gridsome. It might take some time to deploy, but once its done you will be able to access your site via the link Netlify generates for you.

The Netlify Drop can also be used by making use of the generated dist folder after running the gridsome build command.

FTP Deploying

FTP stands for File Transfer Protocol, which is a set of rules that computers follow for the transferring of files from one system to another over the internet. To host your Gridsome site on a traditional hosting via FTP, you need to manually build your project from the Terminal by running gridsome build in your project folder so as to generate a dist folder where your generated site is located.

The generated folder can now be uploaded to any FTP.

Conclusion

As static site generators gain popularity, you must be able to understand building with SSGs like Gridsome to deliver content to your users by comfortably building static websites.

This article is just an introduction to Gridsome. You can check the official Gridsome documentation to learn more here.

To read more about Gridsome, here are some links you can check out:

If you have any questions, you can leave them in the comments section and I’ll be happy to answer every single one! Thanks for reading!

Resources

 

: Full visibility into your web apps

LogRocket is a frontend application monitoring solution that lets you replay problems as if they happened in your own browser. Instead of guessing why errors happen, or asking users for screenshots and log dumps, LogRocket lets you replay the session to quickly understand what went wrong. It works perfectly with any app, regardless of framework, and has plugins to log additional context from Redux, Vuex, and @ngrx/store.

In addition to logging Redux actions and state, LogRocket records console logs, JavaScript errors, stacktraces, network requests/responses with headers + bodies, browser metadata, and custom logs. It also instruments the DOM to record the HTML and CSS on the page, recreating pixel-perfect videos of even the most complex single-page apps.

.
Joel Olawanle Frontend developer and technical writer.

Leave a Reply