Appearance
Switching themes
In the admin: Themes — the screen this page documents (opens in the running app).
What/why: Presentation & theming — what this screen manages and why it exists.
Purpose: change the app's active look-and-feel — per surface, from the admin, with no rebuild or deploy.
When to use
- Applying a new brand or seasonal look to the public site.
- Restyling the admin back-office independently of the buyer experience.
Prerequisites
- Admin access with the
edit_datacapability (anydata_editororadminrole).
Steps
- Open Admin → Themes (
/admin/themes). - The Public theme card lists every theme registered for the public surface; the Admin theme card lists admin-surface themes. The active theme in each card carries an "Active" badge.
- Pick a theme with its radio button and click Apply.
- The change is stored in D1 (
app_settings) and takes effect on the next page load — no rebuild, no redeploy. Each apply is recorded in the audit trail (entitytheme, entity idpublic/admin).
Behavior guarantees
- The two surfaces are independent: changing the public theme never restyles the admin, and vice versa.
- Only themes registered for a surface can be selected or persisted; a stale or invalid stored value falls back to the surface default (
nanawallpublic,adminadmin) instead of breaking rendering. - Deleting a theme file whose slug is still stored is safe — resolution falls back to the surface default on the next request.
To add a new theme to the pickers, see Theming reference.
A/B-testing a presentation (theme + layout)
Instead of applying one theme/layout to everyone, you can split visitors between two or more presentation variants and promote the one that converts best — no rebuild or deploy. This reuses the same A/B experiment surface as persona-path (track) experiments; a presentation experiment just splits on the theme + layout a visitor sees rather than on their track.
Steps
- Open Admin → Experiments (
/admin/experiments) and click New experiment. - Under What to test, choose Presentation (theme & layout). (The subject is fixed once the experiment is created.)
- Add at least two variants. Each variant is a theme + layout combination; mark one as the control (the baseline the others are measured against). Each theme/layout combination may appear only once. Traffic is split evenly.
- Set the goal metric and the guardrails (minimum sample size per variant and minimum runtime), then Create draft experiment.
- On the detail screen, Start the experiment. Only one experiment (of any kind) may run at a time, so stop a running one first.
While it runs
- Every genuine-human visitor is assigned a sticky variant — the same visitor always sees the same theme/layout across sessions — and the public surface serves that variant's theme + layout (overriding the admin default above).
- The assignment respects the visitor's consent tier: it is keyed on the recognized cross-visit id where marketing consent allows, otherwise the functional session cookie. No variant dimension is recorded for a visitor below the measurement tier.
- The Results table shows each variant's reach and goal-metric rate, the lift vs control, and the two-proportion significance test — the same readout as a track experiment, keyed per variant.
Promoting the winner
- Once the guardrails are met and a variant wins, click Promote on that arm.
- Promotion writes the winning variant's theme and layout as the public defaults (the same
app_settingsthe Themes page sets), so once the experiment stops running the whole audience is served the winning presentation — with no code change.
Behavior guarantees
- A presentation experiment never changes a visitor's track attribution — it only changes what they see. Track experiments and presentation experiments are mutually exclusive (one running experiment at a time).
- Only themes/layouts registered for the public surface can be chosen as arms or promoted; a variant whose theme/layout was later removed cannot be promoted.
- If no presentation experiment is running, the public surface serves the admin default theme/layout exactly as before.