【Shopify Theme Blocks】Webデザインを意識した万能セクションを作ろう
- ECサイト
- Shopify
- ThemeBlocks
- サイト構築
- テーマカスタマイズ
- 開発
目次
1. はじめに
1.1 記事について
この記事ではShopify Winter Editions ‘25のアップデート機能の一つTheme Blocksについて、Webデザインを意識した万能セクションの開発にチャレンジしてみたいと思います。
1.2 記事の対象
この記事は、Shopifyテーマ開発者に向けて記載しております。
1.3 記事
この記事を読み終えるまでに、約10分です。
2. Shopify Theme Blocksでできること
2.1 Shopify Theme Blocksの基本仕様
Theme Blocksは簡単に言うと、セクション内で自由にブロック配置ができる機能です。 今まではセクション毎に専用のブロックを用意し、決められた要素・レイアウトのブロックしか配置できませんでしたが、Theme Blocksであればブロックの中身を任意のパーツで構成できるため、同じセクションでも用途に合わせて様々な見せ方が可能になりました。


2.2 既存セクションの課題
Shopifyのカスタマイズ機能はノーコードでセクションを追加したりテキストを変更できるため便利であるものの、フロントエンド開発視点で見ると同じ様なレイアウトでもコンテンツの中身が少し異なるだけで都度専用のセクションを開発する必要があり、個人的には非常に非効率な印象がありました。
例えば次の様な分割レイアウトのデザインがあった場合、「CHARACTERISTIC」エリアの3カラム部分と、「BUSINESS」エリアの分割カラム部分は装飾的な見た目は確かに異なりますが、構造的に分解してみるとどちらもほぼ同じ構成であることがわかります。(画像上に見出しがあるかないかの違いだけ)
Shopifyでこのデザインをセクション化する場合、通常であれば別レイアウトになるためこの見出し1つの違いのためにそれぞれセクションを用意する形になるかと思います。

またShopifyではセクション単位でのコンテンツ配置となるため、こちらの様にセクションを跨いだ背景設定が困難といった点も、微妙な差異による不要なセクション開発の要因となっていると感じています。

2.3 Shopify Theme Blocksでやってみたいこと
Shopify Theme Blocksを利用すれば、コンテンツの差異の解消・グループ化が実現できるため、以下の様に様々なレイアウトも1つのセクションで再現できる可能性があります。
今回はこちらの様なレイアウトを1セクションで実装みたいと思います。

開発コードサンプル
万能セクションのサンプルコードです。 一部アレンジを加えていますが、Dawnのgrid思想に構造を合わせています。 ※CSSは適宜調整してください。
3.1 パーツの作成
パーツはグループ要素を含めて、全部で6種類用意しました。今後増える可能性もありますが、以下のパーツで大体のものには対応できるかと思います。 以下を「blocks」ディレクトリに配置します。
| ファイル | 用途 |
|---|---|
| custom-contentsgroup-multicolumn.liquid | グループ用のパーツ |
| custom-contents-heading.liquid | 見出し用のパーツ |
| custom-contents-text.liquid | テキスト用のパーツ |
| custom-contents-image.liquid | 画像用のパーツ |
| custom-contents-button.liquid | ボタン(リンク)用のパーツ |
| custom-contents-liquid.liquid | スクリプト用のパーツ |
custom-contentsgroup-multicolumn.liquid
<div class="custom-blocks-group {{ block.settings.group_id }} grid {{ block.settings.column_gap }} {{ block.settings.column_grid }} {{ block.settings.column_grid_sp }} align-{{ block.settings.alignment }} valign-{{ block.settings.valignment }}" data-group-label="{{ block.settings.group_name }}" data-group-id="{{ block.settings.group_id }}">
{% content_for 'blocks' %}
</div>
{% schema %}
{
"name": "Group(マルチカラム)",
"class": "group__item grid__item",
"blocks": [
{ "type": "custom-contentsgroup-multicolumn" },
{ "type": "custom-contents-heading" },
{ "type": "custom-contents-text" },
{ "type": "custom-contents-image" },
{ "type": "custom-contents-button" },
{ "type": "custom-contents-liquid" },
{ "type": "@app" }
],
"settings": [
{
"type": "text",
"id": "group_id",
"label": "グループの追加クラス",
},
{
"type": "select",
"id": "column_grid",
"options": [
{
"value": "grid--1-col",
"label": "1列"
},
{
"value": "grid--2-col",
"label": "2列"
},
{
"value": "grid--3-col",
"label": "3列"
},
{
"value": "grid--4-col",
"label": "4列"
},
{
"value": "grid--5-col",
"label": "5列"
},
{
"value": "grid--6-col",
"label": "6列"
},
],
"default": "grid--5-col",
"label": "デスクトップの列数"
},
{
"type": "select",
"id": "column_grid_sp",
"options": [
{
"value": "grid--1-col-tablet",
"label": "1列"
},
{
"value": "grid--2-col-tablet",
"label": "2列"
},
],
"default": "grid--2-col-tablet",
"label": "モバイルでの列数"
},
{
"type": "select",
"id": "column_gap",
"options": [
{
"value": "grid--gapless",
"label": "余白なし"
},
{
"value": "grid--gap-xs",
"label": "最小"
},
{
"value": "grid--gap-s",
"label": "狭い"
},
{
"value": "grid--gap-def",
"label": "通常"
},
{
"value": "grid--gap-l",
"label": "広い"
},
],
"default": "grid--gap-def",
"label": "カラム間の余白"
},
{
"type": "text_alignment",
"id": "alignment",
"label": "カラムの配置"
},
{
"type": "select",
"id": "valignment",
"options": [
{
"value": "top",
"label": "上寄せ"
},
{
"value": "center",
"label": "中央寄せ"
}
],
"default": "top",
"label": "上寄せ"
},
],
"presets": [
{
"name": "Group(マルチカラム)"
}
]
}
{% endschema %}custom-contents-heading.liquid
<{{ block.settings.heading_type }} class="title align-{{ block.settings.alignment }} size-{{ block.settings.heading_size }} {{ block.settings.item_class }}">{{ block.settings.heading }}</{{ block.settings.heading_type }}>
{% schema %}{"name":"見出し","class":"blocks__item blocks__item-heading grid__item","settings":[{"type":"text","id":"heading","label":"見出し"},{"type":"select","id":"heading_type","options":[{"value":"h1","label":"h1"},{"value":"h2","label":"h2"},{"value":"h3","label":"h3"},{"value":"h4","label":"h4"},{"value":"h5","label":"h5"},{"value":"p","label":"指定なし"}],"default":"h3","label":"見出しタイプ"},{"type":"select","id":"heading_size","options":[{"value":"xs","label":"最小"},{"value":"s","label":"小"},{"value":"def","label":"標準"},{"value":"m","label":"大"},{"value":"l","label":"特大"},{"value":"xl","label":"最大"}],"default":"m","label":"見出しサイズ"},{"type":"text_alignment","id":"alignment","label":"配置"},{"type":"text","id":"item_class","label":"要素の追加クラス"},],"presets":[{"name":"見出し"},]}{% endschema %}custom-contents-text.liquid
<div class="align-{{ block.settings.alignment }} {{ block.settings.item_class }}">{{block.settings.text}}</div>
{% schema %}{"name":"テキスト","class":"blocks__item blocks__item-text grid__item","settings":[{"type":"richtext","id":"text","label":"Text"},{"type":"text_alignment","id":"alignment","label":"配置"},{"type":"text","id":"item_class","label":"要素の追加クラス"},],"presets":[{"name":"テキスト"},]}{% endschema %}custom-contents-image.liquid
<picture class="image-wrapper {{ block.settings.item_class }}"><img src="{{ block.settings.image | img_url: 'master' }}" loading="lazy"></picture>
{% schema %}{"name":"画像","class":"blocks__item blocks__item-image grid__item","settings":[{"type":"image_picker","id":"image","label":"t:sections.multicolumn.blocks.column.settings.image.label"},{"type":"text","id":"item_class","label":"要素の追加クラス"},],"presets":[{"name":"画像"},]}{% endschema %}custom-contents-button.liquid
<div class="align-{{ block.settings.alignment }} {{ block.settings.item_class }}"><{%- if block.settings.button_link !=blank -%}a{%- else -%}span{% endif %}{%- if block.settings.button_link !=blank -%}href="{{ block.settings.button_link }}"{% endif %}class="button">{{- block.settings.button_label | escape -}}</{%- if block.settings.button_link !=blank -%}a{%- else -%}span{%- endif -%}></div>
{% schema %}{"name":"ボタン","class":"blocks__item blocks__item-button grid__item","settings":[{"type":"text","id":"button_label","default":"詳しくはこちら","label":"t:sections.multicolumn.settings.button_label.label"},{"type":"url","id":"button_link","label":"t:sections.multicolumn.settings.button_link.label"},{"type":"text_alignment","id":"alignment","label":"配置"},{"type":"text","id":"item_class","label":"要素の追加クラス"},],"presets":[{"name":"ボタン"},]}{% endschema %}custom-contents-liquid.liquid
{{section.settings.custom_liquid}}
{% schema %}{"name":"カスタムLiquid","class":"blocks__item blocks__item-liquid grid__item","settings":[{"type":"liquid","id":"custom_liquid","label":"t:sections.custom-liquid.settings.custom_liquid.label","info":"t:sections.custom-liquid.settings.custom_liquid.info"}],"presets":[{"name":"カスタムLiquid"},]}{% endschema %}3.2 セクションの作成
custom-multicolumn.liquid
<div class="custom-multicolumn {{ section.settings.section_class }} page-width">
<div class="grid {{ section.settings.column_gap }} {{ section.settings.column_grid }} {{ section.settings.column_grid_sp }} align-{{ section.settings.alignment }} valign-{{ section.settings.valignment }}">
{% content_for 'blocks' %}
</div>
</div>
{% schema %}
{
"name": "マルチカラム(Theme Blocks)",
"class": "section custom-section-multicolumn",
"tag": "section",
"blocks": [
{ "type": "custom-contentsgroup-multicolumn" },
{ "type": "custom-contents-heading" },
{ "type": "custom-contents-text" },
{ "type": "custom-contents-image" },
{ "type": "custom-contents-button" },
{ "type": "custom-contents-liquid" },
{ "type": "@app" }
],
"settings": [
{
"type": "text",
"id": "section_class",
"label": "セクションの追加class"
},
{
"type": "select",
"id": "column_grid",
"options": [
{
"value": "grid--1-col",
"label": "1列"
},
{
"value": "grid--2-col",
"label": "2列"
},
{
"value": "grid--3-col",
"label": "3列"
},
{
"value": "grid--4-col",
"label": "4列"
},
{
"value": "grid--5-col",
"label": "5列"
},
{
"value": "grid--6-col",
"label": "6列"
},
],
"default": "grid--5-col",
"label": "デスクトップの列数"
},
{
"type": "select",
"id": "column_grid_sp",
"options": [
{
"value": "grid--1-col-tablet",
"label": "1列"
},
{
"value": "grid--2-col-tablet",
"label": "2列"
},
],
"default": "grid--2-col-tablet",
"label": "モバイルでの列数"
},
{
"type": "select",
"id": "column_gap",
"options": [
{
"value": "grid--gapless",
"label": "余白なし"
},
{
"value": "grid--gap-xs",
"label": "最小"
},
{
"value": "grid--gap-s",
"label": "狭い"
},
{
"value": "grid--gap-def",
"label": "通常"
},
{
"value": "grid--gap-l",
"label": "広い"
},
],
"default": "grid--gap-def",
"label": "カラム間の余白"
},
{
"type": "text_alignment",
"id": "alignment",
"label": "カラムの配置"
},
{
"type": "select",
"id": "valignment",
"options": [
{
"value": "top",
"label": "上寄せ"
},
{
"value": "center",
"label": "中央寄せ"
}
],
"default": "top",
"label": "上寄せ"
},
],
"presets": [
{
"name": "マルチカラム(Theme Blocks)",
"blocks": [
{
"type": "custom-contentsgroup-multicolumn",
}
]
}
]
}
{% endschema %}3.3 ポイント解説
custom-contentsgroup-multicolumn.liquid
セクション自体のgrid化はもちろん、グループパーツもgrid化しているのでネストされた中でさらに分割化が可能です。
また各パーツにCSSのクラスを付与できるようにしているため、より細かなデザイン調整が可能です。

3.4 実装プレビュー
開発した万能セクションを使って、以下の通り色々なレイアウトパターンを1つのセクションで対応することができました!


まとめ
Shopify Theme Blocksの活かし方についてイメージ湧きましたでしょうか? 今回作成したセクションでも十分マルチに活躍できるかと思いますが、様々なケースに対応する中でより万能セクションへとブラッシュアップしていきたいと思います!
Theme Blocksのカスタマイズについては以下の記事も参考にしてみてください。
・Shopify Winter Editions ‘25 | 冬のアップデート2025:Theme Blocksと今後のテーマ開発の動向
・Shopify Winter Editions ‘25 | 冬のアップデート2025:Theme Blocksについて第二部:Theme Blocksの基本構成
・Shopify Winter ’25 Theme Blocks 応用編(第三部):ターゲティング&Static Blocks徹底解説
著者:T.O
弊社では、ECサイトのリプレース案件から、Shopifyカスタムアプリ開発、保守案件に至るまで、EC中心にプロジェクトの質にこだわり、お客様に笑顔になってもらえるよう日々邁進しております。
皆様からのお問い合わせ・ご相談をお待ちしております。
