From db6f976683f653bd30aed53ab8b87645941ea9b8 Mon Sep 17 00:00:00 2001 From: Romain Derie Date: Wed, 21 Feb 2024 16:35:31 +0000 Subject: [PATCH] [FIX] website: consider utm after cookies are accepted Current behavior: When the cookie bar is activated, the optional cookies are deactivated by default, unless you click on I agree. This causes issues regarding UTMs: - You can have blocks to show only if an UTM cookies has been set - UTM should be added on sale order for instance when reaching the website through a link with an UTM and then buying something Steps to reproduce (utm on quotation): 1. Install ecommerce 2. Go to Settings/Website 3. Activate Cookies Bar 4. Open a private tab 5. Go to /shop?utm_campaign=Sale 6. Click on I agree on the cookie bar 7. Buy a product 8. Go back to Sales App in backend 9. Find the last public user quotation 10. Go to other info tab 11. The medium field is empty Steps to reproduce (utm based visibility): 1. Drag & drop a snippet on a page (let's say the /page) 2. Set that snippet visibility to "Visible only if utm campaign is "Sale" 3. Repeat step 2 3 4 from above 4. Open /page?utm_campaign=Sale 5. You will see that the block is not shown despite accepting the cookies and having the correct utm set. Note: we don't want that clicking on I agree reload the page, it would solve everything but would have poor usability. Note that with the default cookies bar, you could still naviguate to another page, and accept the cookies later, in which case the UTM would never be set since they would not be in the URL anymore. It's an acceptable limitation, if that's a real issue to someone, they have to set the popup layout to a blocking one, not the small non intrusive one. Fix: When closing the cookie bar, forcing the info in the URL to be stored in the cookies if the key is a UTM. opw-3681927 closes odoo/odoo#157711 X-original-commit: 8c31c2b08ed84ccdb97af628d9db7f6c67c6d830 Signed-off-by: Romain Derie (rde) Co-authored-by: Antoine (ande) --- .../static/src/js/content/inject_dom.js | 12 +++++++---- .../static/src/snippets/s_popup/000.js | 20 +++++++++++++++++++ 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/addons/website/static/src/js/content/inject_dom.js b/addons/website/static/src/js/content/inject_dom.js index 19dc4dcdfea..9c5c5760bfc 100644 --- a/addons/website/static/src/js/content/inject_dom.js +++ b/addons/website/static/src/js/content/inject_dom.js @@ -25,9 +25,7 @@ export function unhideConditionalElements() { } } -document.addEventListener('DOMContentLoaded', () => { - // Transfer cookie/session data as HTML element's attributes so that CSS - // selectors can be based on them. +export function setUtmsHtmlDataset() { const htmlEl = document.documentElement; const cookieNamesToDataNames = { 'utm_source': 'utmSource', @@ -41,11 +39,17 @@ document.addEventListener('DOMContentLoaded', () => { htmlEl.dataset[dsName] = cookie.replace(/(^["']|["']$)/g, ''); } } +} + +document.addEventListener('DOMContentLoaded', () => { + // Transfer cookie/session data as HTML element's attributes so that CSS + // selectors can be based on them. + setUtmsHtmlDataset(); + const htmlEl = document.documentElement; const country = session.geoip_country_code; if (country) { htmlEl.dataset.country = country; } - htmlEl.dataset.logged = !session.is_website_user; unhideConditionalElements(); diff --git a/addons/website/static/src/snippets/s_popup/000.js b/addons/website/static/src/snippets/s_popup/000.js index 43c4ca5fe9c..3b40b22a37d 100644 --- a/addons/website/static/src/snippets/s_popup/000.js +++ b/addons/website/static/src/snippets/s_popup/000.js @@ -4,6 +4,7 @@ import publicWidget from "@web/legacy/js/public/public_widget"; import { cookie } from "@web/core/browser/cookie"; import {throttleForAnimation} from "@web/core/utils/timing"; import { utils as uiUtils } from "@web/core/ui/ui_service"; +import {setUtmsHtmlDataset} from '@website/js/content/inject_dom'; // TODO In master, export this class too or merge it with PopupWidget const SharedPopupWidget = publicWidget.Widget.extend({ @@ -361,6 +362,25 @@ publicWidget.registry.cookies_bar = PopupWidget.extend({ this.cookieValue = `{"required": true, "optional": ${ev.target.id === 'cookies-consent-all'}}`; this._onHideModal(); }, + /** + * @override + */ + _onHideModal() { + this._super(...arguments); + const params = new URLSearchParams(window.location.search); + const trackingFields = { + utm_campaign: "odoo_utm_campaign", + utm_source: "odoo_utm_source", + utm_medium: "odoo_utm_medium", + }; + for (const [key, value] of params) { + if (key in trackingFields) { + // Using same cookie expiration value as in python side + cookie.set(trackingFields[key], value, 31 * 24 * 60 * 60, "required"); + } + } + setUtmsHtmlDataset(); + } }); export default PopupWidget;