Shopifyの購入ボタンでCart attributesを用いる:試作メモ

窓辺

先日カートパーマリンクの機能を知った際、仕組み的に実現可能に思えたので試作してみました。
当記事のサンプルは試作した仕組みをメモ的に残す目的のため、実際に使用可能なレベルではありません

実現したいこと

  • Shopifyの購入ボタンを使用する
  • Cart attributesに値を入れ、Shopifyに反映させる

想定する用途としては、配送日指定や熨斗関連の設定が挙げられます。
通常購入ボタンではこれらはできないはずですが、不勉強でしたらすみません。

サンプル

まず以下の準備を実行します。

  • Shopify管理画面で購入ボタンを作成
  • 購入ボタン作成時には、「レイアウトスタイル」は「クラシック」を選択

今回は試作のためボタンは消すので、「クリック時のアクション」はどれを選んでも構いません。
他方、後述しますがスライドインしてくるカートだと少々ややこしいことになるので、スライドインカートが出てこない「クラシック」を選びます。

サンプルコード

準備で作った購入ボタンのコードに少し手を入れますが、まずオリジナルを記載します。
商品IDとストアのURLは仮の値を設定しています。


<div id='product-component-0000000'></div>
<script type="text/javascript">
/*<![CDATA[*/
(function () {
  var scriptURL = 'https://sdks.shopifycdn.com/buy-button/latest/buy-button-storefront.min.js';
  if (window.ShopifyBuy) {
    if (window.ShopifyBuy.UI) {
      ShopifyBuyInit();
    } else {
      loadScript();
    }
  } else {
    loadScript();
  }
  function loadScript() {
    var script = document.createElement('script');
    script.async = true;
    script.src = scriptURL;
    (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(script);
    script.onload = ShopifyBuyInit;
  }
  function ShopifyBuyInit() {
    var client = ShopifyBuy.buildClient({
      domain: 'example.myshopify.com',
      storefrontAccessToken: 'xxxxxxxxxxxxxxx,
    });
    ShopifyBuy.UI.onReady(client).then(function (ui) {
      ui.createComponent('product', {
        id: '0000000',
        node: document.getElementById('product-component-0000000'),
        moneyFormat: '%24%7B%7Bamount%7D%7D',
        options: {
  "product": {
    "styles": {
      "product": {
        "@media (min-width: 601px)": {
          "max-width": "calc(25% - 20px)",
          "margin-left": "20px",
          "margin-bottom": "50px"
        }
      }
    },
    "buttonDestination": "checkout",
    "text": {
      "button": "Buy now"
    }
  },
  "productSet": {
    "styles": {
      "products": {
        "@media (min-width: 601px)": {
          "margin-left": "-20px"
        }
      }
    }
  },
  "modalProduct": {
    "contents": {
      "img": false,
      "imgWithCarousel": true,
      "button": false,
      "buttonWithQuantity": true
    },
    "styles": {
      "product": {
        "@media (min-width: 601px)": {
          "max-width": "100%",
          "margin-left": "0px",
          "margin-bottom": "0px"
        }
      }
    },
    "text": {
      "button": "Add to cart"
    }
  },
  "option": {},
  "cart": {
    "text": {
      "total": "Subtotal",
      "button": "Checkout"
    },
    "contents": {
      "note": true
    }
  },
  "toggle": {}
},
      });
    });
  }
})();
/*]]>*/
</script>

上記のproducts内に以下を追加します。


"templates": {
  "myButton": '<div><a style="background-color:#78b657;text-decoration:none;display:block;padding:1rem;text-align:center;color:#fff;margin-top:1rem;" target="_top" href="https://example.myshopify.com/cart/0000000:1?attributes[text]=test&attributes[date]=2023-9-23" rel="noopener">独自チェックアウトボタン</a></div>'
},
"contents": {
  "myButton": true,
  "button": false
},

上記を実際に追加すると以下のようになります。


<div id='product-component-0000000'></div>
<script type="text/javascript">
/*<![CDATA[*/
(function () {
  var scriptURL = 'https://sdks.shopifycdn.com/buy-button/latest/buy-button-storefront.min.js';
  if (window.ShopifyBuy) {
    if (window.ShopifyBuy.UI) {
      ShopifyBuyInit();
    } else {
      loadScript();
    }
  } else {
    loadScript();
  }
  function loadScript() {
    var script = document.createElement('script');
    script.async = true;
    script.src = scriptURL;
    (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(script);
    script.onload = ShopifyBuyInit;
  }
  function ShopifyBuyInit() {
    var client = ShopifyBuy.buildClient({
      domain: 'example.myshopify.com',
      storefrontAccessToken: 'xxxxxxxxxxxxxxx,
    });
    ShopifyBuy.UI.onReady(client).then(function (ui) {
      ui.createComponent('product', {
        id: '0000000',
        node: document.getElementById('product-component-0000000'),
        moneyFormat: '%24%7B%7Bamount%7D%7D',
        options: {
  "product": {
    "templates": {
      "myButton": '<div><a style="background-color:#78b657;text-decoration:none;display:block;padding:1rem;text-align:center;color:#fff;margin-top:1rem;" target="_top" href="https://example.myshopify.com/cart/0000000:1?attributes[text]=test&attributes[date]=2023-9-23">独自チェックアウトボタン</a></div>'
    },
    "contents": {
      "myButton": true,
      "button": false
    },
    "styles": {
      "product": {
        "@media (min-width: 601px)": {
          "max-width": "calc(25% - 20px)",
          "margin-left": "20px",
          "margin-bottom": "50px"
        }
      }
    },
    "buttonDestination": "checkout",
    "text": {
      "button": "Buy now"
    }
  },
  "productSet": {
    "styles": {
      "products": {
        "@media (min-width: 601px)": {
          "margin-left": "-20px"
        }
      }
    }
  },
  "modalProduct": {
    "contents": {
      "img": false,
      "imgWithCarousel": true,
      "button": false,
      "buttonWithQuantity": true
    },
    "styles": {
      "product": {
        "@media (min-width: 601px)": {
          "max-width": "100%",
          "margin-left": "0px",
          "margin-bottom": "0px"
        }
      }
    },
    "text": {
      "button": "Add to cart"
    }
  },
  "option": {},
  "cart": {
    "text": {
      "total": "Subtotal",
      "button": "Checkout"
    },
    "contents": {
      "note": true
    }
  },
  "toggle": {}
},
      });
    });
  }
})();
/*]]>*/
</script>

補足と留意点

追加したコードの意図は以下のとおりで、単に本来のボタンをカートパーマリンクに置き換えているだけです。

  • templates内の要素として、新たにmyButtonを作成
  • myButtonにはカートパーマリンクを設定したaタグを設置
  • contentsmyButtonを表示させ、本来のbuttonを消す

ただし、初期状態の購入ボタンはiframeの中に存在するため、aタグを書いただけでは正常に動きません。

そこでaタグにtarget="_top"を追加することでShopifyのチャックアウト画面へ移動させています。

留意点

  • カートパーマリンクの値が直書きなので、個数やバリエーションの変更や、ユーザーが入力するテキストや日付を反映可能にする必要がある
  • target="_top"で無理矢理対応している箇所は本来の動作ではないので、可能なら本来の動作の流れで実行できるようにした方がよさそう

現状では上記のような状態なので、実用に足るものではなく色々と手直しする必要があります。

参考

結び

おそらく他の誰かが思いついていそうな方法なので、探せばちゃんとしたサンプルが見つかるかもしれません。

0人がこの記事を評価

役に立ったよという方は上の「記事を評価する」ボタンをクリックしてもらえると嬉しいです。

連投防止のためにCookie使用。SNSへの投稿など他サービスとの連動は一切ありません。

コメント欄