fix(theming): allow request theme override#61095
Conversation
JustificationThis 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>
b816150 to
b7ca7d0
Compare
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>
Summary
Adds a request-scoped query string override for light/dark theming:
?theme=light?theme=darkThe override is not persisted to the user's settings.
Details
lightanddark.enforce_themebehavior unchanged.getThemes()unchanged; the override is applied only ingetEnabledThemes().Testing
php -l apps/theming/lib/Service/ThemesService.phpphp -l apps/theming/tests/Service/ThemesServiceTest.phpcomposer test -- apps/theming/tests/Service/ThemesServiceTest.phpManual testing
/login?theme=darkand verifieddata-theme-dark./login?theme=lightand verifieddata-theme-light./login?theme=sepiaand verified no override is applied.