Vertical navigation

Vertical navigation menus can be added and configured using theme settings or used anywhere in your help center.

Simple lists

The following patterns represent simple vertical navigation list styles that you can use to present categories, sections, articles or other help center objects.

<template id="tmpl-sidebar-navigation">
  <% if (categories.length) { %>
    <nav class="nav flex-column my-6">
      <% categories.forEach(function(category, index) { %>
        <a class="nav-link text-base<% if (category.isActive) { %> font-bold<% } %>" href="<%= category.html_url %>">
          <%= category.name %>
        </a>
      <% }) %>
    </nav>
  <% } %>
</template>

Other styles can be applied using utilities. For example, use text-primary to apply the primary color to active items.

Rounded background highlight when active
View code
<template id="tmpl-sidebar-navigation">
  <% if (categories.length) { %>
    <nav class="nav flex-column my-6">
      <% categories.forEach(function(category, index) { %>
        <a class="nav-link text-base border-radius<% if (category.isActive) { %> bg-gray-100 font-bold<% } %>" href="<%= category.html_url %>">
          <%= category.name %>
        </a>
      <% }) %>
    </nav>
  <% } %>
</template>
Pill-style when active
View code
<template id="tmpl-sidebar-navigation">
  <% if (categories.length) { %>
    <nav class="nav nav-pills flex-column my-6">
      <% categories.forEach(function(category, index) { %>
        <a class="nav-link text-base border-radius<% if (category.isActive) { %> is-active<% } %>" href="<%= category.html_url %>">
          <%= category.name %>
        </a>
      <% }) %>
    </nav>
  <% } %>
</template>

Use .bg-primary and .text-primary-inverse on active items for a pill-style navigation.

Background highlight when active
View code
<template id="tmpl-sidebar-navigation">
  <% if (categories.length) { %>
    <nav class="nav flex-column my-6">
      <% categories.forEach(function(category, index) { %>
        <a class="nav-link -mr-4 text-base border-radius-left<% if (category.isActive) { %> bg-gray-200 font-bold<% } %>" href="<%= category.html_url %>">
          <%= category.name %>
        </a>
      <% }) %>
    </nav>
  <% } %>
</template>
Background highlight with left border when active
View code
<template id="tmpl-sidebar-navigation">
  <% if (categories.length) { %>
    <nav class="nav flex-column my-6">
      <% categories.forEach(function(category, index) { %>
        <a class="nav-link text-base <% if (category.isActive) { %> -ml-1 -mr-4 border-left border-left-4 bg-gray-100<% } %>" href="<%= category.html_url %>">
          <%= category.name %>
        </a>
      <% }) %>
    </nav>
  <% } %>
</template>
Primary background highlight with right border when active
View code
<template id="tmpl-sidebar-navigation">
  <% if (categories.length) { %>
    <nav class="nav flex-column my-6">
      <% categories.forEach(function(category, index) { %>
        <a class="nav-link text-base <% if (category.isActive) { %> -mr-4 border-radius-left border-right border-right-4 border-right-primary text-primary font-bold hover:text-primary<% } %>" href="<%= category.html_url %>">
          <%= category.name %>
          <% if (category.isActive) { %>
            <div class="absolute-top bottom-0 left-0 w-full bg-primary border-radius-left" style="opacity: 0.1"></div>
          <% } %>
        </a>
      <% }) %>
    </nav>
  <% } %>
</template>

These list styles can be used within a sidebar, against the background of the page or within other elements like cards.

Pill-style directly on background
View code
<template id="tmpl-sidebar-navigation">
  <% if (categories.length) { %>
    <nav class="nav nav-pills flex-column my-6">
      <% categories.forEach(function(category, index) { %>
        <a class="nav-link text-base border-radius<% if (category.isActive) { %> is-active<% } %>" href="<%= category.html_url %>">
          <%= category.name %>
        </a>
      <% }) %>
    </nav>
  <% } %>
</template>
Background highlight when active within card
View code
<template id="tmpl-sidebar-navigation">
  <% if (categories.length) { %>
    <nav class="nav nav-pills flex-column my-6">
      <% categories.forEach(function(category, index) { %>
        <a class="nav-link text-base border-radius<% if (category.isActive) { %> is-active<% } %>" href="<%= category.html_url %>">
          <%= category.name %>
        </a>
      <% }) %>
    </nav>
  <% } %>
</template>

Multi-level and interactive lists

Sections displayed with category headings
View code
<template id="tmpl-sidebar-navigation"></template>
Responsive category list
View code
<template id="tmpl-sidebar-navigation">
  <div class="my-4 border-top border-bottom md:my-5 lg:border-transparent" x-data="toggle({ isOpen: false })" @collapse:show.stop="open" @collapse:hide.stop="close">

    {{! Mobile toggle }}
    <h3 class="flex align-items-center justify-content-between my-4 font-size-lg cursor-pointer lg:hidden" data-toggle="collapse" data-target="#sidebar-navigation" aria-controls="sidebar-navigation" aria-expanded="false">
      {{t 'categories'}}
      <svg class="fill-current pointer-events-none ml-3" :class="isOpen && 'rotate-180'" width="14px" viewBox="0 0 40 20" xmlns="http://www.w3.org/2000/svg">
        <path d="M20,19.5 C19.4,19.5 18.9,19.3 18.4,18.9 L1.4,4.9 C0.3,4 0.2,2.4 1.1,1.4 C2,0.3 3.6,0.2 4.6,1.1 L20,13.8 L35.5,1.1 C36.6,0.2 38.1,0.4 39,1.4 C39.9,2.5 39.7,4 38.7,4.9 L21.7,18.9 C21.1,19.3 20.5,19.5 20,19.5 Z" fill-rule="nonzero"></path>
      </svg>
    </h3>

    <div class="collapse lg:expand lg:flex-column" id="sidebar-navigation">
      <h3 class="font-size-lg mt-2 hidden lg:block">
        <a class="text-inherit" href="{{page_path 'help_center'}}">
          {{t 'categories'}}
        </a>
      </h3>
      <ul class="list-unstyled font-size-md">
        <% categories.forEach(function(category) { %>
          <li>
            <a class="block py-2 text-inherit<% if (category.isActive) { %> font-bold text-primary<% } %>" href="<%= category.html_url %>">
              <%= category.name %>
            </a>
          </li>
        <% }); %>
      </ul>
    </div>
  </div>
</template>
Responsive section list
View code
{{! Section list }}
<template id="tmpl-sidebar-navigation">
  <% var maxSections =  5 %>
  <div class="border-top border-bottom lg:border-transparent my-5" x-data="toggle({ isOpen: false })" @collapse:show.stop="open" @collapse:hide.stop="close">

    {{! Mobile toggle }}
    <h3 class="flex align-items-center justify-content-between my-4 font-size-lg cursor-pointer lg:hidden" data-toggle="collapse" data-target="#sidebar-navigation" aria-controls="sidebar-navigation" aria-expanded="false">
      {{t 'toggle_navigation'}}
      <svg class="fill-current pointer-events-none ml-3" :class="isOpen && 'rotate-180'" width="14px" viewBox="0 0 40 20" xmlns="http://www.w3.org/2000/svg">
        <path d="M20,19.5 C19.4,19.5 18.9,19.3 18.4,18.9 L1.4,4.9 C0.3,4 0.2,2.4 1.1,1.4 C2,0.3 3.6,0.2 4.6,1.1 L20,13.8 L35.5,1.1 C36.6,0.2 38.1,0.4 39,1.4 C39.9,2.5 39.7,4 38.7,4.9 L21.7,18.9 C21.1,19.3 20.5,19.5 20,19.5 Z" fill-rule="nonzero"></path>
      </svg>
    </h3>

    <div class="collapse lg:expand lg:flex-column" id="sidebar-navigation">
      <div class="py-2">
        <% categories.forEach(function(category, index) { %>
          <h3 class="font-size-lg <% if (index === 0) { %>mt-4 lg:mt-0<% } else { %>mt-6<% } %>">
            <a class="text-inherit" href="<%= category.html_url %>">
              <%= category.name %>
            </a>
          </h3>
          <%= partial('partial-section-list-sections', { parent: category, sections: category.sections, maxSections: maxSections, partial: partial }) %>
        <% }); %>
      </div>
    </div>
  </div>
</template>

{{! Section list - Subsections }}
<template id="tmpl-partial-section-list-sections">
  <% if (sections.length) { %>
    <ul class="list-unstyled<% if (parent.hasOwnProperty('parent_section_id')) { %> pl-4 mb-0<% } %> font-size-md">
      <% sections.slice(0, maxSections).forEach(function(section) { %>
        <li>
          <a class="block py-2 text-inherit<% if (section.isActive) { %> font-bold text-primary<% } %>" href="<%= section.html_url %>">
            <%= section.name %>
          </a>
          <%= partial('partial-section-list-sections', { parent: section, sections: section.sections, maxSections: maxSections, partial: partial }) %>
        </li>
      <% }); %>
      <% if (sections.length > maxSections) { %>
        <li>
          <a class="block py-2 text-inherit" href="<%= parent.html_url %>">
            {{t 'see_more'}}
          </a>
        </li>
      <% } %>
    </ul>
  <% } %>
</template>
Responsive article list
View code
{{! Article list }}
<template id="tmpl-article-list">
  <div class="border-top border-bottom my-5 lg:border-transparent" x-data="toggle({ isOpen: false })" @collapse:show.stop="open" @collapse:hide.stop="close">

    {{! Mobile toggle }}
    <h3 class="flex align-items-center justify-content-between my-4 font-size-lg cursor-pointer lg:hidden" data-toggle="collapse" data-target="#sidebar-navigation" aria-controls="sidebar-navigation" aria-expanded="false">
      {{t 'categories'}}
      <svg class="fill-current pointer-events-none ml-3" :class="isOpen && 'rotate-180'" width="14px" viewBox="0 0 40 20" xmlns="http://www.w3.org/2000/svg">
        <path d="M20,19.5 C19.4,19.5 18.9,19.3 18.4,18.9 L1.4,4.9 C0.3,4 0.2,2.4 1.1,1.4 C2,0.3 3.6,0.2 4.6,1.1 L20,13.8 L35.5,1.1 C36.6,0.2 38.1,0.4 39,1.4 C39.9,2.5 39.7,4 38.7,4.9 L21.7,18.9 C21.1,19.3 20.5,19.5 20,19.5 Z" fill-rule="nonzero"></path>
      </svg>
    </h3>

    <div class="collapse lg:expand lg:flex-column" id="sidebar-navigation">
      <ul class="list-unstyled font-size-lg w-full">
        <% categories.forEach(function(category, index) { %>
          <li class="font-semibold" x-data="toggle({ isOpen: <%= !!category.isActive %> })" @collapse:show.stop="open" @collapse:hide.stop="close">

            {{! Category name and toggle }}
            <div class="flex justify-content-between align-items-center">
              <a class="flex-1 py-3 text-inherit" :class="{ 'text-inherit': !isOpen }" href="<%= category.html_url %>">
                <%= category.name %>
              </a>
              <button class="p-2 ml-1 not-a-button border-radius transition cursor-pointer hover:bg-gray-200 hidden lg:block" :class="{ 'is-active': isOpen }" :aria-expanded="isOpen" data-toggle="collapse" data-target="#category-<%= category.id %>">
                <svg class="text-inherit fill-current pointer-events-none" :class="{ 'rotate-180': isOpen }" width="12px" height="12px" viewBox="0 0 324 190" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
                  <path d="M162,190 C156,190 150,187 146,183 L7,38 C-2,29 -2,15 7,7 C16,-2 30,-2 39,7 L162,135 L285,7 C293,-2 308,-2 317,7 C326,15 326,29 317,38 L178,183 C174,187 168,190 162,190 Z"></path>
                </svg>
              </button>
            </div>

            <div class="hidden lg:block">
              {{! Sections }}
              <%= partial('partial-article-list-sections', {
                id: 'category-' + category.id,
                parentId: '#sidebar-navigation',
                sections: category.sections,
                activeCategoryId: activeCategoryId,
                activeSectionId: activeSectionId,
                activeArticleId: activeArticleId,
                partial: partial
              }) %>
            </div>
          </li>
        <% }); %>
      </ul>
    </div>
  </div>
</template>

{{! Article list - Subsections }}
<template id="tmpl-partial-article-list-sections">
  <% if (sections.length) { %>
    <ul class="list-none pl-3 mb-0 font-size-base collapse" id="<%= id %>" :class="{ 'is-visible': isOpen }" data-parent="<%= parentId %>">
      <% sections.forEach(function(section) { %>
        <li class="font-medium" x-data="toggle({ isOpen: <%= !!section.isActive %> })" @collapse:show.stop="open" @collapse:hide.stop="close">

          {{! Section name and toggle }}
          <div class="flex justify-content-between align-items-center">
            <a class="flex-1 py-2 text-inherit font-semibold" :class="{ 'text-inherit': !isOpen }" href="<%= section.html_url %>">
              <%= section.name %>
            </a>
            <button class="p-2 ml-1 not-a-button border-radius transition cursor-pointer hover:bg-gray-200" :class="{ 'is-active': isOpen }" :aria-expanded="isOpen" data-toggle="collapse" data-target="#section-<%= section.id %>">
              <svg class="text-inherit fill-current pointer-events-none" :class="{ 'rotate-180': isOpen }" width="12px" height="12px" viewBox="0 0 324 190" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
                <path d="M162,190 C156,190 150,187 146,183 L7,38 C-2,29 -2,15 7,7 C16,-2 30,-2 39,7 L162,135 L285,7 C293,-2 308,-2 317,7 C326,15 326,29 317,38 L178,183 C174,187 168,190 162,190 Z"></path>
              </svg>
            </button>
          </div>

          {{! Subsections }}
          <%= partial('partial-article-list-sections', {
            id: 'section-' + section.id,
            parentId: '#' + id,
            sections: section.sections,
            activeCategoryId: activeCategoryId,
            activeSectionId: activeSectionId,
            activeArticleId: activeArticleId,
            partial: partial
          }) %>

          {{! Articles }}
          <% if (section.articles.length) { %>
            <ul class="list-none font-size-md pl-0 mb-0 collapse" :class="{ 'is-visible': isOpen }" id="section-<%= section.id %>" data-parent="#<%= id %>">
              <% section.articles.forEach(function(article) { %>
                <li>
                  <a class="block px-3 py-2 text-inherit border-radius transition<% if (article.isActive) { %> bg-gray-100<% } %>" href="<%= article.html_url %>">
                    <%= article.title %>
                  </a>
                </li>
              <% }); %>
            </ul>
          <% } %>

        </li>
      <% }); %>
    </ul>
  <% } %>
</template>
Responsive article list
View code
{{! Section list }}
<template id="tmpl-section-list">
  <% var maxSections =  5 %>
  <div class="border-top border-bottom my-5 lg:border-transparent" x-data="toggle({ isOpen: false })" @collapse:show.stop="open" @collapse:hide.stop="close">

    {{! Mobile toggle }}
    <h3 class="flex align-items-center justify-content-between my-4 font-size-lg cursor-pointer lg:hidden" data-toggle="collapse" data-target="#sidebar-section-navigation" aria-controls="sidebar-section-navigation" aria-expanded="false">
      {{t 'toggle_navigation'}}
      <svg class="fill-current pointer-events-none ml-3" :class="isOpen && 'rotate-180'" width="14px" viewBox="0 0 40 20" xmlns="http://www.w3.org/2000/svg">
        <path d="M20,19.5 C19.4,19.5 18.9,19.3 18.4,18.9 L1.4,4.9 C0.3,4 0.2,2.4 1.1,1.4 C2,0.3 3.6,0.2 4.6,1.1 L20,13.8 L35.5,1.1 C36.6,0.2 38.1,0.4 39,1.4 C39.9,2.5 39.7,4 38.7,4.9 L21.7,18.9 C21.1,19.3 20.5,19.5 20,19.5 Z" fill-rule="nonzero"></path>
      </svg>
    </h3>

    <div class="collapse lg:expand lg:flex-column" id="sidebar-section-navigation">
      <ul class="list-unstyled m-0 py-2">
        <% categories.forEach(function(category, index) { %>
          <li class="mb-4">
            <a class="font-bold font-size-lg <% if (category.isActive) { %>text-primary<% } else { %>text-inherit<% } %> hidden lg:block" href="<%= category.html_url %>">
              <%= category.name %>
            </a>
            <% if (category.isActive) { %>
              <%= partial('partial-section-list-sections', {
                parent: category,
                sections: category.sections,
                maxSections: maxSections,
                partial: partial
              }) %>
            <% } %>
          </li>
        <% }); %>
      </ul>
    </div>
  </div>
</template>

{{! Section list - Subsections }}
<template id="tmpl-partial-section-list-sections">
  <% var isSubsection = parent.hasOwnProperty('parent_section_id') %>
  <% if (sections.length) { %>
    <ul class="list-unstyled <% if (isSubsection) { %>pl-3 mb-0<% } else { %>py-2 lg:px-4 lg:my-4 lg:bg-gray-200 lg:border-radius<% } %>">
      <% sections.slice(0, maxSections).forEach(function(section) { %>
        <li class="font-size-lg lg:font-size-md">
          <a class="block py-2 text-inherit<% if (section.isActive) { %> text-primary lg:text-inherit lg:font-semibold<% } %>" href="<%= section.html_url %>">
            <%= section.name %>
          </a>
          <%= partial('partial-section-list-sections', { parent: section, sections: section.sections, maxSections: maxSections, partial: partial }) %>
        </li>
      <% }); %>
      <% if (sections.length > maxSections) { %>
        <li>
          <a class="block py-2 text-inherit" href="<%= parent.html_url %>">
            {{t 'see_more'}}
          </a>
        </li>
      <% } %>
    </ul>
  <% } %>
</template>

These navigation menus can support any number of subsections.

All of our themes come with a several vertical navigation menu options built in, which you can display on the Category, Section and Article pages. Because they’re built using our micro-templating system, you can also add them anywhere else in your help center.

You can display vertical navigation menus in the sidebar of the Category, Section and Articles pages using the Sidebar setting associated with each of those pages.

Our themes offer several built-in styles, typically including menus that display a combination of categories, sections and articles in responsive layouts. Each page is configured independently, providing a tremendous amount of flexibility.

To replace an existing vertical navigation menu in the Category, Section and/or Article sidebars with a custom pattern:

  1. Select “Custom template” from the Sidebar setting of the page you’re updating.

  2. Copy-and-paste your selected pattern micro-template into the bottom of the footer.hbs template.

Vertical navigation menus are powered by our Navigation extension and can therefore be used anywhere in the help center.

To display vertical navigation menus outside of the Category, Section and/or Article page sidebars:

  1. Copy the HTML hook below into the position where you’d like the vertical navigation to appear.

     <div data-element="navigation" data-template="sidebar-navigation"></div>
    
  2. Copy-and-paste your selected pattern micro-template into the bottom of the footer.hbs template.

Related patterns