Skip to content
Custom Drawer Menu With Images - Free Tutorial
Browse other ways to boost conversion rate & profit

Custom Drawer Menu With Images - Free Tutorial

In this tutorial, we’ll show you how to set up a visual custom drawer menu to help your customers find your products quickly and easily.

Compatible Themes: This code should work on all free Shopify themes (Dawn, Refresh, Craft, Studio, Publisher, Crave, Origin, Taste, Colorblock, Sense, Ride, Spotlight).

 

Create new metafield

For any object (ex: product, collection, page, etc) that you want to assign a menu image, create a new metafield with the following properties:

  • Name: Header Menu Image
  • Namespace and key: custom.header_menu_image
  • Type: File

Edit settings_schema.json

  {
    "name": "Custom Header Drawer Menu",
    "settings": [
      {
        "type": "checkbox",
        "id": "enable_custom_drawer_menu",
        "label": "Enable Custom Drawer Menu",
        "info": "If enabled, the custom drawer menu will be used instead of the standard drawer menu.",
        "default": false
      },
      {
        "type": "link_list",
        "id": "drawer_menu",
        "label": "Drawer Menu",
        "info": "This menu will be used for the drawer menu. Defaults to header menu if left blank."
      },
      {
        "type": "select",
        "id": "drawer_menu_images_toggle",
        "options": [
          {
            "value": "featured",
            "label": "Featured"
          },
          {
            "value": "metafield",
            "label": "Metafield"
          }
        ],
        "default": "featured",
        "label": "Drawer menu collection image type"
      },
      {
        "type": "header",
        "content": "Menu Title Styling"
      },
      {
        "type": "range",
        "id": "drawer_menu_title_size",
        "min": 1.0,
        "max": 3.0,
        "step": 0.1,
        "unit": "rem",
        "label": "Title Font Size",
        "default": 1.8
      },
      {
        "type": "color",
        "id": "drawer_menu_title_bg",
        "label": "Title Background Color",
        "default": "#f4f4f4"
      },
      {
        "type": "color",
        "id": "drawer_menu_title_color",
        "label": "Title Text Color",
        "default": "#333333"
      }
    ]
  }

Edit header.liquid

      if section.settings.menu != blank or settings.drawer_menu != blank
        if settings.enable_custom_drawer_menu
          if settings.drawer_menu != blank
            assign custom_drawer_menu = settings.drawer_menu
          else
            assign custom_drawer_menu = section.settings.menu
          endif
          render 'header-drawer-custom', menu: custom_drawer_menu
        else
          if section.settings.menu != blank
            render 'header-drawer'
          endif
        endif
      endif

Create new snippet file header-drawer-custom.liquid

{% comment %}
  Renders a header drawer menu with grid layout for mobile and desktop.

  Usage:
  {% render 'header-drawer-2' %}
{% endcomment %}

<header-drawer data-breakpoint="{% if section.settings.menu_type_desktop == 'drawer' %}desktop{% else %}tablet{% endif %}">
  <details id="Details-menu-drawer-container" class="menu-drawer-container">
    <summary
      class="header__icon header__icon--menu header__icon--summary link focus-inset"
      aria-label="{{ 'sections.header.menu' | t }}"
    >
      <span>
        {{- 'icon-hamburger.svg' | inline_asset_content -}}
        {{- 'icon-close.svg' | inline_asset_content -}}
      </span>
    </summary>
    <div id="menu-drawer" class="gradient menu-drawer motion-reduce color-{{ section.settings.menu_color_scheme }}">
      <div class="menu-drawer__inner-container">
        <div class="menu-drawer__navigation-container">
          <nav class="menu-drawer__navigation">
            <div class="drawer-menu-grid">
              {%- for link in menu.links -%}
                {% assign has_image = false %}
                {% if settings.drawer_menu_images_toggle == 'featured' and link.object.featured_image %}
                  {% assign has_image = true %}
                  {% assign menu_image_url = link.object.featured_image | image_url: width: menu_images_size, height: menu_images_size %}
                {% elsif settings.drawer_menu_images_toggle == 'metafield' and link.object.metafields.custom.header_menu_image %}
                  {% assign has_image = true %}
                  {% assign menu_image_url = link.object.metafields.custom.header_menu_image | image_url: width: menu_images_size, height: menu_images_size %}
                {% endif %}
                
                {% if has_image %}
                  <div class="drawer-menu-grid-item">
                    <a href="{{ link.url }}" class="drawer-menu-grid-link">
                      <div class="drawer-menu-grid-image-wrapper">
                        {{ menu_image_url | image_url: width: 300 | image_tag }}
                      </div>
                      <div class="drawer-menu-grid-title-wrapper">
                        <span class="drawer-menu-grid-title">{{ link.title | escape }}</span>
                      </div>
                    </a>
                  </div>
                {% endif %}
              {%- endfor -%}
            </div>

            <ul class="menu-drawer__menu has-submenu list-menu drawer-menu-list" role="list">
              {%- for link in menu.links -%}
                {% assign has_image = false %}
                {% if settings.drawer_menu_images_toggle == 'featured' and link.object.featured_image %}
                  {% assign has_image = true %}
                {% elsif settings.drawer_menu_images_toggle == 'metafield' and link.object.metafields.custom.header_menu_image %}
                  {% assign has_image = true %}
                {% endif %}
                
                {% unless has_image %}
                  <li>
                    {%- if link.links != blank -%}
                      <details id="Details-menu-drawer-menu-item-{{ forloop.index }}">
                        <summary
                          id="HeaderDrawer-{{ link.handle }}"
                          class="menu-drawer__menu-item list-menu__item link link--text focus-inset{% if link.child_active %} menu-drawer__menu-item--active{% endif %}"
                        >
                          {{ link.title | escape }}
                          <span class="svg-wrapper">
                            {{- 'icon-arrow.svg' | inline_asset_content -}}
                          </span>
                          <span class="svg-wrapper">
                            {{- 'icon-caret.svg' | inline_asset_content -}}
                          </span>
                        </summary>
                        <div
                          id="link-{{ link.handle | escape }}"
                          class="menu-drawer__submenu has-submenu gradient motion-reduce"
                          tabindex="-1"
                        >
                          <div class="menu-drawer__inner-submenu">
                            <button class="menu-drawer__close-button link link--text focus-inset" aria-expanded="true">
                              <span class="svg-wrapper">
                                {{- 'icon-arrow.svg' | inline_asset_content -}}
                              </span>
                              {{ link.title | escape }}
                            </button>
                            <ul class="menu-drawer__menu list-menu" role="list" tabindex="-1">
                              {%- for childlink in link.links -%}
                                <li>
                                  <a
                                    id="HeaderDrawer-{{ link.handle }}-{{ childlink.handle }}"
                                    href="{{ childlink.url }}"
                                    class="menu-drawer__menu-item link link--text list-menu__item focus-inset{% if childlink.current %} menu-drawer__menu-item--active{% endif %}"
                                    {% if childlink.current %}aria-current="page"{% endif %}
                                  >
                                    {{ childlink.title | escape }}
                                  </a>
                                </li>
                              {%- endfor -%}
                            </ul>
                          </div>
                        </div>
                      </details>
                    {%- else -%}
                      <a
                        id="HeaderDrawer-{{ link.handle }}"
                        href="{{ link.url }}"
                        class="menu-drawer__menu-item list-menu__item link link--text focus-inset{% if link.current %} menu-drawer__menu-item--active{% endif %}"
                        {% if link.current %}aria-current="page"{% endif %}
                      >
                        {{ link.title | escape }}
                      </a>
                    {%- endif -%}
                  </li>
                {% endunless %}
              {%- endfor -%}
            </ul>
          </nav>

          <div class="menu-drawer__utility-links">
            {%- if shop.customer_accounts_enabled -%}
              <a
                href="{%- if customer -%}{{ routes.account_url }}{%- else -%}{{ routes.account_login_url }}{%- endif -%}"
                class="menu-drawer__account link focus-inset h5 medium-hide large-up-hide"
              >
                {%- if section.settings.enable_customer_avatar -%}
                  <account-icon>
                    {%- if customer and customer.has_avatar? -%}
                      {{ customer | avatar }}
                    {%- else -%}
                      <span class="svg-wrapper">
                        {{- 'icon-account.svg' | inline_asset_content -}}
                      </span>
                    {%- endif -%}
                  </account-icon>
                {%- else -%}
                  <span class="svg-wrapper">
                    {{- 'icon-account.svg' | inline_asset_content -}}
                  </span>
                {%- endif -%}
                {%- liquid
                  if customer
                    echo 'customer.account_fallback' | t
                  else
                    echo 'customer.log_in' | t
                  endif
                -%}
              </a>
            {%- endif -%}

            {%- if localization.available_countries or localization.available_languages -%}
              <div class="menu-drawer__localization header-localization">
                {%- if localization.available_countries and localization.available_countries.size > 1 -%}
                  <localization-form>
                    {%- form 'localization', id: 'HeaderCountryMobileForm', class: 'localization-form' -%}
                      <div>
                        <h2 class="visually-hidden" id="HeaderCountryMobileLabel">
                          {{ 'localization.country_label' | t }}
                        </h2>
                        {%- render 'country-localization', localPosition: 'HeaderCountryMobile' -%}
                      </div>
                    {%- endform -%}
                  </localization-form>
                {% endif %}

                {%- if localization.available_languages and localization.available_languages.size > 1 -%}
                  <localization-form>
                    {%- form 'localization', id: 'HeaderLanguageMobileForm', class: 'localization-form' -%}
                      <div>
                        <h2 class="visually-hidden" id="HeaderLanguageMobileLabel">
                          {{ 'localization.language_label' | t }}
                        </h2>
                        {%- render 'language-localization', localPosition: 'HeaderLanguageMobile' -%}
                      </div>
                    {%- endform -%}
                  </localization-form>
                {%- endif -%}
              </div>
            {%- endif -%}

            <ul class="list list-social list-unstyled" role="list">
              {%- if settings.social_twitter_link != blank -%}
                <li class="list-social__item">
                  <a href="{{ settings.social_twitter_link }}" class="list-social__link link">
                    <span class="svg-wrapper">
                      {{- 'icon-twitter.svg' | inline_asset_content -}}
                    </span>
                    <span class="visually-hidden">{{ 'general.social.links.twitter' | t }}</span>
                  </a>
                </li>
              {%- endif -%}
              {%- if settings.social_facebook_link != blank -%}
                <li class="list-social__item">
                  <a href="{{ settings.social_facebook_link }}" class="list-social__link link">
                    <span class="svg-wrapper">
                      {{- 'icon-facebook.svg' | inline_asset_content -}}
                    </span>
                    <span class="visually-hidden">{{ 'general.social.links.facebook' | t }}</span>
                  </a>
                </li>
              {%- endif -%}
              {%- if settings.social_pinterest_link != blank -%}
                <li class="list-social__item">
                  <a href="{{ settings.social_pinterest_link }}" class="list-social__link link">
                    <span class="svg-wrapper">
                      {{- 'icon-pinterest.svg' | inline_asset_content -}}
                    </span>
                    <span class="visually-hidden">{{ 'general.social.links.pinterest' | t }}</span>
                  </a>
                </li>
              {%- endif -%}
              {%- if settings.social_instagram_link != blank -%}
                <li class="list-social__item">
                  <a href="{{ settings.social_instagram_link }}" class="list-social__link link">
                    <span class="svg-wrapper">
                      {{- 'icon-instagram.svg' | inline_asset_content -}}
                    </span>
                    <span class="visually-hidden">{{ 'general.social.links.instagram' | t }}</span>
                  </a>
                </li>
              {%- endif -%}
              {%- if settings.social_tiktok_link != blank -%}
                <li class="list-social__item">
                  <a href="{{ settings.social_tiktok_link }}" class="list-social__link link">
                    <span class="svg-wrapper">
                      {{- 'icon-tiktok.svg' | inline_asset_content -}}
                    </span>
                    <span class="visually-hidden">{{ 'general.social.links.tiktok' | t }}</span>
                  </a>
                </li>
              {%- endif -%}
              {%- if settings.social_tumblr_link != blank -%}
                <li class="list-social__item">
                  <a href="{{ settings.social_tumblr_link }}" class="list-social__link link">
                    <span class="svg-wrapper">
                      {{- 'icon-tumblr.svg' | inline_asset_content -}}
                    </span>
                    <span class="visually-hidden">{{ 'general.social.links.tumblr' | t }}</span>
                  </a>
                </li>
              {%- endif -%}
              {%- if settings.social_snapchat_link != blank -%}
                <li class="list-social__item">
                  <a href="{{ settings.social_snapchat_link }}" class="list-social__link link">
                    <span class="svg-wrapper">
                      {{- 'icon-snapchat.svg' | inline_asset_content -}}
                    </span>
                    <span class="visually-hidden">{{ 'general.social.links.snapchat' | t }}</span>
                  </a>
                </li>
              {%- endif -%}
              {%- if settings.social_youtube_link != blank -%}
                <li class="list-social__item">
                  <a href="{{ settings.social_youtube_link }}" class="list-social__link link">
                    <span class="svg-wrapper">
                      {{- 'icon-youtube.svg' | inline_asset_content -}}
                    </span>
                    <span class="visually-hidden">{{ 'general.social.links.youtube' | t }}</span>
                  </a>
                </li>
              {%- endif -%}
              {%- if settings.social_vimeo_link != blank -%}
                <li class="list-social__item">
                  <a href="{{ settings.social_vimeo_link }}" class="list-social__link link">
                    <span class="svg-wrapper">
                      {{- 'icon-vimeo.svg' | inline_asset_content -}}
                    </span>
                    <span class="visually-hidden">{{ 'general.social.links.vimeo' | t }}</span>
                  </a>
                </li>
              {%- endif -%}
            </ul>
          </div>
        </div>
      </div>
    </div>
  </details>
</header-drawer>

<style>
  .drawer-menu-grid {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 2rem;
    padding: 2rem;
  }

  .drawer-menu-grid-item {
    text-align: center;
    border-radius: 24px;
    overflow: hidden;
    background: white;
    aspect-ratio: 1;
  }

  .drawer-menu-grid-link {
    display: flex;
    flex-direction: column;
    text-decoration: none;
    color: inherit;
    height: 100%;
  }

  .drawer-menu-grid-image-wrapper {
    height: 80%;
    width: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    background: white;
    overflow: hidden;
  }

  .drawer-menu-grid-image-wrapper img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: center;
  }

  .drawer-menu-grid-title-wrapper {
    height: 20%;
    background: {{ settings.drawer_menu_title_bg }};
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0.5rem;
  }

  .drawer-menu-grid-title {
    font-size: {{ settings.drawer_menu_title_size }}rem;
    line-height: 1.2;
    font-weight: 500;
    color: {{ settings.drawer_menu_title_color }};
    margin: 0;
  }

  .drawer-menu-list {
    padding: 1rem;
    border-top: 1px solid rgba(var(--color-foreground), 0.08);
    margin-top: 1rem;
  }
</style>

Browse other ways to boost conversion rate & profit