The Practicalities of Migrating from WordPress to Eleventy

I recently wrote about the journey I took moving my blog from WordPress to Eleventy (which, to remind you, was the best thing I've ever done). In this post, I explain the steps I took in moving my blog (hint: it's not that difficult). I will go through the following 4 key steps:

  • Install Eleventy
  • Clone the Eleventy base blog repo
  • Convert WordPress posts to markdown
  • Add layout to marked down posts

Recap #

To recap I've been using WordPress for the last few years and, don't get me wrong, it has a purpose. WordPress offers a full CMS, database and a ton of plugins which makes it perfect for non-techies such as business clients (although, some would argue that Netlify offers a CMS - more on that later). The one thing I've found WordPress lacks is control. It is also a bloated system and for my purposes it quickly became apparent that I was trying to crack a nut with a sledgehammer.

Eleventy on the other hand is a static site generator (SSG). As such it drops the bloat and gives you minute control over every aspect of your website. The downside is that you have to have at lease some coding knowledge to get it up and running and maintain it. You also lose the benefit of a CMS unless you use aftermarket tools like Netlify CMS or Contentful, which are both extremely viable options.

Install Eleventy #

While this step isn't strictly required to get you started, I want to show you how simple it is getting Eleventy setup from nothing. First, we create a new project directory and navigate to it:

mkdir my-new-blog
cd my-new-blog

We initialize nmp:

npm init -y

This will create a package.json file in your project directory (required for the next step). Then we install Eleventy:

npm install --save-dev @11ty/eleventy

This will perform a local install of Eleventy in your project directory, the recommended approach. This may take a while, especially if you're working on a mid-2012 Macbook 👀. When it's done installing, you can do a dry run of Eleventy just to make sure it's installed properly:

npx eleventy

If everything installed ok, you should see Wrote 0 files in 0.03 seconds (v0.11.0). Now we can create some template files:

echo '<!doctype html>
            <title>Page title</title>
        </html>' > index.html
echo '# Page header' >

This will create two files: index.html and

Run npx eleventy --serve. This will create a hot reloading web server on localhost. When your web server is ready, you'll get two addresses, for example:

Local: http://localhost:8081

The Local address is the one you want to plug into your web browser. When you do, you'll should see this:

eleventy example

What Eleventy has done is loaded the index.html file you created earlier. You've now setup your very own local instance of Eleventy!

Clone the Base Blog Repo #

Eleventy provides a handy base blog template on GitHub which you can clone as a starting point for your new blog. Follow the link above and get rolling. The repo provides instructions for getting setup, but if it's easier you can follow the instructions below.

  1. Head to the base blog repo
  2. Clone the repo locally
git clone my-blog-name

This will create a local directory called my-blog-name. Call it whatever you like.

  1. Navigate to your local blog folder...
cd my-blog-name

  1. ...and install dependencies
npm install

  1. You can then run npx eleventy to run eleventy, or host locally for development as shown above, npx eleventy --serve.

If you use npx eleventy --serve and go to localhost:8080 browser, you'll see something like this:

local eleventy example

Convert WordPress Posts to Markdown #

This step is the most tedious, particularly if you have lots of wordpress content. Ed Spencer's article was one of the main drivers for me moving my site to Eleventy, and even though I didn't have much content I wanted to move (because I basically started again when I migrated), I found his tip on converting WordPress posts to markdown particularly useful.

Ed suggests using this great little npm package which helps shave a lot of time off converting WordPress to content to markdown. Follow these steps.

  1. Create a new folder locally and head to it.
mkdir wp-content
cd wp-content

  1. In your wp-content directory, grab the WordPress export to markdown repo
git clone convert

This will create a new directory (convert) and clone the repo into that directory

  1. Login to your Wordpress admin site and head to Tools > Export. Export your content, which will save as an xml file. Follow the WordPress documentation on exporting for more info.

  2. Save your export file to the wp-content/convert directory (the same directory where the WordPress to markdown repo is cloned), and navigate to that directory.

  3. Run the following command in the wp-content/convert directory:

node index.js --save-attached-images=true

The tool will ask you a series of questions.

  • Path to WordPress export file: The name of the file you exported from WordPress
  • Path to output folder: The name of the folder to output the markdown. If the folder does not exist it will be created
  • Create year folders: Organize your posts by year in separate folders
  • Create month folders: Organize your posts by month in separate folders
  • Create a folder for each post: Put each post in a separate folder
  • Prefix post folders/files with date: Prefix each post/folder with the post date (YYYY-MM-DD)
  • Save images attached to posts: Save images attached to posts

Answer these based on your individual setup. One point to note is that putting all the markdown files in the same directory will make the next step of the setup easier (i.e. answering 'No' to questions 2 - 4 above), as you'll see in a minute. If you have images in your postsand you've chosen to create a new folder for each post, you'll end up with a directory structure like this:

 |  +--images
 |  |  +--image-1.png
 |  |  +--image-2.png
 |  +--images
 |  |  +--image-3.png
 |  |  +--image-4.png

If you've chosen to put all your posts in the same directory then the directory structure should look something like this:

| +--image-1.png
| +--image-2.png
| +--image-3.png
| +--image-4.png

Add Layout #

Even though most of the hard work has been automated in terms of converting your WordPress posts to markdown, there's still some cleaning up to do. Eleventy uses layout templates to help you layout your posts and pages. In the base blog template you cloned, these will be in the _includes/layouts directory. In here I have a file called post.njk (the Eleventy base blog template uses Nujunks as a templating engine. Read about other templating engines here.) which dictates how my posts are structured. Eleventy will look at this file when rendering a post and create the related markup.

In order for your posts to use a layout file, the file has to be referenced in the front matter, which is the text at the top of a markdown file enclosed with --- which contains data about that file and it's content. The front matter in the files you've just converted to markdown will look something like this:

title: "Post title"
date: "2018-11-12"

To reference a specific layout we need to add a layout marker in the front matter, like this:

layout: layouts/post.njk
title: "Post title"
date: "2018-11-12"

You can see how doing this could quickly become tedious if you have a large number of posts. As a solution, I wrote this simple JavaScript package that adds the layout reference to the beginning of each markdown (.md) file in the current directory:

    var prepend = require('prepend');
    var fs = require('fs');
    var path = require('path');
    var process = require('process')
    const layoutFile = 'layouts/post.njk' // your layout file name and location
    const matter = `---\nlayout: ${layoutFile}` // build front matter
    const currentDir = path.join(__dirname) //current directory;

    // gets each line from a specific file and puts them into an array (lines)
    function getLines(file) {
      var data = fs.readFileSync(file, 'utf8');
      var lines = data.split('\n');
      return lines

    // reads the current directory and returns a list of files in an array
    fs.readdir(currentDir, function(err, files){
      if(err) {

    // iterate through files
      files.forEach(function (file, index) {

        // only apply to markdown files (.md)
        if(path.extname(file) === '.md') {
          var currentFile = getLines(file);
          var data = '';

          for (var i = 1; i < currentFile.length; i++) {
            // put all the content from the current file, excluding the first line (---) into a variable
            data += currentFile[i] + '\n'

          //overwrite the file with the new content
          fs.writeFile(file, data, 'utf8', function(err){
            } else {
              // if no error, prepend layout text at the beginning of the file
              prepend(file, matter, function(err){
                if(err) {
                } else {
                  //notify completion
                  console.log('[done] ' + file)

To use it:

  1. Create a file called index.js in the directory where all your markdown files are installed.
  2. Copy the above code into index.js
  3. Install prepend in the same directory
npm install prepend --save
  1. run node index.js

A few things to note:

  • You need to have NodeJS installed. To check whether you do, run node -v in Command Prompt or Terminal. If you get a version number, you have NodeJS installed. If not, head to NodeJS and grab a copy.
  • This package will overwrite all the markdown files in the directory so make sure you backup them up first!

Clean Up #

Depending on how your posts are structured, there may be some manual work to do in terms of keeping an eye out for broken links or missing images. Because I basically started from scratch, I didn't have this issue.

Rounding it up #

Now that you've got your base blog in place, you can set about putting your own flavour to it. I would start with the following:

  • Remove the information message from _includes/layouts/base.njk
  • Remove the dummy content such as posts in posts/
  • Add your own posts to the posts/ directory
  • Customise index.css in the css/ directory (this is the main CSS file)
  • Look at using Netlify to host a serverless instance of your blog
  • Look at integrating Netlify Forms for comment forms and management

Enjoy 👍

Share this post:

← Home