Notes


Note on GraphQL and the API #

The gate only runs when Craft renders an element's URL. It does not apply to GraphQL, the Element API, or any decoupled/headless front-end. The password itself is excluded from the schema (it can't be selected), and unlocking is a server-side session flag with no API equivalent. But a protected element's other fields stay readable through any API whose scope includes them. Gating API-consumed content is your app's job.

To keep protected content out of an API, prefer scope: leave the section out of your GraphQL token / public schema. If you can't, filter it out. The field handle is exposed as a presence-only query argument (a Craft-wide behaviour), so:

GraphQL
# unprotected entries only
{
  entries(section: "home", <handle>: ":empty:") {
    title
  }
}

Use ":notempty:" for only protected entries. It tests presence against the encrypted value, never the plaintext.

Note on caching #

Protected responses are sent with no-store. If you use a server- or CDN-level full-page cache, make sure it honours that (or excludes protected URLs) so protected pages aren't served from cache to anonymous visitors.

Note on light/dark mode #

The bundled unlock screen is a self-contained page (Speakeasy swaps the whole response, so none of your site's CSS or JS loads on it). It adapts to light/dark via the visitor's OS/browser preference (@media (prefers-color-scheme: dark)), which works everywhere without any cooperation from your templates. It does not follow a site's manual theme toggle (a .dark class, a data-theme attribute, a cookie), because that toggle's JS never runs on the unlock screen. If a visitor's OS is light but they've switched your site to dark, the unlock screen still shows light. To mirror a manual toggle, set a Custom unlock template so the screen renders inside your own layout, where your theme logic applies.

Note on Safari #

When editing in Safari, iCloud Keychain may offer to save the field's value as a site password. It keys on the field's label and has no markup-level opt-out, so name the field anything other than "Password" (e.g. "Passphrase" or "Access code") to avoid the prompt. Firefox and Chrome are unaffected.