On Apache servers, a RedirectMap may be used to import bulk redirects. This provides an ideal solution for creating a self-hosted short URL service for any website, particularly static sites generated with Jekyll.

To implement a URL shortener using Jekyll and Apache, begin by simply adding a new key (e.g. shorturl) to the front matter of any relevant posts. For example:

---
shorturl: example
---

Next, create a new file (e.g. shorturls.txt) which contains the following liquid code:

{% for post in site.posts %}{% if post.shorturl %}{{ post.shorturl }} {{ site.url }}{{ post.url }}
{% endif %}{% endfor %}{% for page in site.pages %}{% if page.shorturl %}{{ page.shorturl }} {{ site.url }}{{ page.url | remove: "index.html" }}
{% endif %}{% endfor %}

Build the site. Once the site is built, a new text file should exist resembling the following:

example https://www.example.com/this-is-an-example

Once the redirect map file is created, instruct Apache to use the file by adding the RedirectMap to the Apache configuration (typically in httpd.conf, or an included vhost) by using the following:

<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteBase /
  
  # IMPORTANT: Make sure this file exists
  # RewriteMap shorturl txt:/path/to/shorturls.txt
  RewriteMap shorturl dbm:/path/to/shorturls.map

  # URL shortener with fallback
  RewriteRule ^(.*)$ ${shorturl:$1|https://example.com/$1} [R=302,L]
</IfModule>

Note: The RewriteRule above uses 302 redirects when redirecting, and allows non-existent paths to fall through/fallback to the unshortened URL.

This may be setup on a primary domain (which may introduce conflicts as new URLs are created), or this may be setup on a secondary domain (e.g. short domain) or subdomain to reduce the possibility of naming collisions.

It may be desirable to prevent direct access to the redirect map file; this can be accomplished with a simple RedirectRule:

# Disable direct access to short URL map
RewriteCond %{REQUEST_URI} ^/shorturls\. [NC]
RewriteRule ^ - [R=404]

Faster Redirects with DBM files

As the number of redirects grows, this solution may become slower (though the number of redirects would need to be very large). In any case, the httxt2dbm command can be used to create dbm files for use with RewriteMap. A dbm database file contains key/value pairs which map the redirect data; this works exactly the same way as a txt map, but it is much faster, because the dbm file is indexed. Rather than processing each line of the file until a match is found (which happens for txt files), the dbm file allows Apache to jump right to the relevant entry. This can greatly improve performance for large data sets.

httxt2dbm -i shorturls.txt -o shorturls.map

Note that with some dbm types, more than one file is generated, with a common base name. For example, you may have two files named mapfile.map.dir and mapfiile.map.pag. This is normal, and you need only use the base name mapfile.map in your RewriteMap directive.

https://httpd.apache.org/docs/current/rewrite/rewritemap.html#dbm

This command may be introduced into build logic, allowing the created dbm file(s) to be created automatically whenever content changes.