【Dawnテーマ】Shopify ポップアップを作ろう〜ニュースレター登録

こんにちは、ムネトです。

悩む人
ストアオーナー

ストアにニュースレター登録のポップアップを作りたいんだけど・・・

といった疑問に、お答えします。

テーマによってはポップアップ機能が最初から実装されているものもありますが、Dawnにはポップアップ機能がないので、実装して追加します。
今回はニュースレターの登録を促すポップアップ表示にしようと思います。

機能要件

  • TOPページに表示
  • TOPページが表示された後、3秒後にポップアップが出現する
  • アカウントを持っていない場合のみポップアップを表示
  • 表示する内容は、既存のニュースレターのセクション「newsletter.liquid」を活用する
  • sessionStorageを利用し、一定時間ストアに滞在中は再表示されない

今回作成するレイアウトはこんなイメージ↓

ポップアップのイメージ 背景黒

では、早速コード編集していきましょう!
テーマは必ず複製してから編集してくださいね〜

ポップアップ表示のコード追加

今回はテーマ:Dawn
バージョン10.0.0を利用します。

コードを編集を開き、新しいセクションを追加します。
セクション名は任意ですが、今回「popup-newsletter.liquid」と名付けました。

新規作成したセクションに下記のコードをコピーします。

{{ 'component-newsletter.css' | asset_url | stylesheet_tag }}
{{ 'newsletter-section.css' | asset_url | stylesheet_tag }}

{%- style -%}
  .section-{{ section.id }}-padding {
    padding-top: {{ section.settings.padding_top | times: 0.75 | round: 0 }}px;
    padding-bottom: {{ section.settings.padding_bottom | times: 0.75 | round: 0 }}px;
  }

  @media screen and (min-width: 750px) {
    .section-{{ section.id }}-padding {
      padding-top: {{ section.settings.padding_top }}px;
      padding-bottom: {{ section.settings.padding_bottom }}px;
    }
  }
{%- endstyle -%}
{% unless customer %}
<div class="bg_custom_popup">
  <div class="custom_popup">
    <span class="custom_popup_title_close"></span>
    <div class="newsletter center {% if section.settings.full_width == false %}newsletter--narrow page-width{% endif %}">  
      <div class="newsletter__wrapper color-{{ section.settings.color_scheme }} gradient content-container isolate{% if section.settings.full_width %} content-container--full-width{% endif %} section-{{ section.id }}-padding">
        {%- for block in section.blocks -%}
          {%- case block.type -%}
            {%- when 'heading' -%}
              <h2
                class="inline-richtext {{ block.settings.heading_size }}{% if settings.animations_reveal_on_scroll %} scroll-trigger animate--slide-in{% endif %}"
                {{ block.shopify_attributes }}
                {% if settings.animations_reveal_on_scroll %}
                  data-cascade
                  style="--animation-order: {{ forloop.index }};"
                {% endif %}
              >
                {{ block.settings.heading }}
              </h2>
            {%- when 'paragraph' -%}
              <div
                class="newsletter__subheading rte{% if settings.animations_reveal_on_scroll %} scroll-trigger animate--slide-in{% endif %}"
                {{ block.shopify_attributes }}
                {% if settings.animations_reveal_on_scroll %}
                  data-cascade
                  style="--animation-order: {{ forloop.index }};"
                {% endif %}
              >
                {{ block.settings.text }}
              </div>
            {%- when 'email_form' -%}
              <div {{ block.shopify_attributes }}>
                {% form 'customer', class: 'newsletter-form' %}
                  <input type="hidden" name="contact[tags]" value="newsletter">
                  <div
                    class="newsletter-form__field-wrapper{% if settings.animations_reveal_on_scroll %} scroll-trigger animate--slide-in{% endif %}"
                    {% if settings.animations_reveal_on_scroll %}
                      data-cascade
                      style="--animation-order: {{ forloop.index }};"
                    {% endif %}
                  >
                    <div class="field">
                      <input
                        id="NewsletterForm--{{ section.id }}"
                        type="email"
                        name="contact[email]"
                        class="field__input"
                        value="{{ form.email }}"
                        aria-required="true"
                        autocorrect="off"
                        autocapitalize="off"
                        autocomplete="email"
                        {% if form.errors %}
                          autofocus
                          aria-invalid="true"
                          aria-describedby="Newsletter-error--{{ section.id }}"
                        {% elsif form.posted_successfully? %}
                          aria-describedby="Newsletter-success--{{ section.id }}"
                        {% endif %}
                        placeholder="{{ 'newsletter.label' | t }}"
                        required
                      >
                      <label class="field__label" for="NewsletterForm--{{ section.id }}">
                        {{ 'newsletter.label' | t }}
                      </label>
                      <button
                        type="submit"
                        class="newsletter-form__button field__button"
                        name="commit"
                        id="Subscribe"
                        aria-label="{{ 'newsletter.button_label' | t }}"
                      >
                        {% render 'icon-arrow' %}
                      </button>
                    </div>
                    {%- if form.errors -%}
                      <small class="newsletter-form__message form__message" id="Newsletter-error--{{ section.id }}">
                        {%- render 'icon-error' -%}
                        {{- form.errors.translated_fields.email | capitalize }}
                        {{ form.errors.messages.email -}}
                      </small>
                    {%- endif -%}
                  </div>
                  {%- if form.posted_successfully? -%}
                    <h3
                      class="newsletter-form__message newsletter-form__message--success form__message"
                      id="Newsletter-success--{{ section.id }}"
                      tabindex="-1"
                      autofocus
                    >
                      {% render 'icon-success' -%}
                      {{- 'newsletter.success' | t }}
                    </h3>
                  {%- endif -%}
                {% endform %}
              </div>
          {%- endcase -%}
        {%- endfor -%}
      </div>
    </div>
  </div>
</div>
{% endunless %}

上記がポップアップを表示する部分のコードです。

ニュースレター以外の表示を行いたい場合には

<div class="newsletter center {% if section.settings.full_width == false %}newsletter--narrow page-width{% endif %}">
</div>

上記のコードの中身を任意で書き換えてください。

アカウント所持の判定

アカウント(会員登録)を持っていない場合という記述

{% unless customer %}
{% endunless %}

ポップアップの表示を制御

以下はポップアップの表示をするためのコードです。

<script>
window.addEventListener('load', function() {
  setTimeout(function() {
    if (!sessionStorage.getItem('disp_popup')) {
      sessionStorage.setItem('disp_popup', 'on');
      const body = document.querySelector('body');
      const bgPopup = document.querySelector('.bg_custom_popup');
      const popup = document.querySelector('.custom_popup');
      const popupTitleClose = document.querySelector('.custom_popup_title_close');

      bgPopup.addEventListener('click', function() {
        closePopup();
      });
      popup.addEventListener('click', function(e) {
        e.stopPropagation();
      });
      popupTitleClose.addEventListener('click', function() {
        closePopup();
      });

      function closePopup() {
        body.classList.remove('open_popup');
      }

      body.classList.add('open_popup');
    }
  }, 3000);
}, false);
</script>

最初の機能要件でお伝えした通り、sessionStorageを利用し該当のページ(今回はTOPページを想定)が表示された3秒後にポップアップを出現させます。

schemeの追加

schemeを追加します。
内容は「newsletter.liquid」で使っているものとほぼ同じ中身です。

{% schema %}
{
  "name": "ポップアップ",
  "tag": "section",
  "class": "section",
  "disabled_on": {
    "groups": ["header"]
  },
  "settings": [
    {
      "type": "color_scheme",
      "id": "color_scheme",
      "label": "t:sections.all.colors.label",
      "default": "background-1"
    },
    {
      "type": "checkbox",
      "id": "full_width",
      "default": true,
      "label": "t:sections.newsletter.settings.full_width.label"
    },
    {
      "type": "paragraph",
      "content": "t:sections.newsletter.settings.paragraph.content"
    },
    {
      "type": "header",
      "content": "t:sections.all.padding.section_padding_heading"
    },
    {
      "type": "range",
      "id": "padding_top",
      "min": 0,
      "max": 100,
      "step": 4,
      "unit": "px",
      "label": "t:sections.all.padding.padding_top",
      "default": 40
    },
    {
      "type": "range",
      "id": "padding_bottom",
      "min": 0,
      "max": 100,
      "step": 4,
      "unit": "px",
      "label": "t:sections.all.padding.padding_bottom",
      "default": 52
    }
  ],
  "blocks": [
    {
      "type": "heading",
      "name": "t:sections.newsletter.blocks.heading.name",
      "limit": 1,
      "settings": [
        {
          "type": "inline_richtext",
          "id": "heading",
          "default": "Subscribe to our emails",
          "label": "t:sections.newsletter.blocks.heading.settings.heading.label"
        },
        {
          "type": "select",
          "id": "heading_size",
          "options": [
            {
              "value": "h2",
              "label": "t:sections.all.heading_size.options__1.label"
            },
            {
              "value": "h1",
              "label": "t:sections.all.heading_size.options__2.label"
            },
            {
              "value": "h0",
              "label": "t:sections.all.heading_size.options__3.label"
            }
          ],
          "default": "h1",
          "label": "t:sections.all.heading_size.label"
        }
      ]
    },
    {
      "type": "paragraph",
      "name": "t:sections.newsletter.blocks.paragraph.name",
      "limit": 1,
      "settings": [
        {
          "type": "richtext",
          "id": "text",
          "default": "<p>Be the first to know about new collections and exclusive offers.</p>",
          "label": "t:sections.newsletter.blocks.paragraph.settings.paragraph.label"
        }
      ]
    },
    {
      "type": "email_form",
      "name": "t:sections.newsletter.blocks.email_form.name",
      "limit": 1
    }
  ],
  "presets": [
    {
      "name": "ポップアップ",
      "blocks": [
        {
          "type": "heading"
        },
        {
          "type": "paragraph"
        },
        {
          "type": "email_form"
        }
      ]
    }
  ]
}
{% endschema %}

styleの追加

最後にスタイルを追加します。
ニュースレターを表示している部分のスタイルは

{{ 'component-newsletter.css' | asset_url | stylesheet_tag }}
{{ 'newsletter-section.css' | asset_url | stylesheet_tag }}

アセットに格納されています。
今回この部分には手を加えません。

popup-newsletter.liquidにスタイルを追加

{% style %}
body.open_popup {
    overflow: hidden;
}

.bg_custom_popup {
    position: fixed;
    top: 0px;
    left: 0px;
    z-index: 9999;
    width: 100vw;
    height: 100vh;
    background-color: rgba(0, 0, 0, 0.5);
    opacity: 0;
    visibility: hidden;
    transition: 0.5s;
}

body.open_popup .bg_custom_popup {
    opacity: 1;
    visibility: visible;
}

.custom_popup {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translateX(-50%) translateY(-50%);
    width: 50vw;
    min-width: 200px;
    background-color: #fff;
}

.custom_popup_title_close {
    position: absolute;
    top: 5%;
    right: 20px;
    width: 20px;
    height: 20px;
    transform: translateY(0%);
    cursor: pointer;
   z-index: 999;
}
  
.custom_popup_title_close::before,
.custom_popup_title_close::after {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translateX(-50%) translateY(-50%);
    width: 100%;
    height: 1px;
    background-color: #333;
    content: "";
}
.custom_popup_title_close::before {
    transform: translateX(-50%) translateY(-50%) rotate(45deg);
}
.custom_popup_title_close::after {
    transform: translateX(-50%) translateY(-50%) rotate(-45deg);
}

@media screen and (max-width: 480px){
  .custom_popup {
    width: 80vw;
    min-width: 200px;
  }
  .custom_popup_title {
    font-size: 16px;
  }
  .custom_popup_content p {
    font-size: 13px;
  }
  .custom_popup_fields input{
    font-size: 12px;
  }
}
{% endstyle %}

スタイル部分の解説は省きます。
中身は必要に応じて修正してください。

カスタマイズでセクションを追加

ストアのカスタマイズからTOPページを開き、今回作成したセクション「ポップアップ」を追加します。


これにて設定は完了です。
お疲れさまでした。

まとめ

shopifyテーマDawnにて、ニュースレター登録のポップアップセクションを作成しました。

最後までお付き合いいただき、ありがとうございました。
この記事が少しでも参考になれば幸いです。