Short URLs

The existing hash.FNV32a function gets you pretty close.

layouts/partials/make-short-url.html
{{ $html := printf `<!DOCTYPE html>
<html lang="%[1]s">
  <head>
    <title>%[2]s</title>
    <link rel="canonical" href="%[2]s">
    <meta name="robots" content="noindex">
    <meta charset="utf-8">
    <meta http-equiv="refresh" content="0; url=%[2]s">
  </head>
</html>
` .Language.LanguageCode .Permalink }}

{{ $hash := .Path | hash.FNV32a }}
{{ $publishPath := path.Join site.LanguagePrefix $hash "index.html" }}
{{ (resources.FromString $publishPath $html).Publish }}
{{ return ($hash | absLangURL) }}

Then call the partial from your base template or single template or whatever.

{{ $shortURL := partial "make-short-url.html" . }}
<p>Short URL: <a href="{{ $shortURL }}">{{ $shortURL }}</a></p>

Every time the partial is called, it writes an HTML redirect file to disk, something like:

public/4042937710/index.html
<!DOCTYPE html>
<html lang="en-US">
  <head>
    <title>http://example.org/posts/post-1/</title>
    <link rel="canonical" href="http://example.org/posts/post-1/">
    <meta name="robots" content="noindex">
    <meta charset="utf-8">
    <meta http-equiv="refresh" content="0; url=http://example.org/posts/post-1/">
  </head>
</html>

On a monolingual site the permalink looks like this:

http://example.org/4042937710

On a multilingual multi-host site, with defaultContentLanguageInSubdir = true, the permalinks look like this:

http://example.org/en/4042937710
http://example.org/de/4042937710

On a multilingual multi-host site, with defaultContentLanguageInSubdir = false, the permalinks look like this:

http://example.org/4042937710
http://example.org/de/4042937710

The hash is based on a page’s logical path, so the shortened URL is not affected by changes to:

  • The title, date, slug, or url front matter fields
  • The permalinks key in your site configuration

This approach will not work if uglyURLs = true in your site configuration, but I suppose you could modify the partial to accommodate that.

5 Likes