← Go Back

The Great Gatsby Migration

Broken Post?Let me know

Photo by Ray Hennessy on Unsplash

I finished migrating a WordPress blog, SlightEdgeCoder.com to Gatsby yesterday (2019-11-10).

I will provide a "rough" list to describe what's done, as there is no one specific way to accomplish this and share my experience.

For a specific way to create a Gatsby blog, I will add links in the Resources section.

Why migrate?

Because of

  1. Pricing
    • I couldn't justify $170/year cost as the site isn't for profit.
  2. Slowness
    • As the site was running on a shared plan, the site was slow and a myriad of plugins made it even slower.
  3. The domain name sucked
    • SlightEdgeCoder.com was purchased years ago as it was cheap and not taken, and also based off on one of my favorite books, The Slight Edge.
    • But it's really a bad name, as it's hard to remember, type, long, and not memorable.
    • Sung.codes is short, memorable, and describes the site purpose.

Why Gatsby?

I've been working with React and that's what I know. There are other SSG or SSR frameworks, but the documentations and ecosystem made me choose it as the migration needed happen quickly. (I started migration after the site went offline).

Rough list

Export WordPress file

Follow steps here up to Move content from one WordPress site to another -> Export from Site A

Note that this exports an XML file, not as markdown.

I've tried Jekyll Exporter but it exported associated images to different folder, not within a folder with Markdown content.

I found it didn't co-located related files (content files and media) thus decided not to use this approach.

Export WordPress to Markdown

I used lonekorean/wordpress-export-to-markdown to convert exported WordPress file from previous step into Markdown files and download media thereof.

It's not a CLI, so you'd need to clone the source.

It's a node application with useful flags for options such as exporting grouped by years, months, etc.

Note that it won't import images in the body unless --contentimages flag is set.

Optional - Add more frontmatters

I had all content imported on DEV. DEV has a nice feature to export your content as JSON.

Under Settings/misc, you can export all of your content.

dev export

Previous step exports markdown but many frontmatters (such as tags, tags, author, etc.) are missing.

So I created a small node script, dance2die/fix-sungcodes-markdown-frontmatters to merge missing frontmatters from DEV json file.

Create or branch existing Gatsby site

Gatsby requires some learning curve so I will refer to you to the Gatsby tutorial.

I already had an existing repository, dance2die/sung.codes so I just created v2 branch to start from existing Gatsby site. (v1 was simply using WordPress RSS data to create a static version of it.)

After familiarizing with Gatsby, you can pursue further with following articles (I didn't follow the all the steps in both, just took the parts I needed)

Or, you can do what I did, standing on the shoulders of giants

Optional - Following Kent C. Dodds blog source

I knew that Kent C. Dodds (KCD, hereafter) migrated from Medium to Gatsby recently (and took very small part finding issues/typos during migration).

Reference: kentcdodds/kentcdodds.com

KCD has generously made the code open source with MIT, I decided to follow his steps and learn from it as well. You know, he is Kent C. Dodds.

KCD has create a global configuration, which made it easy to apply to the whole site.
It was crucial as the common configurations can be used for site content, SEO, or styling for a consistency and traffic.

References:

  1. SEO components
  2. config

I've taken most of his configuration and SEO as well as blog post banner display codes. Doing so made it easy to provide OpenGraph data for SEO and get the consistent configuration data throughout the whole site.

Optional - Redirect traffic

I decided to abandon SlightEdgeCoder.com in favor of sung.codes.
Firat Özcan helped me learn a way to 301 redirect easily with CloudFlare, which is what I did.

Reference: Configuring URL forwarding or redirects with Cloudflare Page Rules

If you need to keep your existing URL, rewrite your URL, instead of redirecting.

To Dos

  1. There are still a lot of styling issues for blog posts.
  2. To report an issue, I added a tweet link per post, but will make it work for GitHub (after creating a template).
  3. Also the biggest issue is a lack of CMS (Current I've created this blog markdown manually.)
    • I decided to go with NetlifyCMS because of its git based workflow, and the site being hosted on Netlify.
  4. RSS feed is not yet implemented. Need a manual copy & paste to share on DEV.

Misc.

Issues

Here are the some issues that I've encountered.

  1. After "Export WordPress to Markdown", the frontmatter date didn't match by a day for some posts with WordPress slug, which used published dates.
    • It was due to WordPress using my local EST time to publish, while lonekorean/wordpress-export-to-markdown used UTC to parse dates and add it as "date" frontmatter metadata.
    • The fix was done during the "Optional - Add more frontmatters" step.
    • It was a sorta critical as I needed to do 301 redirect, and the off-by-one day wasn't able to properly forward to the new domain.
  2. I had no idea how KCD's banner code worked.
  3. Not all banner images or body images are exported/imported.
    • As there are 100+ posts, I wasn't able to check missing media for each.
    • But whenever I write my blogs, I store them on OneDrive, so able to recover'em all (but one by one).
  4. Might be none issue.
    • I've exported markdown in "content/<year>/blog" structure while KCD had a flat "/content/blog".
    • But it wasn't much of an issue because slug is generated dynamically within gatsby-node.js.

Theme

To provide a consistent UI, I used Theme-UI as gatsby plugin, gatsby-plugin-theme-ui.

Gist workaround

"gists" are shown as raw link, thus I used gatsby-remark-embed-gist but hacked by embedding gist CSS for blog post component.

export default ({}) => {
return (
<Layout>
<SEO
frontmatter={frontmatter}
url={new URL(slug, siteUrl).href || siteUrl}
/>
<Link to={`/blog/${year}`}>&larr; Go Back</Link>
👇
{/* This "link" is for styling gists. */}
<link
rel="stylesheet"
href="https://github.githubassets.com/assets/gist-embed-123720f37c57ce9a8f29de081c38ed61.css"
></link>
<Location>
{({ location }) => ( )}
</Location>
</Layout>
)
}
view raw gist css.jsx hosted with ❤ by GitHub

Resources