Add configuration for admins to determine whether to show cookie banner (#20517)
* Cookie banner admin config (wip) * GA4 consent mode based on cookie acceptance * Fix i18n * Merge upstream * Adjust heading
This commit is contained in:
parent
539844165f
commit
ae2371d9a4
7 changed files with 95 additions and 13 deletions
|
|
@ -1,4 +1,5 @@
|
|||
/*eslint-disable prefer-rest-params*/
|
||||
/* global isTouchDevice */
|
||||
|
||||
function initializeBaseTracking() {
|
||||
showCookieConsentBanner();
|
||||
|
|
@ -7,11 +8,12 @@ function initializeBaseTracking() {
|
|||
trackCustomImpressions();
|
||||
}
|
||||
|
||||
// Google Anlytics 3 is deprecated, and mostly not supported, but some sites may still be using it for now.
|
||||
function trackGoogleAnalytics3() {
|
||||
let wait = 0;
|
||||
let addedGA = false;
|
||||
const gaTrackingCode = document.body.dataset.gaTracking;
|
||||
if (gaTrackingCode) {
|
||||
if (gaTrackingCode && localStorage.getItem('cookie_status') === 'allowed') {
|
||||
const waitingOnGA = setInterval(() => {
|
||||
if (!addedGA) {
|
||||
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
|
||||
|
|
@ -33,6 +35,8 @@ function trackGoogleAnalytics3() {
|
|||
}
|
||||
}, 25);
|
||||
eventListening();
|
||||
} else if (gaTrackingCode) {
|
||||
fallbackActivityRecording();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -60,9 +64,13 @@ function trackGoogleAnalytics4() {
|
|||
window['gtag'] = window['gtag'] || function () {
|
||||
window.dataLayer.push(arguments)
|
||||
}
|
||||
|
||||
const consent = localStorage.getItem('cookie_status') === 'allowed' ? 'granted' : 'denied';
|
||||
gtag('js', new Date());
|
||||
gtag('config', ga4MeasurementCode, { 'anonymize_ip': true });
|
||||
gtag('consent', 'default', {
|
||||
'ad_storage': consent,
|
||||
'analytics_storage': consent
|
||||
});
|
||||
clearInterval(waitingOnGA4);
|
||||
}
|
||||
if (wait > 85) {
|
||||
|
|
@ -181,7 +189,7 @@ function trackCustomImpressions() {
|
|||
|
||||
function showCookieConsentBanner() {
|
||||
// if current url includes ?cookietest=true
|
||||
if (window.location.href.includes('cookietest=true')) {
|
||||
if (shouldShowCookieBanner()) {
|
||||
// show modal with cookie consent
|
||||
const cookieDiv = document.getElementById('cookie-consent');
|
||||
|
||||
|
|
@ -190,7 +198,7 @@ function showCookieConsentBanner() {
|
|||
<div class="cookie-consent-modal">
|
||||
<div class="cookie-consent-modal__content">
|
||||
<p>
|
||||
<strong>Some content on our site requires cookies for personalization and analytics.</strong>
|
||||
<strong>Some content on our site requires cookies for personalization.</strong>
|
||||
</p>
|
||||
<p>
|
||||
Read our full <a href="/privacy">privacy policy</a> to learn more.
|
||||
|
|
@ -210,6 +218,12 @@ function showCookieConsentBanner() {
|
|||
document.getElementById('cookie-accept').onclick = (() => {
|
||||
localStorage.setItem('cookie_status', 'allowed');
|
||||
cookieDiv.style.display = 'none';
|
||||
if (window.gtag) {
|
||||
gtag('consent', 'update', {
|
||||
'ad_storage': 'granted',
|
||||
'analytics_storage': 'granted'
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
document.getElementById('cookie-dismiss').onclick = (() => {
|
||||
|
|
@ -220,6 +234,38 @@ function showCookieConsentBanner() {
|
|||
}
|
||||
}
|
||||
|
||||
function shouldShowCookieBanner() {
|
||||
const { userStatus, cookieBannerUserContext, cookieBannerPlatformContext } = document.body.dataset;
|
||||
function determineActualPlatformContext() {
|
||||
if (navigator.userAgent.includes('DEV-Native')) {
|
||||
return 'mobile_app'
|
||||
} else if (isTouchDevice()) {
|
||||
return 'mobile_web'
|
||||
}
|
||||
return 'desktop_web'
|
||||
}
|
||||
|
||||
// Determine the actual platform context
|
||||
const actualPlatformContext = determineActualPlatformContext();
|
||||
|
||||
// Check if either user or platform context is set to 'off'
|
||||
if (cookieBannerUserContext === 'off' || cookieBannerPlatformContext === 'off') {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check based on user status
|
||||
const showForUserContext = (userStatus === 'logged-in' && cookieBannerUserContext === 'all') ||
|
||||
(userStatus !== 'logged-in' && cookieBannerUserContext !== 'off');
|
||||
|
||||
// Check based on platform context
|
||||
const showForPlatformContext = (cookieBannerPlatformContext === 'all') ||
|
||||
(cookieBannerPlatformContext === 'all_web' && ['desktop_web', 'mobile_web'].includes(actualPlatformContext)) ||
|
||||
(cookieBannerPlatformContext === actualPlatformContext);
|
||||
|
||||
// Return true if both user context and platform context conditions are met
|
||||
return showForUserContext && showForPlatformContext;
|
||||
}
|
||||
|
||||
function trackPageView(dataBody, csrfToken) {
|
||||
window.fetch('/page_views', {
|
||||
method: 'POST',
|
||||
|
|
|
|||
|
|
@ -45,6 +45,14 @@ module Constants
|
|||
description: I18n.t("lib.constants.settings.general.ga_analytics_4.description"),
|
||||
placeholder: ""
|
||||
},
|
||||
cookie_banner_user_context: {
|
||||
description: I18n.t("lib.constants.settings.general.cookie_banner_user_context.description"),
|
||||
placeholder: "off"
|
||||
},
|
||||
coolie_banner_platform_context: {
|
||||
description: I18n.t("lib.constants.settings.general.coolie_banner_platform_context.description"),
|
||||
placeholder: "off"
|
||||
},
|
||||
health_check_token: {
|
||||
description: I18n.t("lib.constants.settings.general.health.description"),
|
||||
placeholder: I18n.t("lib.constants.settings.general.health.placeholder")
|
||||
|
|
|
|||
|
|
@ -1,5 +1,8 @@
|
|||
module Settings
|
||||
class General < Base
|
||||
BANNER_USER_CONFIGS = %w[off logged_out_only all].freeze
|
||||
BANNER_PLATFORM_CONFIGS = %w[off all all_web desktop_web mobile_web mobile_app].freeze
|
||||
|
||||
self.table_name = "site_configs"
|
||||
SOCIAL_MEDIA_SERVICES = %w[
|
||||
twitter facebook github instagram twitch mastodon
|
||||
|
|
@ -24,9 +27,15 @@ module Settings
|
|||
setting :contact_email, type: :string, default: ApplicationConfig["DEFAULT_EMAIL"]
|
||||
setting :periodic_email_digest, type: :integer, default: 2
|
||||
|
||||
# Google Analytics Tracking ID, e.g. UA-71991000-1
|
||||
# Analytics and tracking
|
||||
setting :ga_tracking_id, type: :string, default: ApplicationConfig["GA_TRACKING_ID"]
|
||||
setting :ga_analytics_4_id, type: :string, default: ApplicationConfig["GA_ANALYTICS_4_ID"]
|
||||
setting :cookie_banner_user_context, type: :string, default: "off", validates: {
|
||||
inclusion: { in: BANNER_USER_CONFIGS }
|
||||
}
|
||||
setting :coolie_banner_platform_context, type: :string, default: "off", validates: {
|
||||
inclusion: { in: BANNER_PLATFORM_CONFIGS }
|
||||
}
|
||||
|
||||
# Ahoy Tracking
|
||||
setting :ahoy_tracking, type: :boolean, default: false
|
||||
|
|
|
|||
|
|
@ -2,16 +2,9 @@
|
|||
url: admin_settings_general_settings_path,
|
||||
html: { data: { action: "submit->config#updateConfigurationSettings" } }) do |f| %>
|
||||
<details class="crayons-card">
|
||||
<summary class="crayons-subtitle-2 p-6">Google Analytics</summary>
|
||||
<summary class="crayons-subtitle-2 p-6">Google Analytics and Cookies</summary>
|
||||
<div class="p-6 pt-0">
|
||||
<fieldset class="grid gap-4">
|
||||
<div class="crayons-field">
|
||||
<%= admin_config_label :ga_tracking_id, "Google Universal Analytics View ID" %>
|
||||
<%= admin_config_description Constants::Settings::General.details[:ga_tracking_id][:description] %>
|
||||
<%= f.text_field :ga_tracking_id,
|
||||
class: "crayons-textfield",
|
||||
value: Settings::General.ga_tracking_id %>
|
||||
</div>
|
||||
<div class="crayons-field">
|
||||
<%= admin_config_label :ga_analytics_4_id, "Google Analytics 4 Measurement ID" %>
|
||||
<%= admin_config_description Constants::Settings::General.details[:ga_analytics_4_id][:description] %>
|
||||
|
|
@ -19,6 +12,22 @@
|
|||
class: "crayons-textfield",
|
||||
value: Settings::General.ga_analytics_4_id %>
|
||||
</div>
|
||||
<div class="crayons-field">
|
||||
<%= admin_config_label :cookie_banner_user_context, model: Settings::General %>
|
||||
<%= admin_config_description Constants::Settings::General.details[:cookie_banner_user_context][:description] %>
|
||||
<%= select_tag "settings_general[cookie_banner_user_context]",
|
||||
options_for_select(Settings::General::BANNER_USER_CONFIGS, Settings::General.cookie_banner_user_context),
|
||||
multiple: false,
|
||||
class: "crayons-select" %>
|
||||
</div>
|
||||
<div class="crayons-field">
|
||||
<%= admin_config_label :coolie_banner_platform_context, model: Settings::General %>
|
||||
<%= admin_config_description Constants::Settings::General.details[:coolie_banner_platform_context][:description] %>
|
||||
<%= select_tag "settings_general[coolie_banner_platform_context]",
|
||||
options_for_select(Settings::General::BANNER_PLATFORM_CONFIGS, Settings::General.coolie_banner_platform_context),
|
||||
multiple: false,
|
||||
class: "crayons-select" %>
|
||||
</div>
|
||||
</fieldset>
|
||||
<%= render "update_setting_button", f: f %>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -55,6 +55,8 @@
|
|||
data-deployed-at="<%= j(ForemInstance.deployed_at) %>"
|
||||
data-latest-commit-id="<%= j(ForemInstance.latest_commit_id) %>"
|
||||
data-ga-tracking="<%= j(Settings::General.ga_tracking_id) %>"
|
||||
data-cookie-banner-user-context="<%= j(Settings::General.cookie_banner_user_context) %>"
|
||||
data-cookie-banner-platform-context="<%= j(Settings::General.coolie_banner_platform_context) %>"
|
||||
data-ga4-tracking-id="<%= j(Settings::General.ga_analytics_4_id) %>">
|
||||
<%# Repeat of stylesheets in <head> to fix rendering glitch: https://github.com/forem/forem/issues/12377 %>
|
||||
<%= render "layouts/styles", qualifier: "secondary" %>
|
||||
|
|
|
|||
|
|
@ -118,6 +118,10 @@ en:
|
|||
description: Google Universal Analytics Tracking ID, e.g. UA-XXXXXXXX-1
|
||||
ga_analytics_4:
|
||||
description: Google Analytics 4 Measurement ID, e.g. G-XXXXXXXXX
|
||||
cookie_banner_user_context:
|
||||
description: Used to determine whether the cookie banner should be shown based on user context (i.e. logged in or not)
|
||||
coolie_banner_platform_context:
|
||||
description: Used to determine whether the cookie banner should be shown based on platform (i.e. web/mobile)
|
||||
hashtag:
|
||||
description: Used as the twitter hashtag of the community
|
||||
placeholder: '#DEVCommunity'
|
||||
|
|
|
|||
|
|
@ -118,6 +118,10 @@ fr:
|
|||
description: Google Universal Analytics Tracking ID, e.g. UA-XXXXXXXX-1
|
||||
ga_analytics_4:
|
||||
description: Google Analytics 4 Measurement ID, e.g. G-XXXXXXXXX
|
||||
cookie_banner_user_context:
|
||||
description: Used to determine whether the cookie banner should be shown based on user context (i.e. logged in or not)
|
||||
coolie_banner_platform_context:
|
||||
description: Used to determine whether the cookie banner should be shown based on platform (i.e. web/mobile)
|
||||
hashtag:
|
||||
description: Used as the twitter hashtag of the community
|
||||
placeholder: '#DEVCommunity'
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue