DEV Community

Deborah D
Deborah D

Posted on

 

From Jekyll to Gatsby: 7 Simple Steps

Six years ago, during my final year in college, I was enrolled in a course on Open Source technology. To pass the course was to do two things: contribute to an open source project, and blog about it. Laughably, the only thing that propelled me to start writing publicly was the fear of failing the class.

I passed the course and managed to get some semblance of a blog together. However, I didn't put too much effort into building the site itself since much of my effort was expended in writing the content and trying to creep my way into open source. At the time, Jekyll was all the rage and I went with a themed Jekyll starter called Lanyon.

It served me well over the years, but my unfamiliarity with how it worked kept me from making any substantial changes to the structure of the site. I've finally taken the stand to move to a stack I'm more comfortable with.

Why Gatsby?

I considered refurbishing my blog with Gatsby and Next. I decided to go with Gatsby since it is a little more specialized towards static site generation.

Let's Get Migrating

Scaffolding

Getting a Gatsby project up and running is well-documented on the Gatsby site. Enhancing the project to generate a page from a markdown file is also clearly explained.
These are the steps I followed to get the initial project set up for the blog:

  • Used the gatsby-source-filesystem plugin to read markdown files into Gatsby. I added an entry to the plugins key in gatsby.config.js.
plugins: [{
   resolve: `gatsby-source-filesystem`,
   options: {
    name: `markdown-pages`,
    path: `${__dirname}/src/markdown-pages`
  }
}]
Enter fullscreen mode Exit fullscreen mode
  • Parsed markdown files using the gatsby-transformer-remark plugin which extracted the frontmatter as data and the content as HTML.
plugins: [
  {
    resolve: `gatsby-source-filesystem`,
    options: {
      name: `markdown-pages`,
      path: `${__dirname}/src/markdown-pages`
    },
  },
  `gatsby-transformer-remark`
]
Enter fullscreen mode Exit fullscreen mode
  • Created a template for blog posts using React to render a blog post's data as a React component.

  • Generated pages for all markdown files using the createPage Gatsby API.

  • Created an index page for all blog articles that displayed a list of links.

Migrating Content

I copied all the markdown files from my old website to the folder indicated in the gatsby-source-filesystem config entry: markdown-pages. I was now able to see all my old blogs being listed on the index page, but most of the posts themselves looked terribly broken.

Fixing All the Things

Links

To avoid breaking links, I used the same slug format that my old Jekyll site used: YYYY/MM/DD/Title. In my case, the slug was derived from the filename instead of the frontmatter, which required a little special handling.

  • To access the filename, I used createFilePath.
  • I extracted the slug and the date from the filename and passed them along as node fields, available to subsequent page queries.
const result = extractMetadataFromFilename(filePath);
date = result.date;
slug = result.slug;
createNodeField({ node, name: `date`, value: date });
Enter fullscreen mode Exit fullscreen mode

Highlighting

In my old Jekyll site, I was using pygments for syntax highlighting of code snippets, which used syntax like this to create a highlight:

{% highlight C++ %}
{% raw %}
  void f(int x, int n)
  {
    Gadget * g = new Gadget{n}; // Look ! Iā€™m a Java Programmer :)
    if(x < 100) throw std::runtime_error{"weird"}; //leak
    if(x < 200) return; //leak
    delete p;
  }
{% endraw %}
{% endhighlight %}
Enter fullscreen mode Exit fullscreen mode

Since this no longer worked in Gatsby, I changed all highlights to be enclosed in three back-quotes which translates to a <pre> tag enclosing a <code> blog.

I would like to eventually embed gists directly into my posts, but that's an improvement for a later blog post.

Images

First, I copied over the images from my old site to src/images. To make Gatsby aware of where my images were located, I added another plugin entry for the gatsby-source-filesystem plugin.

{
  resolve: `gatsby-source-filesystem`,
  options: {
    name: `images`,
    path: `${__dirname}/src/images`,
  },
}
Enter fullscreen mode Exit fullscreen mode

I then modified the plugin entry for gatsby-trasformer-remark to add the gatsby-remark-images plugin to it.

{
  resolve: `gatsby-transformer-remark`,
  options: {
    plugins: [
      {
        resolve: `gatsby-remark-images`,
        options: {
          maxWidth: 800,
        },
      },
    ],
  },
}
Enter fullscreen mode Exit fullscreen mode

With this configuration, I was able to embed images inline using the familiar markdown format:

![Architecture](../images/NN.jpg)
Enter fullscreen mode Exit fullscreen mode

It's important to use a relative path to the images folder.

- src
  - markdown-pages
  - images
Enter fullscreen mode Exit fullscreen mode

For the directory structure above, ../images/image.png would be the path to an image referenced in a markdown file.

Gifs

gatsby-remark-images cannot handle gifs. I added the gatsby-remark-copy-linked-files plugin to properly handle any gifs that gatsby encountered.

{
  resolve: `gatsby-transformer-remark`,
  options: {
    plugins: [
      {
        resolve: `gatsby-remark-images`,
        options: {
          maxWidth: 800,
        },
      },
      `gatsby-remark-copy-linked-files`
    ],
  },
}
Enter fullscreen mode Exit fullscreen mode

Favicon

Again, I invoked the mighty plugin system of Gatsby and added another plugin entry in gatsby-config.js.

{
  resolve: `gatsby-plugin-favicon`,
  options: {
    logo: `./src/favicon.ico`
  }
}
Enter fullscreen mode Exit fullscreen mode

Styling

I lazily copied over the poole/lanyon theme to avoid me having to write any CSS. Let's not kid ourselves, I don't really know how to design a site.

Since these are global CSS styles, I needed to import them into the gatsby-browser.config.js file to make them apply to the generated HTML files.

import './src/styles/poole.css';
import './src/styles/lanyon.css';
import './src/styles/Calendas_Plus.otf';
Enter fullscreen mode Exit fullscreen mode

Deploying

To test the site out and compare it with my old site, I deployed the site to Netlify. It was about as simple as going to the Netlify site, authorizing access to my GitHub repo, and providing a build command.

Build Command

Testing that No Links are Broken

With my site deployed to Netlify, I tested that no links would be broken by ensuring that each link on the old site also existed on the new site:

links.forEach(link => {
  link = link.replace('deborah-digges.github.io', 'epic-mirzakhani-8e39a6.netlify.app');
  request(link, (err, res, body) => {
    if (err) { console.log('Page fetch failed', err); }
    console.log(link, res.statusCode);
  });
});
Enter fullscreen mode Exit fullscreen mode

I ran the following script on each of the two pages of my old blog to extract all the links:

let links = document.querySelectorAll('a');
let siteLinks = []
for (let i=0; i < links.length; i++) {
  let linkText = links[i].textContent;
  linkText = linkText.replace(/\s+/g, ' ').trim();
  const link = links[i].href;
  siteLinks.push([linkText, link]);
}

for(let i=0; i < siteLinks.length; i++) {
  console.log(siteLinks[i][1]);
}
Enter fullscreen mode Exit fullscreen mode

Admittedly, it's a little rudimentary, but hey! it did the job.

Switching over

Once I was ready to bid adieu to the shackles of my Jekyll site, I overwrote my Github User Pages repository with the shiny new Gatsby site. I will be going over the details of deploying a Gatsby site to GitHub Pages in a subsequent blog post!

Next Up

Now that I'm using a system I understand a little better, I want to soon:

  • Implement pagination
  • Create categories for pages and allow browsing the blog by category
  • Create a navigation element called Content in the header which expands to Blogs, Drawings, Book Reviews
  • Create a Reading List navigation element
  • Lean enough about CSS and design to create a better landing page (Maybe hire a designer?)

If you'd like to check it out in more detail, you can find the source code here.

Tune in again for more exciting updates to my Gatsby blog!

Top comments (0)

50 CLI Tools You Can't Live Without

The top 50 must-have CLI tools, including some scripts to help you automate the installation and updating of these tools on various systems/distros.