From be29df744f1dd3253ef102b968aad248450ab437 Mon Sep 17 00:00:00 2001 From: Daniel da Silva Date: Tue, 17 Sep 2024 12:42:02 +0100 Subject: [PATCH 1/2] Add cookie banner to be gdpr compliant --- gatsby-config.mjs | 13 ++++- package.json | 1 + src/components/cookie-banner.tsx | 88 ++++++++++++++++++++++++++++++++ src/components/page-layout.tsx | 2 + yarn.lock | 14 +++++ 5 files changed, 116 insertions(+), 2 deletions(-) create mode 100644 src/components/cookie-banner.tsx diff --git a/gatsby-config.mjs b/gatsby-config.mjs index c51ffffd2..a0d3ce9cf 100644 --- a/gatsby-config.mjs +++ b/gatsby-config.mjs @@ -28,10 +28,19 @@ const config = { // https://gatsby.dev/graphql-typegen graphqlTypegen: true, plugins: [ + // { + // resolve: 'gatsby-plugin-google-tagmanager', + // options: { + // id: 'GTM-5NPWQ998' + // } + // }, { - resolve: 'gatsby-plugin-google-tagmanager', + resolve: `gatsby-plugin-gdpr-cookies`, options: { - id: 'GTM-5NPWQ998' + environments: ['production', 'development'], + googleTagManager: { + trackingId: 'GTM-5NPWQ998' + } } }, 'gatsby-plugin-image', diff --git a/package.json b/package.json index 919438f58..2f0d14313 100644 --- a/package.json +++ b/package.json @@ -46,6 +46,7 @@ "framer-motion": "^10.18.0", "gatsby": "^5.13.3", "gatsby-plugin-alias-imports": "^1.0.5", + "gatsby-plugin-gdpr-cookies": "^2.0.9", "gatsby-plugin-google-gtag": "^5.13.1", "gatsby-plugin-google-tagmanager": "^5.13.1", "gatsby-plugin-image": "^3.13.1", diff --git a/src/components/cookie-banner.tsx b/src/components/cookie-banner.tsx new file mode 100644 index 000000000..8f9adac0f --- /dev/null +++ b/src/components/cookie-banner.tsx @@ -0,0 +1,88 @@ +import React, { useEffect, useState } from 'react'; +import { useLocation } from '@reach/router'; +import { + Button, + ButtonGroup, + Modal, + ModalBody, + ModalContent, + ModalFooter, + ModalOverlay, + Text +} from '@chakra-ui/react'; +import { initializeAndTrack } from 'gatsby-plugin-gdpr-cookies'; + +const K_NAME = 'gatsby-gdpr-google-tagmanager'; + +function setCookie(cname: string, cvalue: string, exdays: number) { + const d = new Date(); + d.setTime(d.getTime() + exdays * 24 * 60 * 60 * 1000); + const expires = 'expires=' + d.toUTCString(); + document.cookie = cname + '=' + cvalue + ';' + expires + ';path=/'; +} + +function getCookie(cname: string) { + const name = cname + '='; + const decodedCookie = decodeURIComponent(document.cookie); + const ca = decodedCookie.split(';'); + for (let i = 0; i < ca.length; i++) { + let c = ca[i]; + while (c.charAt(0) == ' ') { + c = c.substring(1); + } + if (c.indexOf(name) == 0) { + return c.substring(name.length, c.length); + } + } + return ''; +} + +export default function CookieBanner() { + const [, render] = useState(0); + const cookie = getCookie(K_NAME); + + const location = useLocation(); + + useEffect(() => { + if (cookie === 'true') { + // Initialize the analytics + initializeAndTrack(location); + } + }, [cookie, location]); + + return ( + {}} size='xl'> + + + + + This website uses cookies for analytics purposes. The data is + anonymized and cannot be used to identify you. + + + + + + + + + + + + ); +} diff --git a/src/components/page-layout.tsx b/src/components/page-layout.tsx index 0342a72a4..07b050c1d 100644 --- a/src/components/page-layout.tsx +++ b/src/components/page-layout.tsx @@ -7,6 +7,7 @@ import PageHeader from './page-header'; import PageFooter from './page-footer'; import SponsorsFold from './sponsors-fold'; import { Newsletter } from './newsletter'; +import CookieBanner from './cookie-banner'; export default function PageLayout(props: { children: React.ReactNode; @@ -20,6 +21,7 @@ export default function PageLayout(props: { }, []); return ( + diff --git a/yarn.lock b/yarn.lock index 45d8165e6..3e43d0183 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1337,6 +1337,13 @@ dependencies: regenerator-runtime "^0.14.0" +"@babel/runtime@^7.11.2": + version "7.25.6" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.25.6.tgz#9afc3289f7184d8d7f98b099884c26317b9264d2" + integrity sha512-VBj9MYyDb9tuLq7yzqjgzt6Q+IBQLrGZfdjOekyEirZPHxXWoTSGUTMrpsfi58Up73d13NfYLv8HT9vmznjzhQ== + dependencies: + regenerator-runtime "^0.14.0" + "@babel/runtime@^7.12.13", "@babel/runtime@^7.16.3", "@babel/runtime@^7.2.0": version "7.23.2" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.23.2.tgz#062b0ac103261d68a966c4c7baf2ae3e62ec3885" @@ -7691,6 +7698,13 @@ gatsby-plugin-alias-imports@^1.0.5: dependencies: "@babel/runtime" "^7.2.0" +gatsby-plugin-gdpr-cookies@^2.0.9: + version "2.0.9" + resolved "https://registry.yarnpkg.com/gatsby-plugin-gdpr-cookies/-/gatsby-plugin-gdpr-cookies-2.0.9.tgz#fd3bb2a73c35b52336e9e3ddeedc8380f504e6d5" + integrity sha512-rU4O5oJ+ace0B6D4CG6dG5oOLYRQT3LEb+I5XjCieYVkk1KB0QgqhzsgkV8K6JO18EOExE0Y4HyHQHj3hF6uGg== + dependencies: + "@babel/runtime" "^7.11.2" + gatsby-plugin-google-gtag@^5.13.1: version "5.13.1" resolved "https://registry.yarnpkg.com/gatsby-plugin-google-gtag/-/gatsby-plugin-google-gtag-5.13.1.tgz#81b294f2ab12dad5ba5e9946e4b78cd315676bbc" From 1c2f2accdb78afe31f699ae4faa26186743e70e3 Mon Sep 17 00:00:00 2001 From: Daniel da Silva Date: Tue, 17 Sep 2024 15:34:41 +0100 Subject: [PATCH 2/2] Fix server side rendering --- src/components/cookie-banner.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/components/cookie-banner.tsx b/src/components/cookie-banner.tsx index 8f9adac0f..9fac66c0c 100644 --- a/src/components/cookie-banner.tsx +++ b/src/components/cookie-banner.tsx @@ -22,6 +22,8 @@ function setCookie(cname: string, cvalue: string, exdays: number) { } function getCookie(cname: string) { + if (typeof window === 'undefined') return ''; + const name = cname + '='; const decodedCookie = decodeURIComponent(document.cookie); const ca = decodedCookie.split(';');