Migrating from Wordpress to Ghost: 301'ing some urls

I just migrated from Wordpress to Ghost, for probably the same reason as most people - I got tired of the mass of crazy that Wordpress has become. I just want to write shit, and Wordpress was almost getting in the way of that.

The migration process was ridiculously easy thanks to both Ghost and Digital Ocean - I clicked a few buttons, waited 50 seconds and had a new Ghost installation. I exported my posts from Wordpress, imported them into Ghost and, boom, done.

Well, basically.

Those dang slugs

Wordpress, by default, sets up URLs in the form of http://yourblog.com/yyyy/MM/dd/kinda-nice-post-title. Ghost, by default, uses the form http://yourblog.com/kinda-nice-post-title. I like the Ghost way better, but that meant all links to my posts would be broken.

Let's write some rewrites

The best way to get around this is to set up 301 redirects , so that not only do the old links automatically get redirected to the new links, search engines like Google know it's a permanent redirect and therefore forget the old url and use the new one.

Most instances of Ghost are running under nginx, which is an open source web host, and it has a rewrite module (ngx_http_rewrite_module) installed by default that helps us here.

Configuration files

Nginx uses json formatted .conf files for it's configuration settings. There are 2 files we're going to look at: nginx.conf and [your site name] The main file is nginx.conf and it lives in /etc/nginx/. That file has a bunch of settings that apply to all sites. The [your site name] file has settings that apply to only your site, and it lives in /etc/nginx/sites-enabled/*. The nginx.conf file includes this line:

include /etc/nginx/sites-enabled/*;

that imports the site settings into the main file.

We'll be editing the [your site name] file, since these rewrites will probably only apply to your site. From here on out, I'll use ghost instead of [your site name] since that's what my site is called.

(Ir)Regular expressions

The rewrite module uses regular expressions to match urls, and we'll use one that matches /yyyy/MM/dd/pretty-url and rewrite it to only /pretty-url. The regex is:


This basically says "if the url starts with 4 digits, and then has a slash and 2 digits, and then has another slash and 2 other digits, grab everything after that."

To apply this, edit your site configuration file using vim:

vim /etc/nginx/sites-enabled/ghost

You'll see a server node, and inside of that a location node. In the location node, add the following rule:

rewrite "\d{4}/\d{2}/\d{2}/(.*)$" /$1 permanent;

So your file should look something like this:

server {
    #some stuff
    location / {
        #some stuff
        rewrite "\d{4}/\d{2}/\d{2}/(.*)$" /$1 permanent;

That says "if the url matches this regular expression, rewrite the last bit (the (.*)$) as just /$1, where $1 is the capturing group. And do it permanently, as a 301 redirect.

Save the file, and restart nginx:

sudo service nginx restart

Now hit an old url and watch the magic happen.

* Kind of. It actually lives in /etc/nginx/sites-available and is symbolically linked to sites-enabled.