URL Shortener in less than 30 lines of code

Published: 2020-11-16 by Pradeep Gowda.
Tagged: code, javascript, nginx

Earlier I saw a “show:” post on on HN, which used github’s issues as a database to store information and use that to create a “javascript only URL Shortener”. I thought it could be done without so many components.

Problem statement

  1. Have a simple way to associate a short-code with a long url. Say “gh” to my github profile “https://github.com/btbytes/”
  2. Have a URL where I can use the short code to hit the long URL. eg: https://www.btbytes.com/go/gh

Implementation

We will use a JSON file to store the short code and the long URL like this:

{
    "gh": "https://github.com/btbytes",
    "li": "https://www.linkedin.com/in/btbytes/"
}

We will use an HTML file with Javascript code to look up the short code and see if we have a corresponding entry, if we do, then redirect the browser to the URL.

<!doctype html>
<script>
    const urlParams = new URLSearchParams(window.location.search);
    const hop = urlParams.get('hop')
    var xmlhttp = new XMLHttpRequest();
    xmlhttp.onreadystatechange = function() {
        if (this.readyState == 4 && this.status == 200) {
            var links = JSON.parse(this.responseText);
            const msg = document.getElementById("message");
            if (hop.match(/[a-zA-Z0-9]+/g) && hop in links) {
                const link = links[hop];
                msg.innerHTML = "redirecting: (" + hop + ") to : <a href=" + link + ">" + link + "</a>"
                window.location.replace(link)
            } else {

                msg.innerHTML = "No Such Shortcut: " + hop;
            }
        }
    };
    xmlhttp.open("GET", "/go.json", true);
    xmlhttp.send();
</script>
<body>
    <h1>URL Shortener</h1>
    <h2 id="message"></h2>

Copy this file to the root of the website, which in my case would result in this file living here: https://www.btbytes.com/go.html. We can use this URL right away to do URL shortening by passing the short-code (gh) as a value for the URL parameter (hop) like this: https://www.btbytes.com/go.html?hop=gh

This still does not look “clean”. I’d really want to be able to do https://www.btbytes.com/go/gh

I use nginx on this server, so I can use a rewrite rule to rewrite https://www.btbytes.com/go/gh to https://www.btbytes.com/go.html?hop=gh

rewrite ^/go/([a-zA-Z0-9])+$ /go.html?hop=$1 last;

You can see this URL shortener by visiting https://www.btbytes.com/go/gh

iti.