AEM Dispatcher Caching Strategies for SPA Route URLs

Single-page applications change how browsers request content from Adobe Experience Manager. Instead of loading a new document for every screen, an SPA often updates the address bar with routes such as /products, /products/brisbane, or /account/orders while JavaScript controls the visible experience. That behaviour creates important questions for Dispatcher caching, especially when route URLs look like ordinary pages but depend on client-side rendering.

A sound caching design must distinguish between the HTML shell, AEM-delivered data, static assets, and browser history. It also needs clear rules for query strings, selectors, extensions, redirects, invalidation, and personalisation. A route that appears cacheable can become unsafe if it carries visitor-specific information or relies on an uncached API response.

Australian delivery conditions make this worth careful attention. A national site may serve customers in Sydney, Melbourne, Perth, Brisbane, and regional areas through different network paths, while CDN edge locations and variable NBN performance affect perceived speed. Teams should test from several Australian locations rather than assuming that a response which is fast in a Sydney office will behave identically everywhere.

Why Route URLs Need A Different Cache Model

Traditional AEM pages commonly map a requested path to a rendered HTML document. Dispatcher can cache that response against the URL, subject to filter rules and headers. An SPA route may follow the same pattern at the browser level, yet the server may return one shared application shell for many routes. The visible page is then assembled by JavaScript from model data, GraphQL, REST, or content fragment requests.

This creates two common patterns. In the first, every route is rewritten to /content/site/en.html, and Dispatcher stores one shell response. In the second, AEM renders route-aware HTML for search visibility, accessibility, or initial page performance. The first pattern usually offers simpler invalidation; the second can provide stronger first-render performance but requires route-level cache keys and publishing discipline.

The conference agenda reflects the kind of architecture discussions that help teams evaluate these trade-offs: route handling is not an isolated front-end concern. It affects AEM resource resolution, web server rewrites, CDN behaviour, analytics, and release operations.

How Dispatcher Resolves SPA Requests

Start by documenting the complete request path. A browser may request /au/shop/water-bottles, the web server may rewrite it to /content/example/au/shop.html, and Dispatcher may then apply filters, cache rules, and render selection. If the rewrite removes route information before the cache key is generated, several distinct routes can share a response. That is correct only when the returned document is genuinely identical.

Extensionless routes need particular care. Dispatcher and the web server should agree on whether /shop maps to a page, an HTML representation, or the SPA shell. Avoid broad rewrites that send every unknown path to the shell, because they can hide missing content, interfere with asset requests, or turn a genuine 404 into a successful cached document. Explicit route patterns are easier to audit and safer to purge.

Query parameters deserve the same scrutiny. Tracking parameters such as utm_source should generally be ignored for cache identity, while functional parameters that alter content must either be included in the key or rejected from the cache. A whitelist is safer than allowing every parameter, since an attacker or misconfigured integration could create unlimited cache variants.

Choose Invalidation And TTL Boundaries

For a shared SPA shell, long browser and CDN lifetimes are often appropriate when JavaScript and CSS use fingerprinted filenames. A deployment that changes app.84c1.js to app.91af.js can leave older assets available while new HTML points to the latest versions. This approach reduces broken references during rollout and makes cache purging more predictable.

The HTML shell usually needs a shorter lifetime because it contains asset references, configuration, and sometimes feature flags. AEM activation should trigger invalidation for pages and model responses that depend on changed content. If a route-specific document is cached independently, the activation workflow must identify that URL rather than clearing only the underlying repository path.

Do not treat Dispatcher flushing as a universal solution. Purging a local Dispatcher instance may leave stale data at a CDN, reverse proxy, browser, or service worker. Define ownership for each layer, record purge events, and make cache headers consistent. A short stale period can protect availability during a publish event, but it should never conceal an incomplete invalidation process.

A useful test is to publish a small content change and trace the response through every layer. Confirm the first request is a miss, the next request is a hit, and the changed content appears after the intended purge. Repeat this with two routes that share a shell and two routes that require distinct server-rendered output.

Keep Personalisation Out Of Shared HTML

Shared caching becomes unsafe when a route response includes a name, account status, location, basket contents, entitlement, or experiment assignment. Cookies and authorisation headers should be treated as signals requiring explicit design, not as harmless additions to a public page request. If a personalised response reaches a shared cache, one visitor’s data may be delivered to another.

A safer architecture delivers public HTML from Dispatcher and obtains private information through authenticated, non-cacheable calls. Where possible, keep the shell and public content cacheable, then render user-specific elements in the browser. For sensitive endpoints, use suitable cache-control headers, strict access rules, and an API layer that does not accidentally inherit page-cache behaviour.

This principle applies to sites outside commerce as well. A public child development resource still needs careful separation between general editorial content and any private submission or account function. In the Australian market, privacy expectations under the Privacy Act and the Australian Privacy Principles make accidental disclosure especially costly, even when the original implementation was intended as a performance optimisation.

Analytics should follow the same separation. Avoid making the whole route uncacheable merely because measurement is required. Client-side analytics, server-side event collection, or edge-safe headers can preserve a cacheable document while still supporting campaign attribution and product reporting.

Validate Behaviour Across Australian Delivery Paths

Performance tests should represent actual Australian conditions. Compare response headers, cache status, and time to first byte from Sydney, Melbourne, Brisbane, Perth, and at least one regional location. A route may be a cache hit in a Sydney test while a CDN configuration sends Perth users to an unexpectedly distant origin. Check IPv4 and IPv6 paths if both are supported.

Mobile traffic also deserves realistic testing. Visitors on congested networks, older Android devices, or inconsistent regional connections are more sensitive to a large shell and repeated API calls. A cache hit does not guarantee a fast experience if the browser must download several megabytes before rendering. Compress assets, split JavaScript by route where practical, and keep the initial data request small.

For teams maintaining older AEM implementations, the AEM mobile apps article offers useful historical context for thinking about mobile delivery and application shells. The specific tooling may differ from a current SPA stack, but the architectural question remains: which resources are stable enough to cache, and which responses depend on the device or visitor?

Use automated tests to check more than status codes. Verify that /shop, /shop/, encoded characters, unknown routes, query parameters, trailing slashes, and language prefixes produce the intended cache result. Include publish, unpublish, redirect, and permission changes, then inspect whether stale content remains reachable through alternate URL forms.

Build A Practical Operating Playbook

A reliable implementation turns these decisions into documented rules shared by developers, AEM authors, platform engineers, and support staff. Record the canonical route format, rewrite target, cache key, accepted parameters, invalidation trigger, and expected headers for every public route family.

Use the following recommendations as a working checklist:

  • Cache the public SPA shell separately from private API responses and visitor-specific fragments.
  • Use explicit rewrite rules for supported routes, assets, language prefixes, and genuine 404 responses.
  • Whitelist functional query parameters and remove tracking parameters from cache identity where safe.
  • Fingerprint JavaScript, CSS, and media assets so long-lived caching does not block deployments.
  • Connect AEM publication events to Dispatcher and CDN invalidation for affected route documents.
  • Test cache hits, misses, stale responses, and purges from multiple Australian network locations.
  • Monitor cache status, origin traffic, purge failures, and unexpected query-string variants in production.

Operational monitoring should expose the difference between a browser cache hit, CDN hit, Dispatcher hit, and origin response. Add correlation identifiers to logs, but avoid placing user identifiers in cacheable URLs or response headers. Alerts should cover a sudden fall in hit ratio, a rise in origin requests, repeated 5xx responses, and cache growth caused by uncontrolled parameters.

Review the playbook whenever the SPA router, AEM project structure, CDN, authentication model, or analytics implementation changes. A route that was safely shared last year may become personalised after a feature release. Treat cacheability as an explicit property of each response, not as a permanent characteristic of its URL.

Apply these rules to one representative route family first, then inspect headers and content across the full request chain. Once the shell, APIs, invalidation workflow, and regional performance checks behave correctly, extend the pattern to the remaining routes and preserve the tests as part of every AEM deployment.