Skip to content

Commit

Permalink
feat(Translations): Add translations analytics (#1881)
Browse files Browse the repository at this point in the history
* feat(Translations): Add translations analytics

* added support for Edge, and language detection where possible

* Added whitespace for clarity

* Get the language from the mutation target

* Combine the translate log and language

* Added support for new google tag manager environments

* Updated comment
  • Loading branch information
kotva006 authored Mar 28, 2024
1 parent a713871 commit fe60eb2
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 3 deletions.
2 changes: 2 additions & 0 deletions assets/js/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import fixedsticky from "./fixedsticky";
import geoLocation from "./geolocation";
import addressSearch from "./address-search";
import googleTranslate from "./google-translate";
import translateAnalytics from "./translate-analytics.js";
import scrollTo from "./scroll-to";
import stickyTooltip from "./sticky-tooltip";
import timetableScroll from "./timetable-scroll";
Expand Down Expand Up @@ -367,6 +368,7 @@ inputFocus();
geoLocation();
addressSearch();
googleTranslate();
translateAnalytics();
scrollTo();
tabbedNav();
timetableScroll();
Expand Down
50 changes: 50 additions & 0 deletions assets/js/translate-analytics.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// Detects if the page is translated and notifies analyticis

// adapted from: https://analytical42.com/2022/detect-track-translations-ga4/
// This code does its best to detect if the user changes the language of the page.
// Right now it fully supports logging from users changing the page language from the website itself regardless of the browser used
// This struggles with detecting and reporting the new language when the user uses the browser to
// change the language.
// Chrome - Full support, we can detect when the user translates the page, and what language the page is translated to
// Safari - Full support, we can detect when the user translates the page, and what language the page is translated to
// Edge - Half support, we can detect when the user translates the page, just not what language they changed it to
// Firefox - Full Suuport, we can detect when the user translates the page and what language the page is translated to
export default () => {
// Start by checking if the MutationObserver API is available
if (typeof MutationObserver === "function") {
// Tell the observer to monitor for changes to HTML attributes
const config = { attributes: true };
// Build the function to run when a change is observed
const callback = mutationList => {
// Loop through each observed change
for (let i = 0; i < mutationList.length; i += 1) {
// Only do something if the change was on an attribute
if (mutationList[i].type === "attributes") {
if (
// Check for Edge's browser translation attributes
// Edge adds 2 attributes (_msttexthash and _msthash), so we only check for one to avoid duplicate logging
mutationList[i].attributeName === "_msttexthash" ||
// Check for Chrome, Google, and Safari's browser translation lang attribute
mutationList[i].attributeName === "lang"
) {
// Grab the new language from the html lang attribute (if available)
const newLanguage = mutationList[i].target.getAttribute("lang");
window.dataLayer = window.dataLayer || [];
// Send an event to the dataLayer
// Only log if we can detect the new language and it isn't english (the default of the page which some browsers do not update)
window.dataLayer.push({
event: "translate",
language: newLanguage && newLanguage !== "en" ? newLanguage : ""
});
}
}
}
};
// Create the actual observer
const observer = new MutationObserver(callback);
// Attach the observer to the <title> tag
observer.observe(document.getElementsByTagName("title")[0], config);
// Attach the observer to the <html> tag
observer.observe(document.getElementsByTagName("html")[0], config);
}
};
4 changes: 3 additions & 1 deletion config/runtime.exs
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,9 @@ config :dotcom, LocationService,
aws_index_prefix: System.get_env("AWS_PLACE_INDEX_PREFIX", "dotcom-prod")

config :dotcom, DotcomWeb.ViewHelpers,
google_tag_manager_id: System.get_env("GOOGLE_TAG_MANAGER_ID")
google_tag_manager_id: System.get_env("GOOGLE_TAG_MANAGER_ID"),
google_tag_manager_auth: System.get_env("GOOGLE_TAG_MANAGER_AUTH"),
google_tag_manager_preview: System.get_env("GOOGLE_TAG_MANAGER_PREVIEW")

config :dotcom,
enable_experimental_features: System.get_env("ENABLE_EXPERIMENTAL_FEATURES")
Expand Down
14 changes: 12 additions & 2 deletions lib/dotcom_web/templates/layout/root.html.eex
Original file line number Diff line number Diff line change
Expand Up @@ -119,8 +119,18 @@
}
</script>
<%= if google_tag_manager_id() do %>
<noscript><iframe src="//www.googletagmanager.com/ns.html?id=<%= google_tag_manager_id()%>&visitorType=noJS" height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
<script>(function (w, d, s, l, i) { w[l] = w[l] || []; w[l].push({ 'gtm.start': new Date().getTime(), event: 'gtm.js' }); var f = d.getElementsByTagName(s)[0], j = d.createElement(s), dl = l != 'dataLayer' ? '&l=' + l : ''; j.async = true; j.src = '//www.googletagmanager.com/gtm.js?id=' + i + dl; f.parentNode.insertBefore(j, f); })(window, document, 'script', 'dataLayer', '<%= google_tag_manager_id() %>');</script>
<!-- Google Tag Manager (noscript) -->
<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=<%= google_tag_manager_id()%>&gtm_auth=<%= google_tag_manager_auth() %>&gtm_preview=<%= google_tag_manager_preview() %>&gtm_cookies_win=x"
height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
<!-- End Google Tag Manager (noscript) -->
<!-- Google Tag Manager -->
<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
'https://www.googletagmanager.com/gtm.js?id='+i+dl+ '&gtm_auth=<%= google_tag_manager_auth() %>&gtm_preview=<%= google_tag_manager_preview() %>&gtm_cookies_win=x';f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','<%= google_tag_manager_id() %>');
</script>
<!-- End Google Tag Manager -->
<% end %>
</body>
</html>
14 changes: 14 additions & 0 deletions lib/dotcom_web/views/helpers.ex
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,20 @@ defmodule DotcomWeb.ViewHelpers do
end
end

def google_tag_manager_auth do
case env(:google_tag_manager_auth) do
"" -> nil
id -> id
end
end

def google_tag_manager_preview do
case env(:google_tag_manager_preview) do
"" -> nil
id -> id
end
end

defp env(key) do
Application.get_env(:dotcom, __MODULE__)[key]
end
Expand Down

0 comments on commit fe60eb2

Please sign in to comment.