fix(favicon): update favicon dynamically based on app theme#4118
Open
mixelburg wants to merge 1 commit intoDokploy:canaryfrom
Open
fix(favicon): update favicon dynamically based on app theme#4118mixelburg wants to merge 1 commit intoDokploy:canaryfrom
mixelburg wants to merge 1 commit intoDokploy:canaryfrom
Conversation
jwchmodx
reviewed
Apr 7, 2026
jwchmodx
left a comment
There was a problem hiding this comment.
Minor: brief favicon flash for whitelabeled deployments
When config is still loading (undefined), faviconHref correctly falls back to the theme-based SVG. However, if the user has a custom faviconUrl set in whitelabeling config, there will be a short flash of the default theme icon before the config loads and overrides it.
This is probably acceptable — the flash is short and the pre-hydration _document.tsx entry already shows an OS-matched icon. Worth noting in case brand consistency is a concern for whitelabeled deployments (e.g. enterprise customers). If it ever becomes a visible issue, one option is caching the faviconUrl in localStorage so it's available before the query resolves.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #4100
The favicon was only responding to the OS-level color scheme via CSS
@media (prefers-color-scheme: dark), not Dokploy's class-based theme (vianext-themes). Toggling the app theme had no effect on the favicon until a page reload.Root cause: The favicon is an external resource (not in the DOM), so it cannot observe
<html class="dark">changes — it only responds to the OS media query.Fix:
Added
icon-light.svgandicon-dark.svgto/public— static variants with explicitfill="black"andfill="white"respectively, with the<style>block removed.Extended
WhitelabelingProviderto inject a<link rel="icon">vianext/headthat reflects the current app theme (resolvedThemefromuseTheme()):faviconUrlfrom white-label config takes precedence/icon-dark.svgin dark mode,/icon-light.svgin light mode/icon.svgwhile theme is resolvingThe original
/icon.svgin_document.tsxstays as the pre-hydration fallback (gives OS-matched favicon before JS loads).Greptile Summary
This PR fixes a bug where Dokploy's favicon only responded to the OS-level color scheme (
prefers-color-schememedia query) and not to the app-level theme managed bynext-themes. Two new static SVG variants are added to/public— one for dark mode (white fill) and one for light mode (black fill) — with the dynamic CSS media query block removed from both.Key changes:
WhitelabelingProvidernow always renders a<link rel="icon">vianext/head, driven byresolvedThemefromuseTheme(), so the favicon updates immediately whenever the user toggles the app theme.nullwhile the whitelabeling config is loading, ensuring theme-aware favicon injection works independently of config fetch state.faviconUrlfrom whitelabeling config continues to take precedence. WhenresolvedThemeisundefined(SSR / before hydration), the fallback is/icon.svg, matching the pre-hydration favicon already set in_document.tsx._document.tsxentry is intentionally preserved as the pre-hydration fallback, and thenext/headentry overrides it in the browser after hydration.Confidence Score: 5/5
Safe to merge — no logic bugs, data integrity issues, or security concerns.
All three changed files are straightforward and correct. The theme-based favicon selection handles all expected states (undefined/SSR, dark, light, custom URL). The pre-hydration fallback in _document.tsx is preserved as intended. No P0 or P1 issues found.
No files require special attention.
Important Files Changed
Reviews (1): Last reviewed commit: "fix(favicon): update favicon dynamically..." | Re-trigger Greptile