Jekyll is a great static site tool. If you're using GitHub Pages, it comes with it for free, making it a very useful tool for any public blog or website. It comes, though, with one common problem that I've yet to come across a good solution for: relative paths.
Next: Why are relative paths a problem?
Let's say you have an innocent URL in your layout like the one below. This is a relative path, not an absolute one that begins with /
. It resolves based on wherever it's included from.
<link href="assets/style.css" rel="stylesheet" />
This works well in pages of your site placed in the root directory. Once you path one level deep though, you'll encounter problems.
From this page... | Base | Final URL | Result |
---|---|---|---|
/index.html | / | /assets/style.css | Good ✓ |
/me.html | / | /assets/style.css | Good ✓ |
/about/profile.html | /about | /about/assets/style.css | Wrong ✗ |
One workaround is to use absolute paths by adding a /
in the beginning.
<link href="/assets/style.css" rel="stylesheet" /> ^
This works great for sites that live on its own domain. When your site will be hosted in a sub-directory (such as the case with GitHub Project Pages), this absolute path will not resolve to /project/assets/style.css
as you probably would have intended.
If your site is in... | It resolves to... | |
---|---|---|
user.github.io/ | /assets/style.css | Good ✓ |
user.github.io/project/ | /assets/style.css | Wrong ✗ |
This snippet below automatically determines the relative base and stores it in the variable base
. Place it in your partials path, and include the partial in your layouts.
{% assign base = ''
%}{% assign depth = page.url | split: '/' | size | minus: 1
%}{% if depth <= 1
%}{% assign base = '.'
%}{% elsif depth == 2
%}{% assign base = '..'
%}{% elsif depth == 3
%}{% assign base = '../..'
%}{% elsif depth == 4
%}{% assign base = '../../..'
%}{% endif
%}
Tip: You can also collapse this into one line.
You can then use it as a prefix to URLs, like the examples below. You don't need to include
it all the time—just include it once in your layouts and it will be available everywhere.
{% include base.html %}
<link href="{{base}}/assets/style.css" rel="stylesheet" />
<a href="{{ base }}">Back to home</a>
<a href="{{ base }}/about.html">About me</a>
<a href="{{ base }}{{ post.url }}">Read "{{ post.title }}"</a>