Mobify DevCenter

Filtering Query Strings to Improve Caching

Note: Before you follow this guide, we recommend reading our overview of the request processor.

Many apps use query string parameters to represent variables values. For example, if your app lets users search, you may choose to represent a search for “sweater” using a query string: search=sweater.

It is also common to use query strings to track user actions. For example, we might append a unique query string to each link in a email to track interactions with it: user=john&source=email.

Typically, tracking query strings are not used server side, but are used client side by services like Google Analytics.

Mobify’s CDN looks up objects in its cache using the full URL including the query string. If all requested URLs use unique query strings, every URL will be unique. No request will be served a cached response! This results in sub-optimal performance.

We can use the request processor to filter query strings that are only used on the client side, so that the CDN is more likely to respond with a cached response.

This example uses processRequest to filter query string parameters gclid and utm_campaign, which are commonly associated with Google marketing campaigns. It uses the QueryParameters class to simplify working with query strings:

import {QueryParameters} from 'progressive-web-sdk/dist/utils/ssr-request-processing'
const filterQueryStringKeys = (querystring, filteredKeys) =>
new QueryParameters(querystring).parameters.filter(({key}) => !filteredKeys.includes(key))
export const processRequest = ({path, querystring}) => ({
querystring: filterQueryStringKeys(querystring, ['gclid', 'utm_campaign'])

Because the request processor returns a modified querystring, the modified full URL is used to look up the corresponding object in the cache, and is passed to the app in the event it is not present.

Be aware of a couple of gotchas using this approach:

First, note that parameters filtered using the request processor are not sent to the application. Ensure that your app doesn’t use the filtered parameters for rendering! For example, if you filtered the search parameter from above, you’d have a hard time displaying the correct search results.

In addition, be cautious when you’re filtering parameters from requests you expect the app to redirect. The application won’t see the filtered parameters and the redirect returned to the browser will not contain them. For example, imagine the app for redirects users to a specific locale like If we filter query string parameters in the request processor, the application will be unaware of them, and unable to include them in a redirect. Consider this sequence:

  1. The request processor handles a request for
  2. The request processor filters the gclid query string parameter
  3. The request is forwarded to the application with the full URL
  4. The application returns a redirect to

Note that on this last step, we’ve lost the original gclid parameter, so it won’t be available client side after the user is redirected.

To work around this challenge, avoid filtering query strings of requests you expect to redirect!