Shopify Side Menu: Add a Vertical Navigation Bar

A merchant wanted Dawn's navigation vertical on the left for desktop and pinned to the bottom on mobile. Here is the one Custom Liquid section that does it, no theme files and no developer, with the full code and screenshots.

By AjayCodeWiz · August 18, 2026 · 9 min read

Answered on the Shopify Community

A merchant ran into this and asked about it on the forum. I worked through it on a test store and posted the fix there on August 18, 2026. You can read the original thread, including the follow-up questions, over on the Shopify Community.

View the original thread

What a Shopify side menu is, and why the theme fights you

A side menu is a navigation bar that runs down the left edge of the screen instead of across the top. On a desktop it sits as a thin vertical rail. On a phone it usually flips to a fixed bar pinned along the bottom, close to the thumb.

It looks simple. Then you open your theme editor and there is no setting for it.

A merchant asked for exactly this on the Shopify Community. They run the Dawn theme. They wanted the desktop nav vertical on the left, and the mobile nav fixed to the bottom, like a phone app. Two people replied. Both said the same thing: Dawn does not do this, you would need to hire a developer or rebuild the header in code.

That answer is half right. Dawn does not ship the layout. But you do not need to touch theme files or hire anyone. One Custom Liquid section produces the whole thing.

I reproduced it on a Dawn store and the result matches the look they were after. This post walks through what is going on and gives you the exact code.

A vertical side menu running down the left of a Shopify store on desktopA vertical side menu running down the left of a Shopify store on desktop

Why Dawn has no setting for a vertical menu

Dawn's header is one section, and that section is built to be horizontal. Logo on the left, menu across the middle, cart on the right. Every setting in it assumes that row.

There is no toggle that rotates it to a column, because the header's internal layout is fixed in the theme's own code. The settings only let you rearrange pieces inside the horizontal band.

So when the community answers say "Dawn doesn't work that way," they are describing this. The header is a horizontal component and no amount of clicking turns it vertical.

The move is not to fight the header. It is to hide it and lay your own bar on top.

The one concept that makes this easy: Custom Liquid

Custom Liquid is a section you can add in the theme editor. It accepts HTML, CSS, and Liquid, and it renders wherever you place it.

Two facts about it do all the work here.

It renders inline, so a <style> tag inside it applies to the live page. You can hide the theme's header and position your own bar without editing a single theme file.

It can live in the Header group, which every page loads. Drop the section there once and your new navigation appears site-wide, not just on the home page.

That is the entire trick. Hide the horizontal header with CSS, draw a vertical bar, and pin it with position: fixed so it stays put as the page scrolls.

Add the section

The steps are the same on any Online Store 2.0 theme, Dawn included.

Open your Shopify admin. Go to Online Store, then Themes, and click Customize on your live theme.

In the left panel you will see three groups: Header, Template, and Footer. Under Header, click Add section, then choose Custom Liquid.

Adding a Custom Liquid section under the Header group in the Shopify theme editorAdding a Custom Liquid section under the Header group in the Shopify theme editor

A settings panel opens with a Liquid code box. Paste the code from the next section into it and click Save.

Pasting the code into the Liquid code box and clicking SavePasting the code into the Liquid code box and clicking Save

Because the section sits in the Header group, it now shows on every page of the store.

The code

Paste this whole block into the Liquid code box.

<style>
  :root{ --rail-bg:#f4f0e6; --rail-fg:#1a1a1a; --rail-w:104px; }
  .ck-nav a{ display:flex; flex-direction:column; align-items:center; gap:6px;
    text-decoration:none; color:var(--rail-fg); font-size:12px; }
  .ck-nav svg{ width:22px; height:22px; }
  .ck-rail{ position:fixed; top:0; left:0; height:100vh; width:var(--rail-w); z-index:6;
    display:flex; flex-direction:column; align-items:center; gap:30px;
    padding:26px 0; background:var(--rail-bg); border-right:1px solid rgba(0,0,0,.08); }
  .ck-rail .ck-nav__logo{ margin-bottom:14px; }
  .ck-bar{ display:none; }
  .section-header{ display:none !important; }
  @media (min-width:990px){ body{ padding-left:var(--rail-w); } }
  @media (max-width:989px){
    .ck-rail{ display:none; }
    body{ padding-bottom:78px; }
    .ck-bar{ position:fixed; left:0; right:0; bottom:0; z-index:6;
      display:flex; justify-content:space-around; align-items:flex-end;
      padding:10px 10px 12px; background:var(--rail-bg); border-top:1px solid rgba(0,0,0,.08); }
    .ck-bar .ck-nav__logo{ position:absolute; left:50%; top:-26px; transform:translateX(-50%);
      width:56px; height:56px; border-radius:50%; background:var(--rail-bg);
      display:flex; align-items:center; justify-content:center; box-shadow:0 -3px 8px rgba(0,0,0,.06); }
  }
  .ck-panel{ position:fixed; inset:0; z-index:20; background:var(--rail-bg);
    display:none; padding:80px 24px; overflow:auto; }
  .ck-panel:target{ display:block; }
  .ck-panel__close{ position:absolute; top:22px; right:26px; font-size:30px; text-decoration:none; color:var(--rail-fg); }
  .ck-panel ul{ list-style:none; margin:0; padding:0; max-width:640px; }
  .ck-panel li{ border-bottom:1px solid rgba(0,0,0,.08); }
  .ck-panel a.ck-link{ display:block; padding:16px 0; font-size:22px; text-decoration:none; color:var(--rail-fg); }
  .ck-panel form{ max-width:640px; display:flex; gap:10px; }
  .ck-panel input[type=search]{ flex:1; padding:14px; font-size:18px; border:1px solid rgba(0,0,0,.2); background:#fff; }
  .ck-panel button{ padding:14px 22px; font-size:16px; border:0; background:var(--rail-fg); color:#fff; cursor:pointer; }
</style>

{%- capture nav -%}
  <a href="#ck-menu"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6"><line x1="4" y1="7" x2="20" y2="7"/><line x1="4" y1="12" x2="20" y2="12"/><line x1="4" y1="17" x2="20" y2="17"/></svg><span>Menu</span></a>
  <a href="#ck-search"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6"><circle cx="11" cy="11" r="7"/><line x1="16.5" y1="16.5" x2="21" y2="21"/></svg><span>Search</span></a>
  <a href="{{ routes.root_url }}pages/wishlist"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6"><path d="M6 3h12v18l-6-4-6 4z"/></svg><span>Wish List</span></a>
  <a href="{{ routes.all_products_collection_url }}"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6"><circle cx="12" cy="12" r="9"/><polyline points="12 7 12 12 16 14"/></svg><span>Recent</span></a>
{%- endcapture -%}
{%- capture logo -%}
  <a href="{{ routes.root_url }}" class="ck-nav__logo">{% if settings.logo != blank %}<img src="{{ settings.logo | image_url: width: 96 }}" width="48" alt="{{ shop.name }}">{% else %}<span>{{ shop.name }}</span>{% endif %}</a>
{%- endcapture -%}

<nav class="ck-rail ck-nav">{{ logo }}{{ nav }}</nav>
<nav class="ck-bar ck-nav">
  <a href="#ck-menu"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6"><line x1="4" y1="7" x2="20" y2="7"/><line x1="4" y1="12" x2="20" y2="12"/><line x1="4" y1="17" x2="20" y2="17"/></svg><span>Menu</span></a>
  <a href="#ck-search"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6"><circle cx="11" cy="11" r="7"/><line x1="16.5" y1="16.5" x2="21" y2="21"/></svg><span>Search</span></a>
  {{ logo }}
  <a href="{{ routes.root_url }}pages/wishlist"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6"><path d="M6 3h12v18l-6-4-6 4z"/></svg><span>Wish List</span></a>
  <a href="{{ routes.all_products_collection_url }}"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6"><circle cx="12" cy="12" r="9"/><polyline points="12 7 12 12 16 14"/></svg><span>Recent</span></a>
</nav>

<div id="ck-menu" class="ck-panel"><a href="#" class="ck-panel__close">&times;</a>
  <ul>{%- for link in linklists['main-menu'].links -%}<li><a class="ck-link" href="{{ link.url }}">{{ link.title }}</a></li>{%- endfor -%}</ul>
</div>
<div id="ck-search" class="ck-panel"><a href="#" class="ck-panel__close">&times;</a>
  <form action="{{ routes.search_url }}" method="get" role="search"><input type="search" name="q" placeholder="Search"><button type="submit">Search</button></form>
</div>

How the desktop side menu works

The rail is a position: fixed box glued to the left edge, 100vh tall. flex-direction: column stacks the items down instead of across.

One line pushes the whole store over so nothing hides behind the rail:

@media (min-width:990px){ body{ padding-left:var(--rail-w); } }

And one line hides the theme's own header on the desktop breakpoint:

.section-header{ display:none !important; }

.section-header is the wrapper Dawn puts around its header section. Hiding it clears the horizontal bar so your vertical one is the only navigation on screen.

How the mobile bottom bar works

Below 990 pixels the rail is hidden and a second bar takes over. It is fixed to the bottom, stretched full width, with the items spread evenly by justify-content: space-around.

The logo floats in the middle in a small circle that pokes above the bar, which is the phone-app look the merchant wanted.

The same navigation as a fixed bottom bar on mobile, with a floating logo in the middleThe same navigation as a fixed bottom bar on mobile, with a floating logo in the middle

body { padding-bottom: 78px; } keeps the last bit of every page clear of the bar so it never covers a button or the footer.

What each button does

Menu and Search work out of the box.

Menu opens a full-screen panel listing your Main menu links. It uses the :target CSS trick, so tapping Menu shows the panel and tapping the X hides it, with no JavaScript at all.

Tapping Menu opens a panel with the store's main menu linksTapping Menu opens a panel with the store's main menu links

Search opens a panel with a search box that posts to your store's search page.

Wish List and Recent are wired as plain links so the four-item layout is complete. Dawn has no native wishlist or recently-viewed feature, so those two are placeholders. Point Wish List at a wishlist app, or swap those two links for Cart and Account. They are ordinary anchor tags, so you change the destination by editing the href.

Make it yours

Three values at the top of the code control the look.

--rail-bg is the bar's background color. --rail-fg is the text and icon color. --rail-w is the desktop rail width in pixels. Change those and both the desktop rail and the mobile bar update together.

Your logo comes from Theme settings, then Logo. Once it is set, it appears in the rail and inside the mobile circle automatically. With no logo set, the store name shows as text instead.

To rename an item, edit the <span> label. To change where it goes, edit its href. The menu you see in the Menu panel is your existing Main menu, so manage those links the normal way under Navigation, no code needed.

Should the top header stay or go

This code hides the header everywhere so the side menu is the only navigation, which is what most people asking for this layout want.

If you would rather keep the announcement bar at the top, leave it. The announcement bar is a separate section, not part of .section-header, so it stays visible above your content.

If you want the header back on certain templates only, that is a different job. You would scope the hide rule to specific page types rather than applying it globally. For a whole-store side menu, the version above is what you want.

What to check if it does not look right

If content hides behind the rail, your theme may use a class other than .section-header for its header. Dawn uses .section-header. On a different theme, open the storefront, right click the header, choose Inspect, and read the section's class name, then swap it into the hide rule.

If the Menu panel does not open, make sure you pasted the whole block. The panels rely on the two <div> blocks at the bottom with the id="ck-menu" and id="ck-search" anchors.

If the mobile bar sits too high or too low, adjust the bottom and padding values in the mobile media query.

Will this work on themes other than Dawn

Yes, with one small change. The layout is plain CSS pinned to fixed positions, so it does not depend on Dawn specifically. The only theme-specific line is the one that hides the existing header.

Dawn wraps its header in .section-header. Most Online Store 2.0 themes use a similar wrapper class, but the exact name varies. Refuse, Sense, Craft, and other Shopify-made themes are Dawn-based and often use the same class, so the code frequently works unchanged.

If your header does not disappear, find its class. Open your storefront, right click the header, choose Inspect, and look at the section wrapper's class. Replace .section-header in the hide rule with whatever your theme uses. Everything else stays the same.

Do I need an app for this

No. There is no app cost and nothing to install. It is one section you add in the theme editor, using a feature Shopify already ships on every Online Store 2.0 theme.

Apps make sense for the two placeholder items. A wishlist needs a wishlist app to actually save products, and a proper recently-viewed feed needs one too. The navigation layout itself does not need any of that.

Side menu, vertical menu, mega menu: the difference

These get mixed up, so quickly:

A side menu or vertical menu runs down the side of the page. That is what this post builds.

A mega menu is a wide dropdown panel that opens from a top menu item, showing many links and sometimes images. It is still a horizontal header underneath.

A hamburger menu is the three-line icon that opens a slide-out drawer, common on mobile. Dawn already uses one on small screens.

They solve different problems. If your catalog is deep and you want big categorised dropdowns, you want a mega menu. If you want the app-style rail and bottom bar, you want the side menu above.

The short version

Dawn cannot make a vertical side menu from settings, but it does not need to. One Custom Liquid section in the Header group hides the horizontal header, draws a fixed left rail on desktop, and switches to a fixed bottom bar on mobile. Menu and Search work immediately, the colors and width are three editable values, and no theme files are touched.

Spending too long on manual Shopify busywork?

PinFlow turns your Shopify catalog into Pinterest pins and posts them on a schedule, automatically. Same idea as the section above, let the system handle the repetitive part.

Get PinFlow on the Shopify App Store