A GitHub Pages compatible way of adding anchors to your headings without a plug-in or JavaScript :octocat: https://pure-liquid.allejo.org/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Vladimir Jimenez 1b361fa7e0
Version bump to 1.0.12
3 days ago
.github Update issue templates 2 years ago
_includes Version bump to 1.0.12 3 days ago
_tests Add support for `no_anchor` class (#34) 7 months ago
.editorconfig Don't add newline at EOF in _includes; maybe 4 years ago
.gitattributes Make our Liquid snippet appear as Liquid on GH 9 months ago
.gitignore Initial commit of the snippet 4 years ago
Gemfile Move to GH Actions for unit tests (#24) 2 years ago
LICENSE.md Add license header to the snippet 2 years ago
README.md Add support to generate ids for headers that do not have them (#32) 11 months ago
_config.yml Don't use a theme for our tests 2 years ago
tests.py Upgrade unit test script to Python 3 2 years ago


Jekyll Pure Liquid Heading Anchors

Unit Tests Latest release ko-fi Buy me a coffee

GitHub Pages can't run custom Jekyll plug-ins so when generating anchors for your headings (i.e. h1 - h6), you're stuck with JavaScript solutions that will inject anchors. But what if your users don't have JavaScript enabled on their browsers? If you're building a static website, why not make your anchors static as well?

Sample anchor next to heading

As a part of my "Pure Liquid" series of Jekyll snippets, here is a Liquid snippet that will modify your generated HTML to inject anchors. Want to see it in action? Here are some awesome websites that I know of using this solution .

Want a Table of Contents in your Jekyll layouts without JavaScript or a plug-in?

Check out the sister project over at allejo/jekyll-toc.


Alright, so how do you use it?

  1. Download the anchor_headings.html file from the latest release or the master branch

  2. Toss that file in your _includes folder

  3. Where you typically would put {{ content }} in your layout, you would instead use this Liquid tag to output your page's content:

    {% include anchor_headings.html html=content anchorBody="#" %}

Accessibility is hard and there are many different ways someone may want to handle it. For that reason, this project does not force onto developers any method of handling accessibility. That being said, this project can be configured to be accessible as seen in examples in the wiki.

Layout Inheritance

If this snippet is used in a layout that is inherited by a child layout, it will apply to the child layout as well. If the child layout uses this snippet in addition to the parent layout, then heading anchors will be duplicated. You should only use this snippet in one layout.

🎨 Customization

You may remove anchorBody and add an icon via CSS' content property instead. You may also use HTML in anchorBody and add screen reader friendly markup.

Take a look at the unit tests directory and the wiki page for more examples of how to use this script.


This snippet is highly customizable. Here are the available parameters to change the behavior of the snippet.

Parameter Type Default Description
html string * the HTML of compiled markdown generated by kramdown in Jekyll
beforeHeading bool false Set to true if the anchor should be placed before the heading's content
headerAttrs string '' Any custom HTML attributes that will be added to the heading tag; you may NOT use id; the %heading% and %html_id% placeholders are available
anchorAttrs string '' Any custom HTML attributes that will be added to the <a> tag; you may NOT use href, class or title; the %heading% and %html_id% placeholders are available
anchorBody string '' The content that will be placed inside the anchor; the %heading% placeholder is available
anchorClass string '' The class(es) that will be used for each anchor. Separate multiple classes with a space
anchorTitle string '' The title attribute that will be used for anchors; the %heading% placeholder is available
h_min int 1 The minimum header level to build an anchor for; any header lower than this value will be ignored
h_max int 6 The maximum header level to build an anchor for; any header greater than this value will be ignored
bodyPrefix string '' Anything that should be inserted inside of the heading tag before its anchor and content
bodySuffix string '' Anything that should be inserted inside of the heading tag after its anchor and content
generateId bool false Set to true if a header without id should generate an id to use.

* This is a required parameter


The performance impact of this snippet on your site is pretty negligible. The stats below were gotten from Jekyll's --profile option.

Filename                                         | Count |    Bytes |  Time

# performance on docs.travis-ci.com from ~Aug 2018
_includes/anchor_headings.html                   |   193 | 1667.96K | 0.695


This snippet may be redistributed under the MIT license.