How to create redirects for static websites

Michael Buckbee

07 May 2023

Ah, static websites, the old-fashioned love child of HTML, CSS, and JavaScript, without all those fancy-pants back-end shenanigans. Static sites are pre-rendered, lightning-fast masterpieces delivered to your browser, like a beautiful painting that never changes.

Developers dig them for their simplicity, wicked-fast load times, and ease of deployment.

Static sites do some great things

Static websites offer several advantages for developers, such as minimal server-side processing, which results in quicker load times and reduced server resources. They are also easier to maintain and deploy, as there is no need to manage databases or server-side logic. This combination of speed, simplicity, and ease of use makes static websites an appealing choice for many developers and use cases, particularly for small-scale projects and content-driven websites.

Static sites have problems

Static websites, while elegant in their simplicity, do come with a few management wrinkles that can leave developers scratching their heads. One such challenge is the inability to easily set server-side redirects. Since static sites rely on pre-rendered content and lack server-side processing, implementing redirects can be cumbersome. For instance, if a URL changes or a page is moved, you might find yourself mired in a labyrinth of manual updates or resorting to less-than-ideal client-side solutions, such as JavaScript redirects or setting meta-refreshes on a page.

Meta Refresh Code

<head>
  <meta http-equiv="refresh" content="1; URL='https://example.com/path-to-redirect-to'" /> 
</head>

Javascript Redirect Code

window.location.replace("http://example.com/redirect-path");

While these client-side solutions technically work, they don't actually issue a crisp HTTP 301 response code from the server, they won't work for folks who have JS disabled, and they often show multiple full-page refreshes.

Further, suppose you care at all about SEO. In that case, Google's crawler won't follow the client-side redirects. If you've updated a dev tutorial to no longer describe an outdated and deprecated way of implementing something, Google will never know about it.

I found myself in this exact spot with an article I'd written on Rack::Attack for the Expedited Security site, but that is much more relevant to have here on the Wafris site.

The Solution

My buddy, Chris Fidao, did me a huge favor and wrote the following guide on how to use Nginx to proxy my existing static site through Fly.io and give it superpowers usually only reserved for full-on servers; amongst these: precise control over redirects.

How it all fits together

undefined

Now, there's a decent chance that if you aren't familiar with DNS, Docker, or Nginx, you're going to look at this as hopelessly complicated, throw up your hands and go back to browsing r/programmerhumor.

That would be a mistake as while this solution leverages all of those technologies; it boils down to updating a single text file with the redirect you need and about 10 minutes of button clicking, most of which was spent waiting for DNS to update.

Fly.io Basics

  1. Signup on Fly.io
  2. Update to the latest flyctl, just because. It has changed a lot in the last month or so; there have been significant updates.
  3. Create a new directory and then a file in it named Dockerfile, and paste the following two lines into it:
FROM nginx:1.23
COPY default.conf /etc/nginx/conf.d/default.conf
  1. create a new Fly app and deploy it:
fly launch
# Choose a name
# Choose an organization (if you have multiple, it asks you)
# Choose a region. You can go multi-region later if you'd like
# No pgsql, no redis (but good to know you can add it later)
# Deploy now
  1. From within Fly.io
  • You'll want to assign this app an IP address and point DNS to the domain to that IP.
  • You'll want to create an SSL in Fly.io
  1. Now create a file default.conf with your specific site and redirect
server {
    listen 8080;
    listen [::]:8080;
    server_name  _;

    access_log /dev/stdout;
    error_log /dev/stderr;

    # using "=" here is an exact match for the URI
    # instead of a prefix match. This is a prefix match: `location / {}`
    location = /blog/ultimate-guide-to-rack-attack/ {
        return 301 https://wafris.org/guides/ultimate-guide-to-rack-attack;
    }

    location / {
        proxy_pass https://YOUR_STATIC_SITE_HOST_DOMAIN;
        proxy_set_header X-Forwarded-Host $http_host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

Making these changes means that the domain will not longer point to your current static site host, so the proxy setting in default.conf will need to change to point to the correct location (usually, this is something like your-site-name.example.com or example.com/site-name)

Summing Up

After you complete Fly.io DNS+SSL setup, you should have two files in your local folder:

  1. default.conf - Nginx config file that you customized for your static site host and the redirects you wanted to add.
  2. Dockerfile - tells Fly that you want to use the Nginx docker they have and on deploy to update it with the default.conf file

Run flyctl launch to update your app and enjoy your redirects.

Do this next

We're on a mission to better secure every web app on internet. Here's some ways you can jump in:

1. Check out our Open Source Web Application Firewall

Wafris is the free open source WAF that you can use to understand and visualize the requests hitting your apps and then take steps to protect them. It's still in early development, but you can signup for the waitlist to get early access at wafris.org

2. Investigate IP addresses with our IP Lookup service

Bad bots and probes hit sites within minutes of being put on the Internet. Sort the good from the bad by identifying request IPs as coming from bots, Tor networks, VPNs, proxies and malware hosts at wafris.org/ip-lookup

3. Anything else?

If you have any questions or need help finding the right way to handle web app security issues, please let us know at: help@wafris.org