articles How to add permanent redirects to NGINX

Published → Monday, December 7, 2020 10:43 PM

Problem

This site has been rebuild, moved and moved again. From static Html to Wordpress, to I don't remember what -- and back again. While this is just a personal site; it is important to keep all the links intact. Damnit, those took effort!

SEO. Google indexing, ranking, external links... are vitally important for your site. It took time and effor to build them.

Solution

First plan was to write a fancy Nuxt Module that will generate the rewrite rules, add them to a file, and Docker would put it in the correct place. But. Time.
And waaaaay too complicated & ambitious → after moving this would be useless. 🤦‍♀️

Assuming you have moved all the content from your Wordpress to NuxtJs using the Hugo Export plugin.

Step 1. Generate the new site locally

This will generate AND output all the new routes

✔ Generated route "/journal/alan-watts-the-story-of-the-chinese-farmer"                                                                                                                                19:52:39
✔ Generated route "/journal/life-as-a-web-developer-weve-been-here-before"                                                                                                                             19:52:39
✔ Generated route "/nantucket/nantucket-2"

You can be as lazy as I am and past the output to a spreadsheet. Using Numbers the output was nicely put in different cols. 😎

Step 2. Use the tool you want to create the NGINX syntax

You can do this with Numbers, Excel, Coderunner, ... really any tool you're familiar with.

In the past that was Excel for me, now it's Tinkerwell. Using all the power of Laravel is just FAST! 🎉

BTW 'search & replace' is your best friend - use regexps or just replace \n with ,\n. On hintsight I'm pretty sure this can be completly done with regexp.. but why? 😏

Copy the column with the url, and put those in an array.

$new=[
    "/journal/life-as-a-web-developer-i-bet-it-is",
    "/journal/alan-watts-the-story-of-the-chinese-farmer",
    "/journal/life-as-a-web-developer-weve-been-here-before",
    ...
    ];

Loop and generate the new syntax.

  • we had the same permalinks in wordpress as the name of our new files
  • to have a permanent redirect, use the code 301
  • to have some formatting use \t for a tab; \n for a newline
collect($new)->each(function ($newurl) {
    // rewrite ^oldurl newurl permanent;
    $oldurl = Str::afterLast($newurl, '/');
    echo "location = /$oldurl/ {\n\treturn 301 $newurl;\n}\n";
})

We are using the NGINX best practice: the location → ruling instead of the rewrite.

Step 3. Docker

I'm using my Pagespeed repo, as a base docker image for this website.

Basically you create a txt-file with these new locations and include them in your server config. Just be careful not to use a .conf extension. just leave it extension-less

default.conf
server {
    listen 80 default_server;
    
    ...
    
    include /etc/nginx/conf.d/redirects;
}
Dockerfile
COPY  docker/redirects /etc/nginx/conf.d/redirects
COPY  docker/nginx.conf /etc/nginx/conf.d/default.conf

Result

Test

❯ curl --head http://localhost:5080/arkanoid

Output

+ HTTP/1.1 301 Moved Permanently
Server: nginx
Date: Mon, 07 Dec 2020 20:20:51 GMT
Content-Type: text/html
Content-Length: 162
+ Location: http://localhost/projects/arkanoid
Connection: keep-alive
...

🎉