URL Cleanup

Reformatting, redirecting, and making archives usable.

I read a great article recently about how Slate cleaned up their URLs. It was a good read and inspired me to take a look at my own site and how I was handling URLs. I wasn鈥檛 satisfied.


The biggest change was simply in the format of the URLs. Instead of using dashes to separate the URL components, slashes are now used. I also dropped the day This was a simple configuration change in Hexo:

# Before
permalink: :title/

# After
permalink: :year/:month/:post_title/

While simple, there鈥檚 a lot of quirks that it smooths over. First, :title is the filename. My files are stored in a directory structure like so: _posts/{year}/{month}/{day}-name.md. Hexo actually took that structure and generated a name by using the parent directories (replacing slashes with dashes).

I found :post_title in the comments of the Hexo docs, and it gives me a lot more control over the URLs. It uses a clean version of the post鈥檚 title (which is stored in each file in YAML front matter). Because that doesn鈥檛 include the directory structure, I can specify that myself. All of that results in much cleaner URLs.

Update: Wow. I got the link format wrong. Apparently it requires a trailing slash to actually output the index.html file in a folder with the post name. Sorry about all the broken posts.


Now that I got the URLs cleaned up, I needed a way to fix any links that have been shared or stored previously. I could wire up a whole bunch of redirects on my host or in CloudFlare, but that involves other systems and I wanted to keep this within Hexo.

Enter hexo-generator-alias.

A single line in each file鈥檚 front matter triggers the plugin to create an empty page that redirects to the correct post.

alias: /2017-11-30-iphone-x/index.html

Determining that URL took a bit of trial-and-error, but I settled on that format which provides the correct folder and handles a few different URL formats (with index.html, with the trailing slash, and without). Success!

Adding that line to each post was a bit time consuming, but I think it was worth it.

Archives (or: making the full path usable)

At this point, I could have stopped. URLs had been cleaned up and all the old URLs were going to correctly redirect to the new paths.

But I wanted more.

One of the things I liked about Slate鈥檚 change is that the URL hints that there is more available. You can chop off the right-most part of the path and find more content. I wanted to do that, too. And with a little bit of configuration, Hexo can do it.

Enter hexo-generator-archive.

By default, the archive generator creates pages under an archives directory. This would not do. I wanted them to be right along with the posts. As it happens, that directory is part of the default config (even though the generator is not part of the default install).

# Before
archive_dir: archives

# After
archive_dir: /

The generator also required a little config of it鈥檚 own:

  per_page: 10
  yearly: true
  monthly: true
  daily: false
  order_by: -date

And it works! Go ahead and find any post and see what was published that same month or year. Each of those pages supports pagination, too.

Bonus: autonofollow

While looking around at the various Hexo plugins, one caught my eye: hexo-autonofollow. Once installed (and enabled in the config file), it automatically adds rel="external nofollow noopener noreferrer" to any external links. It also adds target="_blank" to open them in a new tab. Very useful and requires almost nothing to get the benefits.