Dynamic Navigation Menus with Jekyll Data Files
Benefits of Dynamic Navigation Menus
Static navigation menus require manual updates in multiple places when your site structure changes. Dynamic menus built with Jekyll data files and includes:
- Centralize menu configuration in one place
- Allow easy addition, removal, or rearrangement of links
- Enable multi-level nested menus for complex sites
- Improve maintainability and reduce errors
Setting Up Your Navigation Data File
Create a YAML data file _data/navigation.yml to define your menu structure. Example:
- title: Home
url: /
- title: About
url: /about/
- title: Blog
url: /blog/
children:
- title: Tutorials
url: /blog/tutorials/
- title: News
url: /blog/news/
- title: Contact
url: /contact/
This format supports nested children for dropdown or expandable menus.
Creating a Navigation Include
Create an include file _includes/navigation.html that loops through this data to render the menu:
<nav>
<ul class="main-menu">
{% raw %}{% for item in site.data.navigation %}{% endraw %}
<li class="menu-item"{% raw %} {% if page.url == item.url %}class="active"{% endif %}{% endraw %}>
<a href="{% raw %}{{ item.url }}{% endraw %}">{% raw %}{{ item.title }}{% endraw %}</a>
{% raw %}{% if item.children %}{% endraw %}
<ul class="submenu">
{% raw %}{% for child in item.children %}{% endraw %}
<li class="submenu-item"{% raw %} {% if page.url == child.url %}class="active"{% endif %}{% endraw %}>
<a href="{% raw %}{{ child.url }}{% endraw %}">{% raw %}{{ child.title }}{% endraw %}</a>
</li>
{% raw %}{% endfor %}{% endraw %}
</ul>
{% raw %}{% endif %}{% endraw %}
</li>
{% raw %}{% endfor %}{% endraw %}
</ul>
</nav>
Including the Navigation in Your Layout
Place the navigation include in your site's layout, for example in _layouts/default.html:
{% raw %}
{% include navigation.html %}
{{ content }}
{% endraw %}
Styling Your Menus
Use CSS to style the main menu and submenu, including hover effects and active states:
.main-menu {
list-style: none;
padding: 0;
margin: 0;
display: flex;
}
.menu-item {
position: relative;
margin-right: 20px;
}
.menu-item a {
text-decoration: none;
padding: 10px 15px;
display: block;
}
.menu-item.active > a {
font-weight: bold;
border-bottom: 2px solid #007acc;
}
.submenu {
display: none;
position: absolute;
top: 100%;
left: 0;
list-style: none;
padding: 10px 0;
background: #fff;
box-shadow: 0 4px 6px rgba(0,0,0,0.1);
}
.menu-item:hover .submenu {
display: block;
}
.submenu-item a {
padding: 10px 20px;
display: block;
white-space: nowrap;
}
Handling Active Menu Highlighting
The include checks if the current page URL matches menu item URLs and applies an active class accordingly. This helps users understand their current location on your site.
Case Study: Simplifying Navigation Updates
A tech blog with dozens of tutorials and categories faced maintenance headaches when updating navigation. By moving menu links into a centralized data file and rendering dynamically, editors could update menus without touching HTML code, reducing errors and speeding up site updates.
Summary
Using Jekyll data files combined with includes for navigation menus greatly enhances flexibility and maintainability. This approach supports nested menus, active state detection, and easier content management.
Next Steps
The next article will explore building multilingual support in Jekyll with data files and Liquid templating for global reach.
