Skip to content

theme: a document-cache entry replays the first visitor's initialTheme to every visitor #978

Closed

Description

@ivogt

Problem

The document cache (src/cache/document-cache.ts, opt-in via s-maxage) stores the full HTML response, and that includes metadata.initialTheme. Without a PPR capture, payloadInitialTheme reads it from the current visitor's theme cookie (full-payload.ts:100). Every visitor served that cached document therefore gets the first visitor's initialTheme. A visitor with no stored theme keeps the other visitor's useTheme().theme / resolvedTheme for the page's lifetime: ThemeProvider re-syncs only from an explicit cookie or localStorage value (ThemeProvider.tsx ~153).

The <html> class is correct, because the inline theme script reads document.cookie before paint. So the symptom is useTheme() output, such as a toggle label or icon, showing another visitor's theme.

This is the same mismatch the #971 fix (PR pending) closes for PPR shells, where the capture now stores themeConfig.defaultTheme. This report comes from reading the code; no test has run it yet.

Proposal

When a document is rendered for the document cache, set initialTheme to the configured default theme and ignore the visitor's cookie, the same way the shell capture does. Add a test with a dark-cookie visitor first, then a no-cookie visitor.

Activity

  1. ivogt commented on Sep 30, 2026

    @ivogt
    CollaboratorAuthor

    Fixed in #987.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions