Browser: Chrome 110
OS: Windows 11
URL: https://www.axelils.com
Video: Jam
[Please describe this bug in as much detail as possible so we can replicate & debug this bug]
Hello community members,
I am looking for some help with a Google Tag Manager (GTM) implementation for an AJAX-based search feature on my website.
Current Setup & Goal
-
How it works: Users click a search icon in the header to go to the search page. The search is triggered either by clicking the icon or pressing Enter, loading results via AJAX.
-
The Goal: I want to send the search keyword and the results count to Google Analytics via GTM. If a search yields no results, it should still send the keyword with a
0count.
The Problem
Right now, the tracking is not active. I previously tried a few AI-suggested code snippets to push this data to the dataLayer, but they broke the site. Whenever the data layer push code is active, both Google Tag Manager and Tag Assistant freeze completely.
Because of this freezing issue, the tracking event never fires successfully.
Below are the implementation details and the specific code that causes the crash. Any insights into why this freeze is happening or how to properly structure the AJAX data layer push would be greatly appreciated!
Implementation Details
Bricks Builder layout
Section
Container
Block
Filter-Search
Filter- Submit/Reset
Container (Results Wrapper)
Block
Query Results Summary
Basic Text1 (to display search keyword)
Code1 ( To populate dynamic search keyword due to live search)
Loop Block (Query loop for search)
Block
Image
Block
Post title
Basic text2 ( to display author and time )
Pagination
Code2 ( Get search keyword)
Code3 (to ensure search result does not vanish when clicked outside)
Basic Text 1
for
Code 1:
document.addEventListener(âDOMContentLoadedâ, function () {
// Find the Bricks Filter-Search input element
const searchInput = document.querySelector(â.brxe-filter-search input, .brxe-filter-search textareaâ);
if (!searchInput) return;
function updateSummaryKeyword() {
// Find all span placeholders on the page
const targets = document.querySelectorAll(".live-search-keyword");
targets.forEach(span => {
span.textContent = searchInput.value;
});
}
// Update whenever the user types into the input box
searchInput.addEventListener("input", updateSummaryKeyword);
// Run on AJAX query loop complete to catch the text state
document.addEventListener("bricks/query/loop/refresh", function() {
setTimeout(updateSummaryKeyword, 100);
});
});
Code 2:
const urlParams = new URLSearchParams(window.location.search);
const searchKeyword = urlParams.get(âsearch_termâ);
console.log(searchKeyword);
Code 3:
document.addEventListener(âbricks/ajax/query_result/displayedâ, (event) => {
const queryId = event.detail?.queryId
if (!queryId) {
return
}
const query = window.bricksData?.queryLoopInstances?.[queryId]
if (!query?.isLiveSearch) {
return
}
const wrapper = document.querySelector(`[data-brx-ls-wrapper="${queryId}"]`)
const searchInput = Object.values(window.bricksData?.filterInstances || {}).find((filter) => {
return filter.targetQueryId === queryId && filter.filterType === 'search'
})?.filterElement
if (wrapper && searchInput?.value.trim()) {
wrapper.classList.add('keep-live-search-open')
}
if (wrapper && !searchInput?.value.trim()) {
wrapper.classList.remove('keep-live-search-open')
}
})
Code in Code 1 which did not work
document.addEventListener(âDOMContentLoadedâ, function () {
const searchInput = document.querySelector(â.brxe-filter-search input, .brxe-filter-search textareaâ);
const summaryEl = document.querySelector(â.brxe-query-results-summaryâ);
if (!searchInput) return;
function updateSummaryKeyword() {
document.querySelectorAll(".live-search-keyword").forEach(span => {
span.textContent = searchInput.value.trim();
});
}
function getResultsCount() {
if (!summaryEl) return 0;
try {
const stats = summaryEl.getAttribute("data-brx-qr-stats-data");
if (stats) {
const parsed = JSON.parse(stats);
return Number(parsed.total) || 0;
}
} catch (e) {}
const text = summaryEl.textContent || "";
const match = text.match(/out of\\s+(\\d+)/i);
return match ? parseInt(match\[1\], 10) : 0;
}
let lastPushed = ââ;
let pushTimer = null;
function pushSearchEvent() {
const term = searchInput.value.trim();
if (!term || term === lastPushed) return;
const results = getResultsCount();
window.dataLayer = window.dataLayer || \[\];
window.dataLayer.push({
event: "internal_search",
search_term: term,
results_count: results,
has_results: results > 0
});
lastPushed = term;
}
searchInput.addEventListener(âinputâ, updateSummaryKeyword);
document.addEventListener(âbricks/query/loop/refreshâ, function () {
clearTimeout(pushTimer);
pushTimer = setTimeout(function () {
updateSummaryKeyword();
pushSearchEvent();
}, 150);
});
});
Best regards,
D. Mallick