Cape Cod, Massachusetts 41°39'20.7"N 70°09'53.0"W
Back to blog Drupal Development

A Bootstrap Navbar in Drupal 8 with four easy template changes

A Bootstrap Navbar in Drupal 8 with four easy template changes

When Drupal 8 landed, I started learning its theming system from scratch — an empty theme folder on top of Stable (core’s base theme at the time). One of the first things I needed was a Bootstrap Navbar that actually worked with Drupal’s menu system. Turns out it’s cleaner than Drupal 7 ever was.

The four templates

You need to override four templates. Create these in your theme’s templates/ folder:

1. html.html.twig

Add the Bootstrap CSS and JS CDN links, and set <html class="no-js"> so Bootstrap’s JavaScript can toggle it to js.

2. page.html.twig

Replace the default page layout with Bootstrap’s container structure. Wrap the header region in a <div class="navbar navbar-default navbar-fixed-top">.

3. menu--main.html.twig

This is where the Bootstrap Navbar classes live. The key is the <ul class="nav navbar-nav"> wrapper around menu items.

{# menu--main.html.twig #}
<ul class="nav navbar-nav">
  {% for item in items %}
    <li{{ item.attributes.addClass(item.is_expanded ? 'dropdown' : '') }}>
      {% if item.is_expanded %}
        <a href="{{ item.url }}" class="dropdown-toggle" data-toggle="dropdown">
          {{ item.title }} <span class="caret"></span>
        </a>
        <ul class="dropdown-menu">
          {% for child in item.below %}
            <li><a href="{{ child.url }}">{{ child.title }}</a></li>
          {% endfor %}
        </ul>
      {% else %}
        <a href="{{ item.url }}">{{ item.title }}</a>
      {% endif %}
    </li>
  {% endfor %}
</ul>

4. block--system-menu-block--main.html.twig

Remove the default block wrapper so the menu renders directly inside your Navbar, without an extra <div> breaking the Bootstrap structure.

What’s easier than D7

In Drupal 7, you needed Menu Block module and often a custom module to manipulate the menu tree. In Drupal 8, Twig templates give you direct access to the menu structure — including the item.below array for submenus — without any additional modules. Four template overrides and you’re done.