I'm currently chatting with WPEngine in the hopes of getting this issue resolved.
WPEngine's varnish cache does in fact strip out utm_ and gclid_ parameters in an effort to improve caching. Sadly, WPEngines implementation of this "feature" strips out all subsequent query parameters after the first utm_ or gclid_ parameter is identified.
For example the the URL:
www.example.com/test/?foo=bar&utm_source=email&page=1
What you would expect your server to receive:
www.example.com/test/?foo=bar&page=1
What your server actually receives:
www.example.com/test/?foo=bar
Notice how the page=1 parameter is removed even though it is not a utm_ or gclid_ parameter.
WPEngine's proposed workaround is to apply utm_ and gclid_ to the cache exclusion list, but this means that cache will not be served if ever there is a a utm_ or gclid_ parameter in your url. This seems less than ideal as if a URL has a utm_ or gclid_ parameter it is most likely from an email, and doing large email send outs means a spike in traffic which is exactly when you would want to serve a cached page.
Below is some javascript that detects if the utm_ or gclid_ is in the URL and if it is it rearranges the url so that the utm_ and gclid_ parameters are at the end of the query string and then triggers a page redirect. The code below specifically looks for a parameter called tfa_next which is a parameter added on to the end of a URL via a FormAssembly redirect. The below code could be improved to be more generic but I hope it serves as a starting point for anyone who needs it.
const params = new URLSearchParams(window.location.search);
var newParams = "";
console.log("This is working");
if(params.has('tfa_next')){
console.log("it has a tfa_next param");
if(window.location.href.includes("UTM_") || window.location.href.includes("utm_") || window.location.href.includes("GCLID_") || window.location.href.includes("gclid_")){
console.log("it has a utm param");
var count = 0;
for(const [key, value] of params) {
if(count == 0 && key == "tfa_next"){
break;
} else {
count += 1;
}
if(key.includes("UTM_") || key.includes("utm_") || key.includes("GCLID_") || key.includes("gclid_")){
newParams = newParams + key + "=" + encodeURIComponent(value) + "&";
} else {
newParams = key + "=" + encodeURIComponent(value) + "&" + newParams;
}
console.log("NewParams: " + newParams);
}
if(newParams.slice(newParams.length - 1) == "&"){
newParams = newParams.slice(0, newParams.length - 1);
console.log("final query string: " + newParams);
}
if (count > 0) {
console.log("end result: " + window.location.protocol + "//" + window.location.hostname + window.location.pathname + "?" + newParams);
window.location.replace(window.location.protocol + "//" + window.location.hostname + window.location.pathname + "?" + newParams);
}
}
}