All Articles

How to Import your Medium Posts to Gatsby

Gatsby and medium posts comparsion after conversion.

Gatsby is all the all the rage for blogs and static sites right now. The new hotness. I’ve been wanting to move my Medium posts to my own blog for quite some time, so I decided to resurrect my blog, and try Gatsby at the same time.

I have one or two dozen posts on Medium, just enough to make a migration painful. So I spent an afternoon setting up Gatsby, and then a week writing a conversion script.

Medium2gatsby

The result is a script called medium2gatsby.

Some of the features:

  • Converts medium .html files and outputs gatsby .md files.
  • Allows customized output via templates
  • Downloads post images from medium and saves locally
  • Handles embedded tweets
  • Inlines github gists
  • Allows default language for code blocks.
  • Skips over drafts and post replies.
  • Generates report when done.

How to import your Medium posts to Gatsby

  1. Install medium2gatsby CLI via

    npm install -g https://github.com/jamischarles/export-medium-to-gatsby
  2. Download your medium posts as a .zip file

  3. Create a template file, then modify it to match the format your gatsby theme expects. You can also specify your image folder for Gatsby, and whether each post has it’s own folder. Save this file locall.

    Here’s a sample template file:

    module.exports = {
      render: function(data) {
        var template = `\
    ---
    slug: ${data.titleForSlug}
    date: ${data.published}
    title: "${data.title}"
    template: "post"
    draft: false
    description: "${data.description}"
    category: ""
    tags: [${data.tags.join(',')}]
    ---
    ${data.body}`;
    
        return template;
      },
      getOptions: function() {
        return {
          folderForEachSlug: false, // same folder for all posts
          imagePath: '/media', // <img src="/media/[filename]" >. Used in the markdown files.
          // This field is ignored when folderForEachSlug:true. Should be absolute. Location where medium images will be saved.
          imageFolder:
            '/Users/jacharles/dev/blog/static/media', 
          defaultCodeBlockLanguage: '', // code fenced by default will be ``` with no lang. If most of your code blocks are in a specific lang, set this here.
        };
      },
    };
  4. Run the CLI and use the medium-export/posts folder as the input. For the output (-o) specificy either your posts folder (usually content/posts), or copy it there after generating the files. ie: medium2gatsby ~/Downloads/medium-export/posts -o . -t template.js. As currenly written, this preceding command will read the .html files from ~/Downloads/medium-export/posts and save the converted posts in the current folder, and assumes that template.js is in the current folder.

Medium2gatsby will generate this report:

##############################################################
CONVERSION METRICS
posts attempted 24
posts succeeded 16
posts replies that were ignored: 8
posts drafts that were not attempted: 9
posts failed 0
Failed posts: []

medium images attempted 67
images succeeded 67
images failed 0
Failed images: []

gists inlining attempted 2
gists succeeded 2
gists failed 0
Failed gists: []
##############################################################
Medium files from "/Users/jacharles/Downloads/medium-export/posts" have finished converting to "/Users/jacharles/Downloads/medium-export/posts/output" using the "template.js" template.
Detailed output report named "conversion_report.json" can be found in the output folder.

If you encounter a connection error, try again. If you get repeated errors, file an issue.

  1. Start Gatsby with your newly imported files. Verify everything looks good. Make any CSS and styling adjustments as needed. If you see anything majorly wrong, or missing, please file an issue.

  2. Do a happy dance.

How it works

Medium2gatsby reads all the medium-exported .html files, and gathers the necessary data and blog content, then converts the html to markdown. Any medadata it can’t extract from the html will be extracted from the original medium post. Images and gist snippets are downloaded.

For any comments or feedback, hit me up on twitter.