Building a member area on Core dna: who a member is in the data, the sign-in flows and their templates, single sign-on and passkeys, the my-account routing convention, members-only content, sessions and the page cache, and the security checks to run before launch.
L2
Unit 06 · Sessions, cookies and the cache
Member pages and the page cache
Sessions, cookies and the cachePage 31 of 36Updated
The page cache serves a stored copy to anyone who asks, signed in or not, and never stores what a signed-in visitor sees. What that does to a member site, how to measure it, and the cached shell with member fragments that keeps public pages fast.
Who this is for. The theme developer planning a member site, before building it. Afterwards you know which pages a member is served from the cache, which are rendered for them, and how to keep the public pages cached without showing members the wrong thing.
The rule, in two halves
A stored copy is served to everyone. The page cache is read before the platform looks at any cookie or header, so a URL with a stored copy answers with that copy, whoever asks. A signed-in member is served the copy rendered for an anonymous visitor.
Nothing rendered for a signed-in visitor is stored. A member's own render is never written to the cache, so a member never sees another member's page.
A stored copy is keyed on the hostname, the path and any query parameters the page declares; no cookie is part of the key. Authenticated requests and the cache covers the mechanism and the other cache layers.
What it does to a member site
Member pages render every time. A page under /my-account is never stored: signed-out visitors are redirected, and a member's render is not written. Its cost is its render, so keep member templates light (The three query-per-row shapes).
Personal output on a public page is wrong for members. Once anyone has visited the page signed out, members get that copy: a header that says "Sign in", no personal panel, and no CSRF token, so a member form on that page fails with a 403. Testing signed in on a cold cache never shows it.
Keep preventCaching() scoped to what needs it. On a whole public page it makes every visit a full render, for everyone; called from a base template, it switches the page cache off for the whole site. Call it on the member-specific part alone, so the rest of the site keeps the benefit of caching as traffic grows.
Reserve enforceCaching() for pages that look the same to every visitor. It stores the page even when a member rendered it, and the stored copy is then served to everyone who asks for that URL, signed out included. Never call it on a page that shows anything about the visitor.
Measuring it
Two response headers tell you which case a response is. X-Cache-Status says whether it came from the page cache (hit) or was rendered (miss, store when the render was stored, miss, no-store when it was not). X-Authenticated is 1 when the response was rendered for a signed-in user, and 0 otherwise, including on every stored copy. Development environments never store pages, so measure on production or a staging environment that caches:
Then open the same URL signed in as a member and read the headers in the browser's network panel. hit with X-Authenticated: 0 on a page that should know the member means the member was served the anonymous copy. miss, no-store on every request to a public page means caching is off for it, and every visitor pays for a full render. Measuring cache effectiveness covers sites behind the platform's CDN, where a miss is labelled differently.
A cached shell with member fragments
The answer is to cache the page for everyone and load the member-specific parts separately. The shell renders the signed-out version of each personal part, so it is correct for anyone and safe to store. A small fragment, rendered per visitor and never stored, supplies the member's version, and a script swaps it in after the page has painted. For a site header:
The fragment needs a URL of its own. Hybrid builds, in its section on dynamic fragments, sets one up with a Fragment layout and a page per fragment, and shows how the same fragment hands over the CSRF token that a cached page cannot carry. The recipe is the how-to Show logged-in state on a cached page.
Keep fragments small: each one is a render on every page view, for every visitor. The parts that belong in one are few: the member's name and account links, the cart count, the CSRF token, and a personal panel such as "your courses". Everything else stays in the shell, cached.