Build your own URL shortener in 15 minutes
Tags: showdev, opensource, tutorial
Published: 2019-01-20 07:40:37

The [Commons Host](https://commons.host) CDN platform recently introduced support for custom HTTP response headers and redirect rules. Let's use these features to build our own private URL shortener, with support for a custom domain name and Google Analytics tracking. Did I mention this is all free of charge and 100% open source?

Let's get started.

You could use an existing Commons Host site but this tutorial shows how to get started from scratch. These instructions are intended for Mac OS or Linux.

## Project Directory

Start by creating the following project directory structure, then locally installing the Commons Host CLI and `short` tools with NPM.

```
short/                 // Project directory
| CNAME                // File
| commonshost.json     // File
| package.json         // File
\ public/              // Directory
  \ redirect/          // Directory
    \ index.html       // File
```

The project directory is self contained and does not make any global changes to your system. Create it anywhere you prefer, for example in your home directory (`~`).

Run these commands from a terminal to create the project directory.

```
$ mkdir -p short/public/redirect
$ cd short
$ touch CNAME commonshost.json public/redirect/index.html
$ npm init -y
$ npm install -D @commonshost/cli @commonshost/short
```

## Domain Name and DNS

Set up your domain name.

Use either a free Commons Host subdomain, or your own registered custom domain name.

### Option A) Free `*.commons.host` subdomain

Edit the `CNAME` file with your free Commons Host subdomain.

```
$ echo "your-sub-domain.commons.host" >| CNAME
```

Replace `your-sub-domain.commons.host` with any subdomain you like. This tutorial uses `short.commons.host`, so choose a unique name for your own URL shortening service.

No additional DNS configuration is required with a Commons Host subdomain. The DNS setup for all `*.commons.host` subdomains already has a wildcard `CNAME` record pointing to `commons.host`.

### Option B) Custom Domain Name

Edit the `CNAME` file with your registered custom domain name.

```
$ echo "your-name.example" >| CNAME
```

Replace `your-name.example` with your actual registered custom domain name.

You must also create a `CNAME` record pointing from `your-name.example` to `commons.host` at your DNS provider's dashboard. That `CNAME` record will direct users to their nearest Commons Host edge server.

Note: With Cloudflare DNS you may encounter a redirect loop when using *Flexible SSL* (the default setting). Commons Host enforces full TLS and never serves unencrypted content. To solve this you can either:

- Disable the Cloudflare CDN for your CNAME record by setting: **DNS > DNS Records > Status > DNS Only**
- Or, leave the Cloudflare CDN enabled but configure the setting: **Crypto > SSL > Full SSL**

## Configuration File

Save this JSON boilerplate as: `commonshost.json`

This contains the necessary custom header rule and a placeholder for the URL redirects.

```json
{
  "hosts": [
    {
      "headers": [
        {
          "uri": "/redirect/{?url,}",
          "fields": {
            "Refresh": "2; {url}"
          }
        }
      ],
      "redirects": []
    }
  ]
}
```

## Redirect Page

Save this HTML boilerplate as: `public/redirect/index.html`

To set up Google Analytics replace `GA_TRACKING_ID` in the code below with your Google Analytics tracking ID (e.g. `UA-12345678-1`). See the [Google Analytics documentation](https://support.google.com/analytics/answer/1008080?hl=en) for details.

Feel free to customise or remove any Commons Host branding. You have full control over your website.

```html
<!DOCTYPE html>
<html>
  <head>
    <script async src="https://www.googletagmanager.com/gtag/js?id=GA_TRACKING_ID"></script>
    <script>
      window.dataLayer = window.dataLayer || []
      function gtag(){dataLayer.push(arguments)}
      gtag('js', new Date())
      gtag('config', 'GA_TRACKING_ID')
    </script>
    <title>Redirecting</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <style>
      body { text-align: center; font-family: sans-serif; }
      a { color: black; }
    </style>
  </head>
  <body>
    <main>
      <h1>Redirecting</h1>
      <p id="location"></p>
    </main>
    <footer>
      Powered by 🐑 <a href="https://commons.host" rel="noopener">Commons Host</a>.
    </footer>
    <script>
      if ('URLSearchParams' in window) {
        const params = new URLSearchParams(location.search)
        if (params.has('url')) {
          const to = document.createElement('a')
          const url = params.get('url')
          to.href = url
          to.textContent = url
          document.querySelector('#location').appendChild(to)
        }
      }
    </script>
  </body>
</html>
```

## Sign Up to Commons Host

Create a Commons Host account via the CLI tool. This saves a token in `~/.commonshost` that keeps you authenticated on this machine.

```
$ npx commonshost signup
```

Enter an email address, username, and password to create your account.

```
? Email address: sebdeckers83@gmail.com
? Username: seb
? Password: [hidden]
  ✔ Registering account
  ✔ Creating new authentication token
  ✔ Saving credentials
```

## Shorten a URL

The `short` command creates a new redirect rule and prints the resulting short URL.

```
$ npx short https://en.wikipedia.org/wiki/Longest_words
🔗 https://short.commons.host/1302
```

The `redirects` section of your `commonshost.json` configuration file should now contain something like this:

```json
"redirects": [
  {
    "from": "/1302",
    "to": "/redirect/?url=https%3A%2F%2Fen.wikipedia.org%2Fwiki%2FLongest_words"
  }
]
```

Tip: Run `npx short --help` to see more advanced options. For example the `--emoji` option will generate random emoji for shortened URLs. 🤨

## Deploy to Commons Host

```
$ npx commonshost deploy
To cancel, press Ctrl+C.

Detected options file: commonshost.json
To override, use: --options "path"

Deploying:

  Directory: 	~/short
  File count:	1
  Total size:	1.84 kB
  URL:		https://short.commons.host
  Options:	~/short/commonshost.json

  ✔ Uploading
```

Finished! Enjoy your personal URL shortener powered by Commons Host.

## Summary

To shorten another URL, just repeat the final two commands from within the project directory:

1. `npx short https://some.really.long.url.example/foo/bar.html`
1. `npx commonshost deploy --confirm`

Check the [server documentation](https://help.commons.host/server/configuration/host/) to learn how to customise your Commons Host site further, like setting up a `404` fallback HTML page.

Thanks to [@donavon](https://twitter.com/donavon) for the feedback on this tutorial.