WordPressでCookie同意ダイアログを出す

ダイアログにOKボタンがあるだけのシンプルなやつ。

Cookie同意ダイアログはプラグインも色々とあるが、設定がややこしかったりスタイルが思い通りに調整できないので自作。

ちなみに厳密にやろうとすると国別に出しわけたりとかCookieを拒否された場合の挙動なども作りこむ必要があり、割と奥が深い。
やたら高機能なプラグインがあるのもそのためである。

footer.php

ChatGPTさんに書いてもらったやつを少し手直し。
constでなくvarを使うChatGPTさん。

WordPressなのでfooter.phpに追加するがHTMLに貼り付けても使える。
ので単にテーマの設定でウィジェットとして追加してもいい。

<style>
.cookie-notice-container {
  position: fixed;
  bottom: -420px;
  width: 100%;
  z-index: 1000;
  transition: bottom 0.5s ease-out;
  filter: drop-shadow(-4px 4px 8px rgba(0,0,0,0.14));
}

.cookie-notice {
  margin: 0 auto;
  padding: 16px 32px;
  max-width: 800px;
  text-align: center;
  border: 1px solid #999;
  border-radius: 2px;
  background-color: #fefefe;
}

.cookie-notice-text {
  color: #333;
  line-height: 1.8em;
  font-weight: 500;
  text-align: left;
}

.cookie-notice-accept-button {
  width: 200px;
  margin: 8px auto;
  padding: 8px 16px;
  color: #666;
  font-weight: bold;
  border: 1px solid #666;
  border-radius: 2px;
}
</style>

<!-- Cookie同意ダイアログ -->
<div id="cookie-notice" class="cookie-notice-container">
  <div class="cookie-notice">
    <p class="cookie-notice-text">
      ウチはCookie使ってるぜ。詳しくは<a href="/privacy.html">プライバシーポリシー</a>を見てくれよな!
    </p>
    <button id="cookie-notice-accept-button" class="cookie-notice-accept-button">OK</button>
  </div>
</div>

<script>
  // Cookieがセットされていない場合はダイアログを表示する
  const acceptCookieName = "site_cookie_accepted";
  document.addEventListener("DOMContentLoaded", function() {
    function getCookie(name) {
      const match = document.cookie.match(new RegExp('(^| )' + name + '=([^;]+)'));
      if (match) return match[2];
    }

    // クライアントサイドのCookieかサーバーサイドのCookieのどちらかがセットされていればダイアログは表示しない
    if (!getCookie(acceptCookieName)) {
      document.getElementById('cookie-notice').style.bottom = '0px';
    }
  });

// OKボタンを押したとき、Cookieをセットしてダイアログを閉じる
  document.getElementById('cookie-notice-accept-button').addEventListener('click', function() {
    // 有効期限はサーバーサイドであらためてセットするのでここでは不要
    document.cookie = acceptCookieName + '=true; path=/';

    document.getElementById('cookie-notice').style.bottom = '-420px';
  });
</script>

funcitons.php

JavaScriptで発行したCookieはiPhoneのSafariでは有効期限に関わらず1日しか持たない。
のでサーバー側で発行しなおす。

HTTPヘッダーを使うので何かを描画する前に実行する必要があるということで、get_headerアクションにフックさせている。

add_action('get_header', function(){
  if (isset($_COOKIE['site_cookie_accepted'])) {
    setcookie('site_cookie_accepted', 'true', time() + 86400*365, '/');
  }
});

参考: CookieやITPについての整理 https://zenn.dev/lclco/articles/39c74a74274e08

これをやらないとiPhoneだと毎日ダイアログが出る。そういうことまではChatGPTさんはなかなか教えてくれない。