Table of Contents

Commonly used on the Article page, a table of contents provides an overview of the structure of the page with links to each section.

The patterns on this page are designed for use with our Table of Contents extension, but can be used as standalone micro-templates.

Within page content

Simple ordered list
View code
<template id="tmpl-table-of-contents">
  <% if (items.length > 1) { %>
    {{~#if settings.table_of_contents_heading}}
      <h4>
        {{#if settings.use_translations}}
          {{dc settings.table_of_contents_heading}}
        {{else}}
          {{settings.table_of_contents_heading}}
        {{/if}}
      </h4>
    {/if}}
    <ol>
      <% items.forEach(function(item) { %>
        <li class="list-item">
          <a class="inline-block px-2 hover:no-underline" href="<%= item.html_url %>">
            <%= item.name %>
          </a>
        </li>
      <% }); %>
    </ol>
  <% } %>
</template>
Simple unordered list
View code
<template id="tmpl-table-of-contents">
  <% if (items.length > 1) { %>
    {{~#if settings.table_of_contents_heading}}
      <h4>
        {{#if settings.use_translations}}
          {{dc settings.table_of_contents_heading}}
        {{else}}
          {{settings.table_of_contents_heading}}
        {{/if}}
      </h4>
    {/if}}
    <ul>
      <% items.forEach(function(item) { %>
        <li class="list-item">
          <a class="inline-block px-2 hover:no-underline" href="<%= item.html_url %>">
            <%= item.name %>
          </a>
        </li>
      <% }); %>
    </ul>
  <% } %>
</template>
Ordered list with borders
View code
<template id="tmpl-table-of-contents">
  <% if (items.length > 1) { %>
    {{~#if settings.table_of_contents_heading}}
      <h4>
        {{#if settings.use_translations}}
          {{dc settings.table_of_contents_heading}}
        {{else}}
          {{settings.table_of_contents_heading}}
        {{/if}}
      </h4>
    {/if}}
    <ol class="list-bordered list-inside p-0 mb-6">
      <% items.forEach(function(item) { %>
        <li>
          <a class="inline-block py-3 px-2 text-inherit hover:no-underline" href="<%= item.html_url %>">
            <%= item.name %>
          </a>
        </li>
      <% }); %>
    </ol>
  <% } %>
</template>
Card with list group
View code
<template id="tmpl-table-of-contents">
  <% if (items.length > 1) { %>
    <div class="my-5 bg-white border border-radius shadow">
      {{~#if settings.table_of_contents_heading}}
        <h4 class="uppercase tracking-wide px-5 py-4 my-0 border-bottom">
          {{#if settings.use_translations}}
            {{dc settings.table_of_contents_heading}}
          {{else}}
            {{settings.table_of_contents_heading}}
          {{/if}}
        </h4>
      {/if}}
      <ol class="list-unstyled list-bordered font-size-md p-0 mb-0">
        <% items.forEach(function(item, index) { %>
          <li class="flex text-gray-700">
            <a class="flex-1 px-5 py-3 text-inherit hover:no-underline" href=" <%= item.html_url %>">
              <%= item.name %>
            </a>
            <span class="px-5 py-3">
              <%= index + 1 %>
            </span>
          </li>
        <% }); %>
      </ol>
    </div>
  <% } %>
</template>
Callout with two column list
View code
<template id="tmpl-table-of-contents">
  <% if (items.length > 1) { %>
    <div class="my-5 px-6 py-3 bg-gray-100 border-left border-4 border-radius border-primary">
      {{~#if settings.table_of_contents_heading}}
        <h3 class="my-5 uppercase tracking-wide font-size-base">
          {{#if settings.use_translations}}
            {{dc settings.table_of_contents_heading}}
          {{else}}
            {{settings.table_of_contents_heading}}
          {{/if}}
        </h3>
      {{/if}}
      <ol class="list-unstyled row row-lg">
        <% items.forEach(function(item, index) { %>
          <li class="sm:col-6 xl:col-4">
            <a class="block py-2" href="<%= item.html_url %>">
              <%= item.name %>
            </a>
          </li>
        <% }); %>
      </ol>
    </div>
  <% } %>
</template>

Collapsible

Collapsible boxed list
View code
<template id="tmpl-table-of-contents">
  <% if (items.length > 1) { %>
    <div class="bg-gray-100 border border-radius border-gray-200 px-5 my-5 min-w-50 md:inline-block md:float-right md:ml-5 md:py-4 lg:px-6" x-data="{ isExpanded: false }" x-on:collapse:show="isExpanded = true" x-on:collapse:hide="isExpanded = false">
      {{~#if settings.table_of_contents_heading}}
        <h4 class="flex align-items-center justify-content-between my-4">
          {{#if settings.use_translations}}
            {{dc settings.table_of_contents_heading}}
          {{else}}
            {{settings.table_of_contents_heading}}
          {{/if}}
          <button class="not-a-button circle cursor-pointer w-6 h-6 md:hidden hover:bg-gray-300" data-toggle="collapse" data-target="#toc-links">
            <svg class="svg-icon pointer-events-none" :class="{ 'rotate-180': isExpanded }" xmlns="http://www.w3.org/2000/svg" focusable="false" viewBox="0 0 12 12" aria-hidden="true">
              <path fill="none" stroke="currentColor" stroke-linecap="round" d="M3 4.5l2.6 2.6c.2.2.5.2.7 0L9 4.5"></path>
            </svg>
          </button>
        </h4>
      {{/if}}
      <div class="collapse md:expand" id="toc-links">
        <ul class="list-unstyled font-size-base">
          <% items.forEach(function(item) { %>
            <li>
              <a class="block py-1 text-inherit hover:no-underline" href="<%= item.html_url %>">
                <%= item.name %>
              </a>
            </li>
          <% }); %>
        </ul>
      </div>
    </div>
  <% } %>
</template>

Within sidebar

Our themes offer the ability to present table of contents elements in a left or right-hand sidebar using theme settings. Sidebar elements appear on larger screen sizes, stick to the top of the page when a visitor scrolls and automatically highlight the active section of the page.

Sticky sidebar navigation with Scrollspy
View code
<template id="tmpl-table-of-contents">
  <% if (items.length > 1) { %>
   <div class="sticky-top{{#unless settings.sticky_header}} pt-4 -mt-4{{/unless}}"{{#if settings.sticky_header}} style="padding-top: {{settings.header_height}}; margin-top: -{{settings.header_height}};"{{/if}}>
      {{~#if settings.table_of_contents_heading}}
        <h3 class="font-size-lg mt-6">
          {{#if settings.use_translations}}
            {{dc settings.table_of_contents_heading}}
          {{else}}
            {{settings.table_of_contents_heading}}
          {{/if}}
        </h3>
      {{/if}}
      <ol class="nav nav-pills flex-column font-size-md">
        <% items.forEach(function(item) { %>
          <li class="nav-item">
            <a class="nav-link border-radius" href="<%= item.html_url %>">
              <%= item.name %>
            </a>
          </li>
        <% }); %>
      </ol>
    </div>
  <% } %>
</template>

On the Article page

Our themes allow you to display table of contents elements on the Article page within article content or in a left or right-hand sidebar.

You can add one of several built-in styles using the Table of Contents setting in the Article page elements setting group. Most themes have 4 or 5 built-in styles.

Custom patterns can be added into a theme by copying-and-pasting the pattern code into the bottom of the Article page template (article_page.hbs).

If you’re planning to use a custom sidebar pattern, ensure that you select the “In sidebar (left)” or “In sidebar (right)” option in the Table of Contents setting.

Related patterns