Building a blog with Gridsome: Creating the Blog

Published on October 30, 2018

    Alex Jover Morales

    Building a blog with Gridsome: Creating the Blog

    While we believe that this content benefits our community, we have not yet thoroughly reviewed it. If you have any suggestions for improvements, please let us know by clicking the “report an issue“ button at the bottom of the tutorial.

    Gridsome is the Gatsby alternative for Vue.js that aims to provide the tech stack to build blazing fast statically generated websites. It’s data-driven, using a GraphQL layer to get data from different sources in order to dynamically generate pages from it.

    A few days ago I announced Gridsome on Twitter as soon as I heard about it. It’s a project built by the brothers Tommy Vedvik and Hans-Jørgen Vedvik (could they be the next Nuxt brothers?).

    It has special focus on web performance, applying the PRPL pattern in order to achieve fast time to interactive (TTI) and therefore great scores in Lighthouse.

    I’m pretty sure you’re as excited as I am, so let’s see how we can build a simple blog with Gridsome!

    Getting Started

    Gridsome comes with a nice CLI to bootstrap the project. Let’s start by installing it and creating a project:

    $ npm install --global @gridsome/cli
    $ gridsome create my-awesome-blog

    Now you can go to my-awesome-blog and run npm run develop to start building the blog.

    Folder Structure

    If you go to the src folder created, you’ll see that it’s no much different than with a usual Vue app.

    Similar to the way Nuxt.js works, Gridsome has pages and layouts.

    Pages are the Vue components that define the pages of the website, and their folder structure determine the routes created. For instance, by default you have pages/Index.vue and pages/About.vue, that will end up creating the / and /about routes.

    If you take a look at any of the pages, you’ll see they are wrapped in a <Layout> component, which is the default layout registered in main.js. Take a look at the layout docs to find more info.


    Another important piece is the gridsome.config.js file, where you can configure many aspects of a Gridsome app.

    A basic configuration may look like this:

    module.exports = {
      siteName: "Alligator",
      siteUrl: "https://alligator.io",
      siteDescription: "Learn about it on Alligator.io! 🐊",
      icon: "src/alligator-favicon.png",
      plugins: []

    You can see some metadata properties, as well as a plugins option that we’re about to use.

    See the config docs to find all the config options.

    Building a Blog

    Enough said, let’s get a real blog started!

    For the blog, we’d like to write the posts in markdown, so that a page is created for each markdown file.

    We can’t use Gridsome’s pages for it, since they have a specific path based on their folder structure. Instead, we want to dynamically generate a page per post.

    For that, we need to use the source-filesystem plugin which takes local files as source of data, creates routes for them and adds their data to the GraphQL layer.

    In order to understand the markdown content, it also needs transformer-remark. Let’s install both:

    $ npm install --save-dev @gridsome/source-filesystem @gridsome/transformer-remark

    And add the following config to gridsome.config.js:

    module.exports = {
      transformers: {
        remark: {}
      plugins: [
          use: "@gridsome/source-filesystem",
          options: {
            path: "blog/**/*.md",
            typeName: "Post"

    As you can see, the options talk for themselves, but the important ones for us here are:

    • path: we’re telling it to grab the markdown posts from the blog folder. It’ll create a route given the path of the file (for blog/crazy-post.md the path will be /blog/crazy-post)
    • typeName: that’s the GraphQL entity that will be created

    Creating the Post template

    Gridsome uses templates to define how these dynamically generated pages will be rendered.

    The template we create for the post must match the typeName option we’ve just set. So, let’s create templates/Post.vue with the following content:

        <div v-html="$page.post.content"/>
    query Post ($path: String!) {
      post: post (path: $path) {
    export default {
      metaInfo() {
        return {
          title: this.$page.post.title

    The outstanding thing here is the <page-query> tag… What’s that?

    If you remember, Gridsome uses a GraphQL layer to access the data, and the @gridsome/source-filesystem plugin is filling it with the posts found.

    What’s even more amazing, is that you can access a whole GraphQL playground at http://localhost:8080/___explore, so you can explore the schema and try your queries in there!

    GraphQL Playground

    As soon as you have your query ready, you can place it in the <page-query> tag, which accepts a $path variable in order to query the right post.

    The result of that query will be placed within the $page instance property. In that way, we can insert the post content using <div v-html="$page.post.content"/>.

    Isn’t that cool?

    Another outstanding point is the metaInfo computed property. That’s in there because Gridsome uses vue-meta, so you have full control on the meta info for SEO, social media and metadata purposes, and you can use $page to access the post data.

    Finally, create a blog/awesome-article.md with some random content:

    title: An awesome article
    ## An awesome article
    This is some **awesome** content for a crazy sample blog

    Now, thanks to hot reloading, the article should be available at http://localhost:8080/blog/awesome-article

    Gridsome Blog Running

    Wrapping Up

    So far we’ve seen how to get started with Gridsome, as well as installing and using plugins in order to connect with different types of source data.

    Stay tuned for the second part of this article to see how to extend our blog with a paginated page that lists the blog’s posts.

    Stay cool 🦄

    Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.

    Learn more about our products

    About the authors
    Default avatar
    Alex Jover Morales


    Still looking for an answer?

    Ask a questionSearch for more help

    Was this helpful?

    This textbox defaults to using Markdown to format your answer.

    You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!

    Nice tutorial, really like it

    Try DigitalOcean for free

    Click below to sign up and get $200 of credit to try our products over 60 days!

    Sign up

    Join the Tech Talk
    Success! Thank you! Please check your email for further details.

    Please complete your information!

    Featured on Community

    Get our biweekly newsletter

    Sign up for Infrastructure as a Newsletter.

    Hollie's Hub for Good

    Working on improving health and education, reducing inequality, and spurring economic growth? We'd like to help.

    Become a contributor

    Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.

    Welcome to the developer cloud

    DigitalOcean makes it simple to launch in the cloud and scale up as you grow — whether you're running one virtual machine or ten thousand.

    Learn more
    DigitalOcean Cloud Control Panel