見出し画像

[Shopify]ローカルストレージを使って「最近閲覧した商品履歴」を表示する・セクションテンプレート #127

こんにちは。Shopify専門エンジニアのまりん(@crowd37cord)です。

今日はローカルストレージで最近閲覧した商品を保存して表示する方法についてご紹介。今回はデザインはシンプルに、8件まで閲覧履歴を表示するという仕様で作成しています。

カスタマイズ画面でのレイアウト調整版は次回出そうかと思っています。あと、色んなデザインパターンも今度紹介予定です^^

ベーステーマ:Dawn
※どのテーマでも機能のところは使えると思います。テーマやバージョンによってはレイアウトは調整必要。

✔️今回のゴール

閲覧履歴0件の時は非表示。タイトル部分も表示されません。

・表示件数:8件
・PC:4つずつ
・SP:2つずつ
※今回はカスタマイズ画面で調整はできません。



🔸CMSの特徴

アンカータグ用
見出し
余白


✔️ローカルストレージに格納するコード

下記を設置するだけでOK.

{% comment %}latest checked products
{% render 'product-localstrage' %}
{% endcomment %}
<script>
(function() {
    // エスケープ処理を行う関数
    function escapeHtml(text) {
        return text
            .replace(/&/g, "&amp;")
            .replace(/</g, "&lt;")
            .replace(/>/g, "&lt;")
            .replace(/"/g, "&quot;")
            .replace(/'/g, "&#039;");
    }

    // 数値を3桁ごとにカンマ区切りでフォーマットする関数
    function formatPrice(price) {
        return price.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
    }

    // 閲覧した商品の情報をローカルストレージに保存する関数
    function saveRecentlyViewedProduct(product) {
        try {
            product.title = escapeHtml(product.title);

            let viewedProducts = JSON.parse(localStorage.getItem('recentlyViewedProducts')) || [];
            
            // すでに含まれている場合は削除
            viewedProducts = viewedProducts.filter(p => p.id !== product.id);
            

            // 新しい商品情報を先頭に追加
            viewedProducts.unshift(product);

            // 最大保存数
            if (viewedProducts.length > 8) {
                viewedProducts.pop();
            }

            localStorage.setItem('recentlyViewedProducts', JSON.stringify(viewedProducts));
           
        } catch (error) {
            console.error('Error saving product to local storage:', error);
        }
    }

    // ページロード時に現在の商品の情報を保存
    document.addEventListener('DOMContentLoaded', function () {
        try {
            
            const currentProduct = {
                id: {{ product.id }},
                title: "{{ product.title | escape }}",
                handle: "{{ product.handle }}",
                url: "{{ product.url }}",
                price: "{{ product.price | money_with_currency }}",
                image: "{{ shop.url }}/cdn/shop/{{ product.featured_image | image_url: 'master' }}",
                variants: [
                    {% for variant in product.variants %}
                    {
                        id: "{{ variant.id }}",
                        title: "{{ variant.title }}",
                        price: "{{ variant.price | money_with_currency }}"
                    }
                    {% if forloop.last == false %},{% endif %}
                    {% endfor %}
                ]
            };
            console.log('Current product:', currentProduct);
            saveRecentlyViewedProduct(currentProduct);
        } catch (error) {
            console.error('Error retrieving current product data:', error);
        }
    });
})();
</script>

ローカルストレージに格納されます。

上記を少し解説すると、、、

📌商品情報をローカルストレージに保存する関数

function saveRecentlyViewedProduct(product) {
    try {
        product.title = escapeHtml(product.title);

        let viewedProducts = JSON.parse(localStorage.getItem('recentlyViewedProducts')) || [];
        
        // すでに含まれている場合は削除
        viewedProducts = viewedProducts.filter(p => p.id !== product.id);
        
        // 新しい商品情報を先頭に追加
        viewedProducts.unshift(product);

        // 最大保存数
        if (viewedProducts.length > 8) {
            viewedProducts.pop();
        }

        localStorage.setItem('recentlyViewedProducts', JSON.stringify(viewedProducts));
       
    } catch (error) {
        console.error('Error saving product to local storage:', error);
    }
}
  • escapeHtml関数を使って商品タイトルをエスケープ。

  • 既に保存されている商品情報を取得し、現在の商品が含まれていれば削除。

  • 新しい商品情報をリストの先頭に追加。

  • 保存する商品の最大数を8に制限し、超過分を削除。

  • 更新されたリストをローカルストレージに保存。

📌ページロード時の処理

document.addEventListener('DOMContentLoaded', function () {
    try {
        const currentProduct = {
            id: {{ product.id }},
            title: "{{ product.title | escape }}",
            handle: "{{ product.handle }}",
            url: "{{ product.url }}",
            price: "{{ product.price | money_with_currency }}",
            image: "{{ shop.url }}/cdn/shop/{{ product.featured_image | image_url: 'master' }}",
            variants: [
                {% for variant in product.variants %}
                {
                    id: "{{ variant.id }}",
                    title: "{{ variant.title }}",
                    price: "{{ variant.price | money_with_currency }}"
                }
                {% if forloop.last == false %},{% endif %}
                {% endfor %}
            ]
        };
        console.log('Current product:', currentProduct);
        saveRecentlyViewedProduct(currentProduct);
    } catch (error) {
        console.error('Error retrieving current product data:', error);
    }
});
  • 現在表示されている商品の情報を取得し、currentProductオブジェクトを作成。

  • saveRecentlyViewedProduct関数を呼び出して、currentProductをローカルストレージに保存。


これをスニペットに書いて、商品ページに置いておくだけ🎵
ぜひ試してみてね。

【ご購入時のご注意】
※返金&サポート&コメント返信はしておりません。
※現時点の最新のDawnテーマをベースに作成してます。
※コード&設置方法のみのご紹介で解説などはしておりません。
※2024.6時点のコードです。メンテナンスは今後する予定はありません。
※環境やバージョンによりレイアウト崩れることもありますので適当にCSSで調整していただければと思います。(メンバーシップでコメント頂いた場合は修正します)

✔️設定手順

簡単な下記のレイアウトでCMSもシンプルなものでセクションテンプレ作ったので載せておきます。

ここから先は

7,574字 / 5画像
この記事のみ ¥ 1,500
期間限定 PayPay支払いすると抽選でお得に!

この記事が気に入ったらサポートをしてみませんか?