fix: use allowlist for query params to prevent path fragmentation
Switch from blocklist (strip known-bad params) to allowlist (only keep UTM/attribution params). Eliminates cache-busters like _t and _ from page paths without maintaining an ever-growing blocklist.
This commit is contained in:
@@ -8,6 +8,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|||||||
|
|
||||||
### Improved
|
### Improved
|
||||||
|
|
||||||
|
- **Cleaner page paths in your reports.** Pages like `/products?_t=123456` or `/about?session=abc` now correctly show as `/products` and `/about`. Only marketing attribution parameters (like UTM tags) are preserved for traffic source tracking — all other junk parameters are automatically removed, so your Top Pages and Journeys stay clean without us having to chase down every new parameter format.
|
||||||
- **Refreshed chart background.** The dashboard chart now has subtle horizontal lines instead of the old dotted background, giving the chart area a cleaner look with soft faded edges.
|
- **Refreshed chart background.** The dashboard chart now has subtle horizontal lines instead of the old dotted background, giving the chart area a cleaner look with soft faded edges.
|
||||||
- **Smoother loading transitions.** When your data finishes loading, the page now fades in smoothly instead of appearing all at once. This applies across Dashboard, Journeys, Funnels, Uptime, Settings, Notifications, and shared dashboards. If your data was already cached from a previous visit, it still loads instantly with no animation — the fade only kicks in when you're actually waiting for fresh data.
|
- **Smoother loading transitions.** When your data finishes loading, the page now fades in smoothly instead of appearing all at once. This applies across Dashboard, Journeys, Funnels, Uptime, Settings, Notifications, and shared dashboards. If your data was already cached from a previous visit, it still loads instantly with no animation — the fade only kicks in when you're actually waiting for fresh data.
|
||||||
- **Faster tab switching across the board.** Switching between Settings, Funnels, Uptime, and other tabs now shows your data instantly instead of flashing a loading skeleton every time. Previously visited tabs remember their data and show it right away, while quietly refreshing in the background so you always see the latest numbers without the wait.
|
- **Faster tab switching across the board.** Switching between Settings, Funnels, Uptime, and other tabs now shows your data instantly instead of flashing a loading skeleton every time. Previously visited tabs remember their data and show it right away, while quietly refreshing in the background so you always see the latest numbers without the wait.
|
||||||
|
|||||||
@@ -230,25 +230,29 @@
|
|||||||
return cachedSessionId;
|
return cachedSessionId;
|
||||||
}
|
}
|
||||||
|
|
||||||
// * Normalize path: strip trailing slash and ad-platform click/tracking IDs.
|
// * Normalize path: strip trailing slash and all query params except UTM/attribution.
|
||||||
// * UTM params (utm_source, utm_medium, etc.) are intentionally kept in the path
|
// * Allowlist approach — only UTM params pass through because the backend extracts
|
||||||
// * because the backend extracts them for attribution before cleaning the path.
|
// * them for attribution before cleaning the stored path. Everything else (cache-busters,
|
||||||
var STRIP_PARAMS = ['fbclid', 'gclid', 'gad_source', 'msclkid', 'twclid', 'dclid', 'mc_cid', 'mc_eid', 'ad_id', 'adset_id', 'campaign_id', 'ad_name', 'adset_name', 'campaign_name', 'placement', 'site_source_name', 'utm_id'];
|
// * ad click IDs, filter params, etc.) is stripped to prevent path fragmentation.
|
||||||
|
var KEEP_PARAMS = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'source', 'ref'];
|
||||||
function cleanPath() {
|
function cleanPath() {
|
||||||
var pathname = window.location.pathname;
|
var pathname = window.location.pathname;
|
||||||
// * Strip trailing slash (but keep root /)
|
// * Strip trailing slash (but keep root /)
|
||||||
if (pathname.length > 1 && pathname.charAt(pathname.length - 1) === '/') {
|
if (pathname.length > 1 && pathname.charAt(pathname.length - 1) === '/') {
|
||||||
pathname = pathname.slice(0, -1);
|
pathname = pathname.slice(0, -1);
|
||||||
}
|
}
|
||||||
// * Strip UTM/marketing params, keep other query params
|
// * Only keep allowlisted params, strip everything else
|
||||||
var search = window.location.search;
|
var search = window.location.search;
|
||||||
if (search) {
|
if (search) {
|
||||||
try {
|
try {
|
||||||
var params = new URLSearchParams(search);
|
var params = new URLSearchParams(search);
|
||||||
for (var i = 0; i < STRIP_PARAMS.length; i++) {
|
var kept = new URLSearchParams();
|
||||||
params.delete(STRIP_PARAMS[i]);
|
for (var i = 0; i < KEEP_PARAMS.length; i++) {
|
||||||
|
if (params.has(KEEP_PARAMS[i])) {
|
||||||
|
kept.set(KEEP_PARAMS[i], params.get(KEEP_PARAMS[i]));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
var remaining = params.toString();
|
var remaining = kept.toString();
|
||||||
if (remaining) pathname += '?' + remaining;
|
if (remaining) pathname += '?' + remaining;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// * URLSearchParams not supported — send path without query
|
// * URLSearchParams not supported — send path without query
|
||||||
|
|||||||
Reference in New Issue
Block a user