アプリなしでShopifyにウィッシュリストを追加:コード付き4つのDIY方法(2026年版)

はい、アプリなしでShopifyにウィッシュリストを追加できます。実際に動くコード付きの4つの方法、それぞれの限界、そしてアプリが本当に元を取れる場面を解説します。

Sep
Sep
15
Read
2026年6月8日
アプリなしでShopifyにウィッシュリストを追加:コード付き4つのDIY方法(2026年版)

結論を先に言うと、はい、アプリなしでShopifyにウィッシュリストを追加できます。 ただしShopifyは標準機能としては提供していません。そしてDIY方法のほとんどは、実店舗のスケールには耐えられません。とはいえ、商品数が数百以下で、開発者フレンドリーなテーマを使っているなら、いくつかの方法は十分に機能します。

このガイドでは、動作する全方法、実際のコード、そしてそれぞれの限界について正直にお伝えします。読み終わる頃には、DIY版を導入すべきか、それとも面倒を避けるべきかが分かるはずです。

Shopifyにウィッシュリスト機能は標準搭載されている?

いいえ。2026年現在、Shopifyはどのプラン(BasicでもPlusでも)にもウィッシュリスト機能を含めていません。自分で構築するか、サードパーティのアプリをインストールするかの二択です。

だからこそ、このキーワードが存在します。毎月数万人のマーチャントが「shopify wishlist without app(Shopify ウィッシュリスト アプリなし)」を検索し、隠された設定を期待しています。そんなものはありません。しかし、Liquid、JavaScript、metafieldsを使って構築する妥当な方法が4つあります。順に見ていきましょう。

方法1:localStorageウィッシュリスト(最も一般的なDIY)

これは「無料ウィッシュリスト」チュートリアルの90%が教える方法です。商品カードにハートボタンを追加し、ブラウザのlocalStorageに商品データを保存し、保存された配列からウィッシュリストページをレンダリングします。

メリット: ログイン不要。オフラインでも動作。バックエンド不要。約50行のコード。

デメリット: ウィッシュリストは1つのブラウザの、1つのデバイスにしか存在しません。買い物客がモバイルで保存してデスクトップで戻ってきたら、ウィッシュリストは空です。Cookieを削除?消えます。ブラウザを切り替え?消えます。さらに、商品が値下げされたり再入荷したりしてもメールを送れません。相手が誰だか分からないからです。

ステップ1 — 商品ページにウィッシュリストボタンを追加

テーマコードエディタ(オンラインストア → テーマ → コードを編集)を開き、商品テンプレートのスニペット(通常はsnippets/product-card.liquidまたはsections/main-product.liquid内)を見つけます。ハートを表示したい場所にこれを挿入します:

<button
  type="button"
  class="wishlist-btn"
  data-id="{{ product.id }}"
  data-handle="{{ product.handle }}"
  data-title="{{ product.title | escape }}"
  data-image="{{ product.featured_image | image_url: width: 400 }}"
  data-price="{{ product.price | money }}"
  aria-label="Add to wishlist">
  <span class="wishlist-icon">♡</span>
  <span class="wishlist-label">Save</span>
</button>

ステップ2 — JavaScriptを設定

これをassets/wishlist.jsに追加(ファイルを作成)し、theme.liquidから{{ 'wishlist.js' | asset_url | script_tag }}で読み込みます:

(function () {
  const KEY = 'shopify_wishlist_v1';
  const read = () => JSON.parse(localStorage.getItem(KEY) || '[]');
  const write = (list) => localStorage.setItem(KEY, JSON.stringify(list));

  function syncButton(btn, list) {
    const inList = list.some(i => i.id === btn.dataset.id);
    btn.classList.toggle('in-wishlist', inList);
    btn.querySelector('.wishlist-icon').textContent = inList ? '♥' : '♡';
    btn.querySelector('.wishlist-label').textContent = inList ? 'Saved' : 'Save';
  }

  function updateCount() {
    const count = read().length;
    document.querySelectorAll('.wishlist-count').forEach(el => {
      el.textContent = count;
      el.hidden = count === 0;
    });
  }

  document.querySelectorAll('.wishlist-btn').forEach(btn => {
    syncButton(btn, read());

    btn.addEventListener('click', () => {
      let list = read();
      const exists = list.find(i => i.id === btn.dataset.id);
      if (exists) {
        list = list.filter(i => i.id !== btn.dataset.id);
      } else {
        list.push({
          id: btn.dataset.id,
          handle: btn.dataset.handle,
          title: btn.dataset.title,
          image: btn.dataset.image,
          price: btn.dataset.price,
          addedAt: Date.now()
        });
      }
      write(list);
      syncButton(btn, list);
      updateCount();
    });
  });

  updateCount();
})();

ステップ3 — ウィッシュリストページを作成

オンラインストア → ページで「Wishlist」という名前の新しいページを作成し、ハンドルをwishlistにします。次にtemplates/page.wishlist.liquidというテンプレートを作成し、そのページに割り当てます:

{% layout 'theme' %}

<div class="page-width wishlist-page">
  <h1>Your wishlist</h1>
  <div id="wishlist-grid" class="wishlist-grid"></div>
  <p id="wishlist-empty" hidden>
    Your wishlist is empty.
    <a href="{{ routes.collections_url }}/all">Browse products</a>.
  </p>
</div>

<script>
  (function () {
    const list = JSON.parse(localStorage.getItem('shopify_wishlist_v1') || '[]');
    const grid = document.getElementById('wishlist-grid');
    const empty = document.getElementById('wishlist-empty');

    if (!list.length) { empty.hidden = false; return; }

    grid.innerHTML = list.map(item => `
      <article class="wishlist-card">
        <a href="/products/${item.handle}">
          <img src="${item.image}" alt="${item.title}" loading="lazy">
          <h3>${item.title}</h3>
          <p>${item.price}</p>
        </a>
        <button data-id="${item.id}" class="wishlist-remove">Remove</button>
      </article>
    `).join('');

    grid.addEventListener('click', e => {
      const btn = e.target.closest('.wishlist-remove');
      if (!btn) return;
      const next = JSON.parse(localStorage.getItem('shopify_wishlist_v1'))
        .filter(i => i.id !== btn.dataset.id);
      localStorage.setItem('shopify_wishlist_v1', JSON.stringify(next));
      btn.closest('.wishlist-card').remove();
      if (!next.length) { grid.innerHTML = ''; empty.hidden = false; }
    });
  })();
</script>

これがlocalStorageウィッシュリストの完全版です。動作はします。しかし、デバイスをまたぐ買い物客には30〜50%の離脱率があり、分析データもなく、欲しかった商品がセールになったり再入荷したりしても誰にもメールを送れません。だから方法2に続きます。

方法2:顧客メタフィールド(「適切な」DIYアプローチ)

買い物客がアカウントを作成するなら、metafields経由で顧客オブジェクトにウィッシュリストを保存できます。これでウィッシュリストはデバイスをまたいで追従し、技術的にはメールも送れます。ただし、それらのメールを実際に送信するのは別問題です。

メリット: デバイス間同期。クエリ可能な実データ。ブラウザのクリアにも耐える。

デメリット: 顧客のログインが必要(匿名と比較すると即座に60〜80%の離脱)。ストアフロントからメタフィールドに書き込むには、顧客アクセストークン付きのStorefront API、またはApp Proxy + 小さなサーバーレス関数が必要です。コピペで済む解決策はありません。開発作業へのコミットが必要です。

メタフィールドのセットアップ

設定 → カスタムデータ → 顧客 → 定義を追加へ進みます:

  • ネームスペースとキー:custom.wishlist
  • タイプ:JSON
  • アクセス:Storefront 読み取り + 書き込み

Liquidでウィッシュリストの状態を表示

{% if customer %}
  {% assign wishlist_raw = customer.metafields.custom.wishlist.value | default: '[]' %}
  {% assign wishlist = wishlist_raw | parse_json %}

  <button
    class="wishlist-btn-meta"
    data-id="{{ product.id }}"
    data-customer="{{ customer.id }}">
    {% if wishlist contains product.id %}♥ Saved{% else %}♡ Save{% endif %}
  </button>
{% else %}
  <a href="{{ routes.account_login_url }}?return_url={{ request.path }}"
     class="wishlist-btn-logged-out">♡ Log in to save</a>
{% endif %}

メタフィールドに書き込む

ここからが厄介です。Storefront APIは匿名のJSから直接customer.metafieldsを変更させてくれません。顧客アクセストークン、または認証済みのApp Proxyが必要です。最小限のApp Proxyハンドラ(Node.js、Vercel/Cloudflare Workersにデプロイ)はこのようになります:

// /api/wishlist-toggle  (Shopify App Proxy)
export default async function handler(req) {
  const { customerId, productId } = await req.json();

  const query = `
    mutation updateWishlist($id: ID!, $value: String!) {
      customerUpdate(input: {
        id: $id,
        metafields: [{
          namespace: "custom",
          key: "wishlist",
          type: "json",
          value: $value
        }]
      }) {
        customer { id }
        userErrors { message }
      }
    }
  `;

  // 1. Fetch current list
  // 2. Toggle productId
  // 3. Send mutation to Admin API
  // 4. Return new state
}

認証、エラー処理、レート制限まで実装すると、完全版は約200行になります。経験のない開発者の現実的な構築時間は1〜2日。経験者なら2〜3時間です。

方法3:line item propertiesによる隠しカート(後で保存)

一部のチュートリアルでは、数量0のウィッシュリストアイテムをカートに追加したり、_wishlist: trueのようなカスタムプロパティを使ったりして、カートを悪用することを提案しています。やめてください。 カートの計算が壊れ、チェックアウトが混乱し、ほとんどのテーマはそのアイテムをレンダリングしてしまいます。Redditで推奨されているのを見たときに避けるべきだと分かるように、ここで言及しています。

唯一まだ擁護可能なバリアントは、メインカートの外でレンダリングする別個の「後で保存」カート属性です。このように:

<!-- in cart.liquid -->
{% assign saved = cart.attributes.saved_items | split: ',' %}
{% if saved.size > 0 %}
  <div class="saved-for-later">
    <h2>Saved for later</h2>
    {% for handle in saved %}
      {% assign p = all_products[handle] %}
      <a href="/products/{{ p.handle }}">{{ p.title }} — {{ p.price | money }}</a>
    {% endfor %}
  </div>
{% endif %}

中途半端な対策です。カートが空になるとカート属性も消えます。スキップしましょう。

方法4:共有可能URLウィッシュリスト(ソーシャルハック)

これは本当のウィッシュリストではなく、「お気に入りをシェア」リンクです。クライアントサイドでリストを構築し、買い物客が共有またはブックマークできるURLにエンコードします。

// Build a share URL from the localStorage list
function getShareUrl() {
  const ids = JSON.parse(localStorage.getItem('shopify_wishlist_v1') || '[]')
    .map(i => i.id)
    .join(',');
  return `${location.origin}/pages/wishlist?items=${ids}`;
}

// On the wishlist page, hydrate from ?items=
const params = new URLSearchParams(location.search);
if (params.get('items')) {
  const ids = params.get('items').split(',');
  // Fetch each /products/{id}.js and render
  Promise.all(ids.map(id =>
    fetch(`/products/${id}.js`).then(r => r.json())
  )).then(renderWishlist);
}

方法1への追加機能として有用です。買い物客が友達とリストを共有したり、自分自身に送ったりできます。単独でウィッシュリストとして機能するものではありません。

正直な評価:DIYで十分な場合と破綻する場合

DIYが機能するのは、以下の4つすべてにはいと答えられる場合です:

  1. ストアのSKU数が約500未満(手動メンテナンスが現実的)。
  2. デバイス間同期を気にしない(または既に顧客アカウントを強制している)。
  3. ウィッシュリスト商品がセールになったり再入荷したりした際に顧客にメールを送る予定がない。
  4. スタッフに開発者がいる、または自分でLiquidを編集できる。

DIYは以下を望んだ瞬間に破綻します:

  • 顧客に「ウィッシュリストの商品が再入荷しました」とメールを送りたい — localStorageのエントリの持ち主が誰なのか分かりません。
  • SMSやメールで放置されたウィッシュリストを回収したい — 同じ問題。
  • 分析でウィッシュリストのコンバージョンを表示したい — GA4イベントは発火させられますが、バックエンドの作業なしには売上に紐付けられません。
  • ゲストにアカウント作成を強制せず保存させ、かつ後でログインしたときにメールアドレスに同期させたい。
  • 技術的でないマーケターに管理を任せたい。

これらは理論上の制限ではありません。DIYウィッシュリストで始めたストアのほとんどが6か月以内にアプリに切り替える理由です。

DIYウィッシュリストの実際のコスト(正直に)

人々が「アプリなし」を検索するのは、アプリが高価な選択肢だと思い込んでいるからです。検証してみましょう。

localStorage版を構築する開発者:2〜4時間。 時給75ドルなら150〜300ドル、加えて継続コストはゼロ。妥当です。

メールトリガー付きのメタフィールド版を構築する開発者:8〜16時間。 600〜1,200ドル、加えて実際にメールを送るためのKlaviyoなど(月20〜45ドル)。さらにテーマが更新されたりShopifyのチェックアウト拡張が変更されたりするたびにメンテナンスが発生します。

別個のウィッシュリストアプリ + 別個の再入荷通知アプリ + 別個の予約注文アプリ:通常はそれぞれ月15〜25ドル。つまり3つの機能で月45〜75ドル。

統合アプリ:請求は1つだけ。

あるいは:3機能すべてを1つのアプリで、無料プラン付き

開示 — 私たちはNotify Me!を作っており、ほとんどのストアにはウィッシュリスト + 再入荷通知 + 予約注文がセットで必要だという理由で構築しました。顧客が商品を保存 → 在庫切れになる → 通知が届く → 再入荷しない場合は予約注文を提供。一緒に使うべき3つの機能です。

セットアップは実際にどう見えるか

ダッシュボードからページごと(商品、コレクション、ホーム)に機能をオン/オフできます。テーマコードのメンテナンスは不要です:

Notify Me! Shopify wishlist app dashboard showing guest mode enabled, exclude-specific-variants control, and visibility toggles for Product Page, Collection Page, and Home Page Notify Me!のウィッシュリスト画面 — ゲストモードはデフォルトでオンになっており、顧客がログインした瞬間にウィッシュリストがアカウントに紐付けられます。コード変更は不要です。

商品ページボタン — 完全カスタマイズ可能

ハート、ブックマーク、星のアイコンを選択。両状態のラベルを編集。ウィジェットはAdd-to-Cartボタンの隣にインラインでレンダリングされます:

Shopify wishlist button customization in Notify Me! showing heart, bookmark, and star icon options, custom 'Add to wishlist' and 'It's in wishlist' button labels, and a live product page preview with a LuxeCraft Mug 商品ページボタン設定 — Liquidに触れることなく、追加前/追加後のラベル、アイコン、スタイルを設定できます。

コレクションページウィジェット — すべてのカードで動作

DIY方法が最も苦労するところ:すべてのコレクションページのタイルに動作する保存ボタンを設置すること。アプリならこれを1つのトグルで処理します:

Shopify collection page wishlist buttons with star icons positioned top-right on product cards in a Notify Me! widget preview コレクションページウィジェット — アイコン、位置、表示スタイルを選択。すべての商品カードに自動でレンダリングされます。

価格(年額請求)

プラン価格ウィッシュリストアクション再入荷通知予約注文
Lite無料累計50回累計100回累計5回
Starter$15.92/月24,000/年6,000/年6,000/年
Standard$31.92/月120,000/年18,000/年18,000/年
Rocket$55.92/月300,000/年60,000/年120,000/年
Plus$399.92/月無制限無制限無制限

プランの詳細は料金ページをご覧ください。無料のLiteプランは、支払いをする前に実際にストアでテストできるように用意されています。ほとんどのストアは長期的にStarterプランを使用します。月15.92ドルで、別途インストールするはずの3つのアプリを置き換えられます。

上記のDIY版では実現できない機能:

  • ゲストモード(ログイン強制なし) — 初回ログイン時にウィッシュリストが自動的にアカウントへ紐付け
  • 顧客ごとに複数の名前付きリスト
  • ホーム、コレクション、商品ページのウィッシュリストウィジェット
  • 値下げ、在庫僅少、再入荷時の自動メール・SMSトリガー
  • 組み込みの予約注文ボタンと分割支払い
  • テーマに合わせた完全なLiquidカスタマイズ
  • BtoBおよびDtoC対応を標準装備

Shopifyアプリストアで無料スタート →

FAQ

コーディングなしでShopifyにウィッシュリストを追加できますか?

アプリなしでは無理です。すべてのノーコード方法は、ウィッシュリストアプリのインストールか、テーマへのコード貼り付けのいずれかが必要です。標準のトグル設定はありません。

無料のShopifyウィッシュリストはありますか?

いくつかあります。上記のlocalStorage方法は、自分で構築すれば無料です。アプリでは、Notify Me!のLiteプランがウィッシュリストアクション累計50回まで無料です。これは、高額プランに移行する前に、顧客が実際にこの機能をストアで使うかを検証するのに十分です。

Shopify 2.0にはウィッシュリストがありますか?

いいえ。Shopify 2.0はテーマアーキテクチャ(セクション、ブロック、アプリブロック)のことで、ウィッシュリスト機能を追加するものではありません。ただし、アプリブロックを介してウィッシュリストアプリのインストールがよりクリーンになりました。だからこそ、最新のウィッシュリストアプリの多くは数秒で2.0テーマに組み込めるのです。

Liquidだけでウィッシュリストを追加できますか?

部分的には可能です。Liquidは顧客メタフィールドにデータがあればウィッシュリストを表示できますが、ストアフロントからメタフィールドに書き込むことはできません。アイテムを保存するにはJavaScriptと、Storefront APIまたはApp Proxyのいずれかが必要です。

アプリなしでShopifyの商品ページにウィッシュリストを追加するにはどうすればよいですか?

上記の方法1を使ってください:ウィッシュリストボタンスニペットを商品テンプレートに貼り付け、wishlist.jsをテーマアセットに追加し、templates/page.wishlist.liquidからウィッシュリストページを作成します。完全なコードはこのガイドに記載されています。

ウィッシュリストは実際にコンバージョンを向上させますか?

はい — 保存することは実際の購入意図を示すシグナルであり、ウィッシュリストを使う買い物客は閲覧のみの買い物客よりも有意に高い率でコンバージョンする傾向があります。さらに大きな効果は、ウィッシュリスト所有者に商品がセールになったり再入荷したりした際にメールを送ることから生まれます。DIY方法が及ばないのはこの部分です。

顧客がCookieをクリアすると、localStorageウィッシュリストはどうなりますか?

完全に削除されます。バックアップなし、復旧なし。これがDIYアプローチからストアが卒業する最大の理由です。

ウィッシュリストは再入荷メールをトリガーできますか?

ウィッシュリストを顧客のメールアドレスに紐付けている場合に限ります。localStorageでは不可能です。顧客メタフィールドなら可能ですが、それでも在庫変化を検知してメールを送るバックエンドが必要です。Notify Me!のような両方を行うアプリなら、その作業を完全に省略できます。

ウィッシュリストとウェイトリストの違いは何ですか?

ウィッシュリストは、買い物客が覚えておきたい商品のキュレーションリストです。一方ウェイトリストは、一時的に在庫切れの商品や発売前の商品のための順番待ち列です。ウィッシュリストはオープンエンドで、ウェイトリストは在庫や発売日によって時間的に区切られています。ほとんどのストアは最終的に両方を欲しがります。

Continue Selling When Out of Stockとウィッシュリスト、どちらが良いですか?

別の問題です。Continue Selling When Out of Stockは、在庫のない商品の注文を受け付けられるようにします(実質的に予約注文)。ウィッシュリストは、買い物客がコミットせずにアイテムを保存できるようにします。在庫のない商品で需要を捉えようとしているなら、通常は両方とも欲しくなります — 意図を集めるウィッシュリストと、今すぐ買う準備ができている買い物客のための予約注文オプションです。


最終更新:2026年6月。Online Store 2.0のShopifyテーマ向けに書かれています。テーマが古い(vintage)場合、Liquidのパスは少し異なります — JavaScriptは同一です。

Install or Regret!

Stores using Notify Me! have generated Millions in Revenue. Join the club:
Start Free

NotifyMe を配置する準備ができました 専門知識をテストに電子メールで送信しますか?

在庫が少ない場合や在庫切れの場合でも、再入荷、在庫少、予約注文を利用して収益を生み出しましょう。
今すぐインストール