Shopifyストアを運営していて、こんな「壁」にぶつかったことはありませんか?
- 商品数が増えて、Dawn標準の1カラム(縦一列)メニューでは回遊性が悪い
- メニューにアイコン(画像)を入れたいが、月額数千円のアプリを入れるしかないと思っている
- PCではプロっぽくホバーで出し、スマホではスッキリ折りたたみで見せたい
先日、あるオーナー様から「アプリの固定費を削りつつ、大手ECサイトのような使い勝手の良いサイドナビを作りたい」というご相談をいただきました。
この難題を、Shopifyの標準機能である「メタフィールド」と「Liquidカスタマイズ」だけで解決し、月額コスト0円でプロ仕様の2カラム・ナビゲーションを実装した全手順を公開します。
もくじ
事前準備:このカスタマイズに必要な3つの要素
コードを書く前に、Shopifyの管理画面で「データの器」を準備する必要があります。ここが抜けると画像が表示されませんので、確実に行ってください。
1. コレクション・メタフィールドの定義
カテゴリ(コレクション)にアイコン画像を登録するための専用枠を作ります。
- [設定] > [カスタムデータ] > [コレクション] へ移動
- [定義を追加する] をクリック
- 名前:カテゴリーアイコン
- ネームスペースとキー:custom.category_icon(※下記紹介のコードを使うには、一字一句同じにする必要があります)
- タイプ:ファイル(画像のみを許可)を選択して保存

2. コレクションへのアイコン登録
- [商品管理] > [コレクション] から各カテゴリを開く
- ページ下部のメタフィールド欄に、32px〜80px程度のアイコン画像をアップロード

3. ナビゲーションメニューの作成
- [オンラインストア] > [メニュー] で「大カテゴリ > サブカテゴリ」の2階層構造のメニューを作成
- [重要] サブカテゴリのリンク先は、必ず「コレクション」から選択してください

Sections フォルダに custom-navigation.liquid という名前で新規作成し、以下のコードを貼り付けます。
<style>
:root { --side-nav-width: 260px; --side-nav-bg: #ffffff; }
.side-nav-root { width: 100%; margin-bottom: 2rem; position: relative; z-index: 101; }
.side-nav-wrapper { background: var(--side-nav-bg); border: 1px solid #e5e5e5; }
.side-nav-list { list-style: none; padding: 0; margin: 0; }
.side-nav-item { position: relative; border-bottom: 1px solid #f0f0f0; }
.side-nav-header { display: flex; justify-content: space-between; align-items: center; }
.side-nav-link { display: block; width: 100%; padding: 1.2rem 1.5rem; text-decoration: none; color: #333; font-weight: 600; font-size: 1.4rem; }
.side-nav-arrow { position: absolute; right: 1.5rem; width: 8px; height: 8px; border-top: 2px solid #999; border-right: 2px solid #999; transform: rotate(45deg); pointer-events: none; }
/* PC: ホバーメガメニュー(重なり順を最優先) */
@media screen and (min-width: 750px) {
.side-nav-root { max-width: var(--side-nav-width); }
.side-nav-megapanel {
display: none; position: absolute; left: 100%; top: -1px; width: 540px;
background: #fff; border: 1px solid #e5e5e5; box-shadow: 15px 0 30px rgba(0,0,0,0.1);
z-index: 99999 !important; padding: 2.5rem;
}
.side-nav-item:hover .side-nav-megapanel { display: block; }
.side-nav-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 2rem; }
.side-nav-mobile-toggle { display: none; }
}
/* スマホ: アコーディオン */
@media screen and (max-width: 749px) {
.side-nav-mobile-toggle {
display: flex; width: 100%; padding: 1.2rem; background: #fff; border: 1px solid #333;
font-weight: bold; font-size: 1.4rem; justify-content: space-between; align-items: center;
}
.side-nav-mobile-toggle .toggle-icon { width: 8px; height: 8px; border-top: 2px solid #333; border-right: 2px solid #333; transform: rotate(135deg); transition: 0.3s; }
.side-nav-wrapper { display: none; }
.side-nav-wrapper.is-open { display: block; }
.side-nav-megapanel { display: none; background: #fafafa; padding: 1.5rem; border-top: 1px solid #eee; }
.side-nav-header.is-sub-open + .side-nav-megapanel { display: block; }
.side-nav-header.is-sub-open .side-nav-arrow { transform: rotate(135deg); }
.side-nav-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 1rem; }
}
.side-nav-child-item { display: flex; flex-direction: column; align-items: center; text-decoration: none; color: #666; font-size: 1.2rem; text-align: center; }
.side-nav-child-item img { margin-bottom: 0.8rem; object-fit: contain; }
.side-nav-placeholder { width: 40px; height: 40px; background: #f5f5f5; margin-bottom: 0.8rem; border-radius: 4px; }
</style>
<script>
document.addEventListener('DOMContentLoaded', () => {
const toggleBtn = document.querySelector('.side-nav-mobile-toggle');
const navWrapper = document.querySelector('.side-nav-wrapper');
if (toggleBtn && navWrapper) {
toggleBtn.addEventListener('click', () => {
const isOpen = navWrapper.classList.toggle('is-open');
toggleBtn.setAttribute('aria-expanded', isOpen);
});
}
document.querySelectorAll('.side-nav-header').forEach(header => {
header.addEventListener('click', (e) => {
if (window.innerWidth < 750 && header.nextElementSibling?.classList.contains('side-nav-megapanel')) {
e.preventDefault();
header.classList.toggle('is-sub-open');
}
});
});
});
</script>
{%- if section.settings.menu != blank -%}
<div class="side-nav-root">
<!-- スマホ用開閉ボタン -->
<button type="button" class="side-nav-mobile-toggle" aria-expanded="false">
{{ section.settings.mobile_button_label }}
<span class="toggle-icon"></span>
</button>
<nav class="side-nav-wrapper">
<ul class="side-nav-list" role="list">
{%- for link in section.settings.menu.links -%}
<li class="side-nav-item">
<div class="side-nav-header">
<a href="{{ link.url }}" class="side-nav-link">{{ link.title }}</a>
{%- if link.links != blank -%}
<span class="side-nav-arrow" aria-hidden="true"></span>
{%- endif -%}
</div>
{%- if link.links != blank -%}
<div class="side-nav-megapanel">
<div class="side-nav-grid">
{%- for childlink in link.links -%}
{%- assign coll = childlink.object -%}
<a href="{{ childlink.url }}" class="side-nav-child-item">
{%- if coll.metafields.custom.category_icon != blank -%}
<img src="{{ coll.metafields.custom.category_icon | image_url: width: 80 }}"
alt="{{ childlink.title }}" width="40" height="40" loading="lazy">
{%- else -%}
<div class="side-nav-placeholder"></div>
{%- endif -%}
<span>{{ childlink.title }}</span>
</a>
{%- endfor -%}
</div>
</div>
{%- endif -%}
</li>
{%- endfor -%}
</ul>
</nav>
</div>
{%- endif -%}
{% schema %}
{
"name": "カスタム・サイドメニュー",
"settings": [
{
"type": "link_list",
"id": "menu",
"label": "メニューを選択",
"default": "main-menu"
},
{
"type": "text",
"id": "mobile_button_label",
"label": "スマホ用ボタンのラベル",
"default": "カテゴリから探す"
}
],
"presets": [
{
"name": "カスタム・サイドメニュー"
}
]
}
{% endschema %}ステップ2:theme.liquid のレイアウト拡張
Dawnの1カラム構造を、サイドバーが共存できる2カラム構造へ拡張します。
Layout/theme.liquid を開き、{{ content_for_layout }} 周辺を以下のように書き換えます。

<main id="MainContent" class="content-for-layout focus-none" role="main" tabindex="-1">
<div class="page-width custom-main-flex-container">
{%- if template == 'index' or template contains 'collection' -%}
<aside class="custom-sidebar-area">
{% section 'custom-navigation' %}
</aside>
{%- endif -%}
<div class="custom-main-content-area">
{{ content_for_layout }}
</div>
</div>
</main>
<style>
@media screen and (min-width: 750px) {
.custom-main-flex-container {
display: flex; gap: 4rem; max-width: 160rem !important; margin: 4rem auto; position: relative; z-index: 1;
}
.custom-sidebar-area {
width: 260px; flex-shrink: 0; position: sticky; top: 2rem; height: fit-content; z-index: 100;
}
.custom-main-content-area { flex-grow: 1; position: relative; z-index: 1; }
}
</style>ステップ3:動作確認と運用のコツ
実装が完了したら、管理画面の**[カスタマイズ]**から「カスタム・サイドメニュー」セクションを追加し、作成したメニューを選択してください。
- PC: マウスを重ねると、バナーや商品画像の上に重なる形でメガメニューがパッと表示されます。
- スマホ: 「カテゴリから探す」というボタンが表示され、タップしたときだけメニューが展開する省スペース設計です。
⚠️ 他のテーマをご使用の場合の注意点
今回のコードは最新の Dawn(およびOS 2.0準拠の無料テーマ) に最適化されています。
他社製の有料テーマや、既に大幅にカスタマイズされたテーマの場合、以下の理由でそのまま動かない可能性があります。
- CSSクラス名の衝突: テーマ独自のレイアウト指定と干渉する場合があります。
- グリッドシステムの相違: page-width というクラス名を使っていないテーマでは、レイアウトが崩れることがあります。
- JavaScriptの競合: 既に搭載されているメニュー機能とスクリプトが干渉する場合があります。
うまくいかない場合は、テーマ独自のメインエリアのIDやクラス名に合わせてCSSを調整する必要があります。
まとめ
ナビゲーションはECサイトの「顔」であり、接客の要です。
Dawnのポテンシャルを最大限に引き出し、標準機能を賢く組み合わせることで、「表示速度」「コスト」「デザイン」のすべてにおいて妥協しないストア作りが可能です。
アプリの月額費用を抑えたい、もっと自由なレイアウトにしたいとお考えの方は、ぜひこのカスタマイズに挑戦してみてください!
カスタマイズのご相談はこちら
自社ストアに合わせた微調整や、他テーマへの導入でお困りの方はお気軽にお問い合わせください。
当ブログ お問い合わせフォーム
https://yurufuwacat.com/question/
MottuDesign公式HP CONTACTフォーム
https://mottu-design.com/contact/