Using Hashnode as a Source for Gatsby

Published | 5 min read

I have done quite a few website migrations over the years. My blog like many first started out on WordPress. After several attempts at optimisation, I ended up generating a static version of my WordPress website.

On my static site generation journey, I discovered Gatsby.js and completely redesigned my website around it. However, writing posts locally in markdown has its own downsides and lacks the discoverability you get from blogging on Hashnode.

So I decided to move my blog posts over to Hashnode but I still wanted my posts to appear on my main blog.

Migrating the Blog Posts

The first step was to import all my blog posts to Hashnode. There are a few methods you can use to import your blog posts.

Hashnode import methods

I decided to use the Dev.to importer as I repost all my posts on dev.to anyway. Unfortunately, the bulk import didn’t work for me so I had to import my posts one at a time.

This was handy though as you need to set the following for each post manually:

  • Post slug
  • Tags
  • Canonical URL

Once all my posts were imported it was time to edit my Gatsby website to start pulling down the posts.

Gatsby plugins

If you do a search for gatsby-source-hashnode you will find a couple of plugins on the Gatsby website.

I decided to go with the first one (gatsby-source-hashnode) as it has a lot more downloads and still appears to be maintained.

However, I quickly noticed when testing out the plugin that it was only pulling down the first 6 posts from my Hashnode blog. This might be a recent change to the API which hasn’t yet been picked up by the plugins.

Luckily, the plugin is open source so I raised a PR for the plugin owner to review.

In the meantime, I copied my modified code to a folder in my gatsby repository called plugins/gatsby-source-hashnode. I then used the plugin as described in the documentation.

GraphQL queries

I am using GraphQL queries in a few places to pull down posts:

  • Blog Feed
  • Blog Post
  • Latest Posts
  • RSS Feed

For reference, this is what a couple of my queries look like for pulling from Hashnode.

Blog Feed

query pageQuery($skip: Int!, $limit: Int!) {
    site {
      siteMetadata {
        title
        description
      }
    }
    allHashNodePost(
      sort: { fields: [dateAdded], order: DESC }
      limit: $limit
      skip: $skip
    ) {
      edges {
        node {
          brief
          slug
          title
          coverImage {
            childImageSharp {
              gatsbyImageData(
                width: 920
                height: 483
                layout: CONSTRAINED
                transformOptions: {cropFocus: CENTER}
              )
            }
          }
        }
      }
    }
  }

Blog Post

query BlogPostBySlug($slug: String!) {
    site {
      siteMetadata {
        title
        author
        siteUrl
      }
    }
    hashNodePost(slug: { eq: $slug }) {
      _id
      brief
      childMarkdownRemark {
        htmlAst
      }
      slug
      title
      dateAdded
      coverImage {
        publicURL
        childImageSharp {
          gatsbyImageData(
            width: 920
            height: 483
            layout: CONSTRAINED
            transformOptions: {cropFocus: CENTER}
          )
        }
      }
    }
  }

I am not yet pulling down tags or reading time from the API. That is something I will try out later.

Automation with GitHub actions

I already have GitHub actions set up for my website so that any new commits to the main branch trigger a website build and push to S3. I wrote a post about it if you want to find out how.

However, now that I am not committing articles to that repo I needed a way to automatically trigger builds when I publish a new post on Hashnode.

Luckily, Hashnode has an option to backup your blog posts to GitHub which we can use as the trigger point.

Step 1: Add workflow_dispatch to your GitHub action

To be able to remotely trigger a build on GitHub you need to add workflow_dispatch to the on: section of your workflow file.

This is what the top of mine looks like:

name: Deploy Blog

on:
  workflow_dispatch:
  push:
    branches:
      - main

Step 2: Create a personal access token

Next, we need to create a personal access token that we will use as the API Key for triggering the remote build.

You can do this in GitHub under Settings > Developer Settings > Personal Access Tokens

I set my access token with the following permissions.

GitHub Access

You will need to set an expiry date as well and set yourself a reminder to generate a new token before it expires.

Make sure you copy the access key as you won’t get a chance again!

Step 3: Add the key as a secret to your backup repository

To be able to use this access key we need to add it as a secret to the repository where Hashnode is backing up your posts.

On the backup repository go to Settings > Secrets and add a new repository secret called ACCESS_TOKEN and put in the key from the previous step.

Step 4: Add a workflow file

Next, we need to add a workflow that gets triggered every time a commit is added to this repository. In our case, this will be whenever we publish a post on Hashnode (Note: Drafts aren’t saved in GitHub).

Add the following file to your backup repository .github/workflows/workflow.yml

---
name: Trigger Deploy

on:
  push:
    branches:
      - main

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - run: |
          curl -X POST \
          -H "Authorization: Bearer ${{secrets.ACCESS_TOKEN}}" \
          -H "Accept: application/vnd.github.v3+json" \
          https://api.github.com/repos/GITHUB_USERNAME/WEBSITE_REPO/actions/workflows/workflow.yml/dispatches \
          -d '{"ref": "main"}'

Make sure you change GITHUB_USERNAME to match your GitHub username, WEBSITE_REPO to the repository with your Gatsby.js website and workflow.yml to match the name of your deploy workflow file.

To test, try updating one of your posts in Hashnode and you see this workflow get triggered then followed by your website workflow.


Was this post useful?
If you found this post useful and would like to support me, you can do so by buying me a coffee. Donations help keep this blog ad free.

ALSO ON ALEXHYETT.COM

What is DeFi? Understanding Decentralized Finance

What is DeFi? Understanding Decentralized Finance

  • 19 November 2021
If you are new to the crypto space the concepts of decentralised finance can seem a bit overwhelming. There are so many new terms to try and understand, it can be challenging to see how everything fits together. I have been working in the traditional...
What is Web3? The Decentralised Internet Explained

What is Web3? The Decentralised Internet Explained

  • 15 October 2021
If you have stumbled upon this article you have probably seen the term web3 being mentioned around the internet. Especially on Twitter at the moment it seems to be the latest buzzword. With all the hype around NFTs and crypto at the moment, a lot of ...
Ditch the Ads: The Future of Website Monetization

Ditch the Ads: The Future of Website Monetization

  • 08 October 2021
Do you remember that scene in Ready Player One, when IOI are showing what the future of the Oasis will look like once they take over? “We have determined that we’ll be able to fill 80% of the user’s display with advertising before inducing seizures”...
Dealing with Imposter Syndrome as a Software Developer

Dealing with Imposter Syndrome as a Software Developer

  • 28 May 2021
I have been a professional software developer for over a decade and I have been writing code for over 25 years. However, sometimes I still feel like a fraud. It turns out, I am not the only one that feels this way and they have a name for it, it is c...
Mocking API calls using WireMock

Mocking API calls using WireMock

  • 14 May 2021
It is rare in software development that you are building something in complete isolation from everything else. Generally, you are going to be making calls to other systems or components. If you are lucky you are building against an existing API that ...
Using ngrok to test local websites and APIs

Using ngrok to test local websites and APIs

  • 07 April 2021
Often when I am creating a new website, I want to see how it is going to look on an actual device like my phone or tablet. You can use Chrome Web Tools for mimicking a device but it isn’t the same as an actual phone. Chances are however that if you t...
Using GitHub Actions to Deploy to S3

Using GitHub Actions to Deploy to S3

  • 26 March 2021
Recently I went through the process of setting up Drone CI on my Raspberry Pi. The plan was to use my Raspberry Pi as a build server for this website as well as other projects. However, the Sharp image library that Gatsby uses to resize images doesn’...

Alex Hyett
WRITTEN BY

Alex Hyett

Software Developer, Entrepreneur, Father, and Husband. Engineering Lead at Checkout.com.

Want to get in touch? You can find me here:


Join the Newsletter

Subscribe to get my latest content by email.

    I won't send you spam. Unsubscribe at any time.