Shopify Liquidで会員登録後に会員登録完了ページに遷移させる

## 今回の目的

今回はLiquidで会員登録完了時に会員登録完了ページに遷移させるようにしたいと思います。
この問題は自分もどうしたら良いかわからずかなり悩んだところです。
あまり参考になるような記事がないのと、参考になるようなものを見つけてそれ通りに実践しても思うように動いていなかったのが原因です。


## Shopifyの会員登録の仕様

他のテーマではどのようになっているか知りませんがDebutテーマでは、会員登録(/account/register)を行うとカートに商品がない場合は、トップページに飛び、
商品がある場合は、チェックアウトページに飛びます。
これだと会員登録されたかどうかがぱっと見わかりづらいです。そこで会員登録後に会員登録完了ページ(/pages/register_completed)に飛ばすにはどうしたら良いか考えました。
ちなみに会員登録完了ページはShopifyのページ機能を利用して作成しております。

## 会員登録完了ページにリダイレクトさせるには？

正解にたどり着くまでいろんな方法を試しました。

**1.ログインのリダイレクト方法と同じものを使う**

shopifyのtutorialでログイン後は遷移先を変更できるという記事(https://shopify.dev/tutorials/customize-theme-redirect-customers-when-they-log-in)

を見たので会員登録でも同じようにやればうまくいくのでは？と思い、まずはこれを試しました。

```
 {% form 'create_customer', id: formId, novalidate: 'novalidate' %}
  <input type="hidden" name="register_url" value="/pages/register_completed" />
```

残念ながらこの方法では**何も変わらずトップ画面に飛ばされてしまいました**、、><
ログインフォームにおいては、このinputタグを入れていると、その指定先にリダイレクトしてくれる仕様があるらしいのですが、他の画面にはその仕様がないらしいです。他でもつけてくれたらいいのにと思ってしまいます。
これがどういう仕組みで動いているか分かる人は教えていただきたいです。

**2. 「form.posted_successfully？」を使ってみる　**

[shopifyの開発者ドキュメント](https://shopify.dev/docs/themes/liquid/reference/objects/form#form-posted_successfully)をみると**form.posted_successfully？**という明らかに使えそうでは？と思えるオブジェクトがありました。

```
{% form ..%}
..
{% if form.posted_successfully? %}
 <script>location.href = '/pages/register_completed';</script>
{% endif %}
{% endform %}
```

これでいけるやろ！と思いましたが**残念ながらこの方法でもトップに飛ばされてしまいました**、、><><
じゃあこのオブジェクトどこで使えるの？という話ですが、お問い合わせフォームでは使えます。
お問い合わせ内容を入力してお問い合わせ完了ページに遷移させたい時は上のコードにやればうまくいくみたいです。
正直その辺の仕組みは謎です🤔

ここのブログでもお問い合わせ完了ページにリダイレクトする方法が紹介されております。https://note.com/osamuiwasaki/n/ne3e3e2038c7d

 **3. jsの利用**

1,2がダメだったのでどうしようと思い、「shopify register redirect liquid」で検索してみると海外の記事がたくさん出てきました。やはり海外の方が参考記事の量が違いますね。

この辺の記事が特に参考になりました。

https://community.shopify.com/c/Shopify-Design/Redirect-after-customer-registration/td-p/293044/page/3
https://heliumdev.com/blog/shopify-redirect-after-registration/

これらで紹介されているコードを
**theme.liquidのbodyタグの直下に置きます**
RECAPTURE(challengeページ)を使う場合は上のコード、RECAPTUREを取り除いた場合は下のコードが良いかと思います
shopify plusの場合は、管理画面のライブチャットから申請すれば、RECAPTURE画面を外してもらうことができます。plus以外はわかりません。

```
 {{ '//ajax.googleapis.com/ajax/libs/jquery/2.2.3/jquery.min.js' | script_tag }}
<!-- Handle registration redirect -->
<script>
  $(document).ready(function(){
    var $returnTo = $('<input type="hidden" name="return_to" value="/pages/register_completed" />');

    if ($('#create_customer').length > 0){ //if registration form
      $returnTo.insertBefore($('#create_customer input[type="submit"]')); // add return_to input
    } else if ($('#g-recaptcha').length){ //if captcha form
       $returnTo.insertBefore($('.shopify-challenge__container input[type="submit"]'));
    }
  });
</script> 
</body>
```

```
 {{ '//ajax.googleapis.com/ajax/libs/jquery/2.2.3/jquery.min.js' | script_tag }}
<script>
  (function() {
    var REDIRECT_PATH = '/pages/register_completed';

    var selector = '#create_customer, form[action$="/account"][method="post"]',
        $form = document.querySelectorAll(selector)[0];

    if ($form) {
      $redirect = document.createElement('input');
      $redirect.setAttribute('name', 'return_to');
      $redirect.setAttribute('type', 'hidden');
      $redirect.value = REDIRECT_PATH;
      $form.appendChild($redirect);
    }
  })();
</script>
</body>
```

これで一応登録後登録完了ページにリダイレクトされます。👏

ただ、これで終わり。ではありません。。このコードを入れることによって、本来エラーが出る状況(登録情報を入力していない、一度登録したメアドで再登録する)でも登録完了ページに
飛んでしまいます。これでは使えません。

なのでエラーが出るようにしなければなりません。

## エラーがある場合会員登録ページに戻すには

こちらもjsとliquidを使用して対応します。

```
{% unless customer %}

<script>
  location.href = '/account/register';
  localStorage.setItem('register_failed', true);
</script>
{% endunless %}

```

会員登録完了ページに使用しているtemplatesファイルはここでは**page.liquid**とします。
**page.liquid**の下にログインしていない時は**{% unless customer %}**で囲み、jsで会員登録画面に戻るようにし、ローカルストレージにエラーを出すフラグとして、
setItemでデータを保存します。

これでログイン時以外は会員登録画面に戻ります。

最後に会員登録画面に戻った時エラーを出すようにします。

この場合、debutのデフォルトのエラー表示はうまく働かないみたいなのですごく簡単にエラー文を作成します。

```
 <div class="error text-center error-hide">
    <p>会員登録エラー</p>
  </div>
</div>

<script>
   $(document).ready(function() {
  if (localStorage.getItem('register_failed') === 'true') {
    $('.error').removeClass('error-hide');
    localStorage.removeItem('register_failed');
  };
   });
</script>
```
**register.liquid**に上のコードを書きます。
**error-hide**クラスにはdisplay:none;が入っております。
会員登録完了ページから会員登録ページに戻る時につけたフラグをみて、error-hideクラスとローカルストレージのデータを削除します。

これでエラーない時は会員登録完了画面へ、エラーがある場合は会員登録ページに戻り、エラーも出せるようになります！

登録成功時
![スクリーンショット 2020-11-27 0.21.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435480/c444fc9d-8acc-03ba-d65a-7e497ac63b1f.png)

登録失敗時
![スクリーンショット 2020-11-27 0.27.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435480/a2607f09-bea4-6fcb-b78d-f060e9196558.png)


## まとめ

Shopifyではテーマ作成していると、意外と簡単にできるだろうと思っていたところで詰まったりします。
今は会員登録完了画面に遷移するのに結構手間がかかりますが、将来的にはもっと楽にできるようになって欲しいですね。

何かしらこうした方がもっと良いとか指摘ありましたらどんどんコメント送ってください。お待ちしております。