Skip to content

fix(theming): allow request theme override#61095

Open
giacomoarru wants to merge 3 commits into
nextcloud:masterfrom
giacomoarru:fix/theme-querystring
Open

fix(theming): allow request theme override#61095
giacomoarru wants to merge 3 commits into
nextcloud:masterfrom
giacomoarru:fix/theme-querystring

Conversation

@giacomoarru

Copy link
Copy Markdown

Summary

Adds a request-scoped query string override for light/dark theming:

  • ?theme=light
  • ?theme=dark

The override is not persisted to the user's settings.

Details

  • Accepts only light and dark.
  • Ignores invalid and non-string values.
  • Preserves enabled themes of other types, such as OpenDyslexic.
  • Keeps admin-configured enforce_theme behavior unchanged.
  • Leaves getThemes() unchanged; the override is applied only in getEnabledThemes().

Testing

  • php -l apps/theming/lib/Service/ThemesService.php
  • php -l apps/theming/tests/Service/ThemesServiceTest.php
  • composer test -- apps/theming/tests/Service/ThemesServiceTest.php

Manual testing

  • Opened /login?theme=dark and verified data-theme-dark.
  • Opened /login?theme=light and verified data-theme-light.
  • Opened /login?theme=sepia and verified no override is applied.

@giacomoarru giacomoarru requested a review from a team as a code owner June 9, 2026 08:55
@giacomoarru giacomoarru requested review from come-nc, leftybournes, provokateurin and salmart-dev and removed request for a team June 9, 2026 08:55
@giacomoarru

Copy link
Copy Markdown
Author

Justification

This pull request introduces a query string override to control the visual theme of embedded Nextcloud Forms.

The main use case is embedding public forms inside external websites via iframe. In this scenario, the surrounding website may have a fixed light design, while the embedded Nextcloud form can automatically switch to dark mode depending on the visitor’s device or browser preference, for example when the user has system-wide dark mode enabled.

This creates an inconsistent user experience: the external page remains white, but the embedded form is rendered with a dark background. In some cases, this also affects readability, branding consistency, and accessibility, especially when the form is intended to visually integrate with a light-themed public website.

A global configuration such as forcing the whole Nextcloud instance to light mode is not a suitable solution, because administrators may still want the rest of Nextcloud to respect user preferences or system theme settings. Similarly, applying custom CSS globally can have unintended side effects on other forms or other parts of the instance.

The proposed query string override solves this in a narrow and explicit way. It allows the embedding page to request a specific theme only for that embedded form view, without changing the global Nextcloud theme behavior and without affecting other users, other forms, or the rest of the instance.

Example use case:

<iframe
  src="https://cloud.example.com/index.php/apps/forms/embed/FORM_ID?theme=light"
  style="width:100%; border:0;">
</iframe>

This makes embedding Nextcloud Forms in external websites more predictable and easier to integrate, while preserving the existing default behavior when no override is provided.

The change is especially useful for organizations that use Nextcloud Forms as part of public-facing websites, intranets, landing pages, or customer portals where the visual appearance of the embedded form needs to match the host page.

Support ?theme=light and ?theme=dark as a request-scoped override that is
not persisted to user settings and never bypasses an admin-configured
enforce_theme. Invalid, empty, non-string or unknown values are ignored,
and non-visual themes such as the OpenDyslexic font theme are preserved.
The override is applied only in ThemesService::getEnabledThemes() so that
getThemes() and theme registration remain unchanged.

Assisted-by: Cline
Signed-off-by: Jack Arru <giacomo@beta.srl>
@giacomoarru giacomoarru force-pushed the fix/theme-querystring branch from b816150 to b7ca7d0 Compare June 9, 2026 09:34
The request-scoped ?theme=light / ?theme=dark override set the
data-theme-* body attribute but ThemeInjectionService still injected the
OS prefers-color-scheme stylesheets on :root and a combined color-scheme
meta. On a dark-OS machine the root element and native controls stayed
dark, so the override appeared not to work.

When an override is active (and no enforce_theme is set), force the
chosen theme unconditionally on :root, drop the prefers-color-scheme
auto-switching stylesheets, and expose only the override color-scheme
meta. Behavior without an override and admin enforce_theme precedence are
unchanged.

Assisted-by: Cline
Signed-off-by: Jack Arru <giacomo@beta.srl>
@susnux susnux added this to the Nextcloud 35 milestone Jun 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants