How to capture and redirect old blog post URLs to a stand alone Ghost blog instance

Let's say you are moving your whole old blog to your brand new Ghost stand alone instance.

Then you most likely probably have some old blog post URLs you would like to make sure still works, even though you are moving to Ghost.

For example your old post URL:

  • http://old.myblog.com/post/2011-11-26-mypost.html

should now go to:

  • http://myblog.com/2011-11-26-mypost/

For me personally, I had around 50 legacy URLs I wanted to point to new Ghost blog posts.

You can of course solve this in various ways, such as creating (reverse) proxies and URL rewrites using various softwares such as Apache webserver or nginx. However since I am hosting Ghost as a one-click DigitalOcean app, I wasn't interested in maintaining a second service just for routing the legacy blog post URLs.

Luckily, if you feel comfortable with JavaScript, Node.js and Regular Expressions, then you can create these redirects directly in the Ghost instance.

What you need to do is open up the file /ghost/core/server/routes/frontend.js and scroll down to where the first routing is declared:

frontendRoutes = function frontendRoutes(middleware) {  
    var router = express.Router(),
        subdir = config.paths.subdir,
        images-in-html-and-css-to-decrease-the-number-of-http-request
        routeKeywords = config.routeKeywords,
        indexRouter = express.Router(),
        tagRouter = express.Router({mergeParams: true}),
        authorRouter = express.Router({mergeParams: true}),
        rssRouter = express.Router({mergeParams: true}),
        privateRouter = express.Router();

!HERE!

    // ### Admin routes
    router.get(/^\/(logout|signout)\/$/, function redirectToSignout(req, res) {
        /*jslint unparam:true*/
        res.set({'Cache-Control': 'public, max-age=' + utils.ONE_YEAR_S});
        res.redirect(301, subdir + '/ghost/signout/');
    });

Then you can include your own routing that does 301 permanent redirects, by including code similar to this:

router.get(/^\/post\/.+$/, function redirectOldURLRouter(req, res) {

    var redirects = {
        "/post/2011-11-26-mypost/": "/2011-11-26-mypost/",
        "/post/2011-11-26-mypost.html/": "/2011-11-26-mypost/"
    };

    var redirectPath = redirects[req.url];
    var redirectURL;

    if ( redirectPath ) {

        redirectURL = "http://myblog.com.me" + redirectPath;
        console.log("REDIRECT", req.url + " -> " + redirectURL);

    } else {

        redirectURL = "http://myblog.com.me/?" + req.url;
        console.log("REDIRECT, BUT NO HIT", req.url + " -> " + redirectURL)

    }

    res.redirect(301, redirectURL);

});

Restart Ghost and try out an old URL. It should be redirected correctly to your new blog post!

Leave blog comments and discuss on Reddit

Gotchas

  • If you have old URLs using other sub domains, point all these old sub domains to the same domain your Ghost instance now resides at
  • The routing can't handle file extensions, so your property value needs to end with a slash /, for example /post/2011-11-26-mypost.html/
  • On DigitalOcean, the file was /var/www/ghost/core/server/routes/frontend.js
  • On DigitalOcean, you can start Ghost production version with the command npm start --production to see the console.log outputs.
  • On DigitalOcean, you can stop/start/restart the Ghost service with the command service ghost start/stop/restart