Merge pull request #6983 from coollabsio/andrasbacsai/fix-dark-mode-flicker

Fix dark mode white screen flicker on page transitions
This commit is contained in:
Andras Bacsai 2025-10-24 13:18:39 +02:00 committed by GitHub
commit 340006db75
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 35 additions and 21 deletions

View file

@ -1,11 +1,19 @@
<!DOCTYPE html>
<html data-theme="dark" lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<script>
// Immediate theme application - runs before any rendering
(function() {
const t = localStorage.theme || 'dark';
const d = t === 'dark' || (t === 'system' && matchMedia('(prefers-color-scheme: dark)').matches);
document.documentElement.classList[d ? 'add' : 'remove']('dark');
})();
</script>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="robots" content="noindex">
<meta name="theme-color" content="#ffffff" />
<meta name="theme-color" content="#101010" id="theme-color-meta" />
<meta name="color-scheme" content="dark light" />
<meta name="Description" content="Coolify: An open-source & self-hostable Heroku / Netlify / Vercel alternative" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<meta name="twitter:card" content="summary_large_image" />
@ -41,6 +49,12 @@
@endenv
<meta name="csrf-token" content="{{ csrf_token() }}">
@vite(['resources/js/app.js', 'resources/css/app.css'])
<script>
// Update theme-color meta tag (non-critical, can run async)
const t = localStorage.theme || 'dark';
const isDark = t === 'dark' || (t === 'system' && matchMedia('(prefers-color-scheme: dark)').matches);
document.getElementById('theme-color-meta')?.setAttribute('content', isDark ? '#101010' : '#ffffff');
</script>
<style>
[x-cloak] {
display: none !important;
@ -108,7 +122,7 @@
}
});
}
// Existing link sanitization
if (node.nodeName === 'A' && node.hasAttribute('href')) {
const href = node.getAttribute('href') || '';
@ -123,20 +137,11 @@
return DOMPurify.sanitize(html, config);
};
// Initialize theme if not set
if (!('theme' in localStorage)) {
localStorage.theme = 'dark';
document.documentElement.classList.add('dark')
} else if (localStorage.theme === 'dark') {
document.documentElement.classList.add('dark')
} else if (localStorage.theme === 'light') {
document.documentElement.classList.remove('dark')
} else {
if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
document.documentElement.classList.add('dark')
} else {
document.documentElement.classList.remove('dark')
}
}
let theme = localStorage.theme
let cpuColor = '#1e90ff'
let ramColor = '#00ced1'

View file

@ -49,21 +49,30 @@
localStorage.setItem('theme', userSettings);
const themeMetaTag = document.querySelector('meta[name=theme-color]');
let isDark = false;
if (userSettings === 'dark') {
document.documentElement.classList.add('dark');
themeMetaTag.setAttribute('content', this.darkColorContent);
this.theme = 'dark';
isDark = true;
} else if (userSettings === 'light') {
document.documentElement.classList.remove('dark');
themeMetaTag.setAttribute('content', this.whiteColorContent);
this.theme = 'light';
} else if (darkModePreference) {
isDark = false;
} else if (userSettings === 'system') {
this.theme = 'system';
document.documentElement.classList.add('dark');
} else if (!darkModePreference) {
this.theme = 'system';
document.documentElement.classList.remove('dark');
if (darkModePreference) {
document.documentElement.classList.add('dark');
isDark = true;
} else {
document.documentElement.classList.remove('dark');
isDark = false;
}
}
// Update theme-color meta tag
if (themeMetaTag) {
themeMetaTag.setAttribute('content', isDark ? '#101010' : '#ffffff');
}
},
mounted() {