Always I reload any page happens a quick flash that changes the entire system to dark mode and comes back again, but really quick.
Before, this was happens also on dark mode too, but I could fix it loading the function that loads the themes on head of the HTML. Therefore, this doesn't work in light mode, and I have no idea why.
We are using Thymeleaf (from Java), idk if it changes anything, and also HTML, Tailwind CSS, and JS. I'm going to put the file code here which is the all pages template that it happens.
(function() {
const docElement = document.documentElement;
const cookieMatch = document.cookie.match(/theme=(dark|light)/);
const savedTheme = cookieMatch ? cookieMatch[1] : null;
const themeToApply = savedTheme || 'light';
if (themeToApply === 'dark') {
docElement.classList.add('dark');
} else {
docElement.classList.remove('dark');
}
if (window.innerWidth >= 1024) {
const sidebarMatch = document.cookie.match(/sidebarState=(true|false)/);
const sidebarOpen = sidebarMatch ? sidebarMatch[1] === 'true' : true;
if (!sidebarOpen) {
docElement.classList.add('sidebar-closed');
} else {
docElement.classList.remove('sidebar-closed');
}
} else {
docElement.classList.add('sidebar-closed');
}
})();
tailwind.config = {
darkMode: 'class',
theme: {
extend: {
// extensões de tema
}
}
}
function layout() {
return {
isSidebarOpen: window.innerWidth >= 1024 ?
!document.documentElement.classList.contains('sidebar-closed') : false,
theme: (document.cookie.match(/theme=(dark|light)/) || [null, 'light'])[1],
oneYearInSeconds: 365 * 24 * 60 * 60,
init() {
this.$watch('theme', (newTheme) => {
if (newTheme === 'dark') {
document.documentElement.classList.add('dark');
} else {
document.documentElement.classList.remove('dark');
}
document.cookie = `theme=${newTheme}; path=/; max-age=${this.oneYearInSeconds}`;
});
this.$watch('isSidebarOpen', (isOpen) => {
if (!isOpen) {
document.documentElement.classList.add('sidebar-closed');
} else {
document.documentElement.classList.remove('sidebar-closed');
}
});
window.addEventListener('resize', () => {
if (window.innerWidth < 1024) {
this.isSidebarOpen = false;
}
});
},
toggleSidebar() {
this.isSidebarOpen = !this.isSidebarOpen;
if (window.innerWidth >= 1024) {
document.cookie = `sidebarState=${this.isSidebarOpen}; path=/; max-age=${this.oneYearInSeconds}`;
}
},
closeSidebarOnMobile() {
if (window.innerWidth < 1024) {
this.isSidebarOpen = false;
}
},
toggleTheme() {
this.theme = (this.theme === 'light' ? 'dark' : 'light');
}
}
}
<script src="https://cdn.tailwindcss.com"></script>
<script defer src="https://cdn.jsdelivr.net/npm/[email protected]/dist/cdn.min.js"></script>
<link href="https://cdn.datatables.net/2.0.8/css/dataTables.tailwindcss.css" rel="stylesheet">
<script src="https://code.jquery.com/jquery-3.7.1.js"></script>
<script src="https://cdn.datatables.net/2.0.8/js/dataTables.js"></script>
<script src="https://cdn.datatables.net/2.0.8/js/dataTables.tailwindcss.js"></script>
<link rel="stylesheet" type="text/css" th:href="@{/css/style.css}" />
<body class="flex flex-col min-h-screen bg-neutral-50 dark:bg-zinc-800 overflow-x-hidden" x-data="layout()">
<header class="w-full z-20 sticky top-0 left-0 right-0 bg-white shadow border-b border-gray-200">
<div th:replace="~{layouts/header :: header}"></div>
</header>
<div class="flex lg:flex-row flex-col">
<div th:replace="~{layouts/sidebar :: sidebar}"></div>
<!-- Overlay para mobile quando sidebar está aberta -->
<div x-show="isSidebarOpen && window.innerWidth < 1024" @click="toggleSidebar()" x-transition:enter="transition-opacity ease-out duration-300" x-transition:enter-start="opacity-0" x-transition:enter-end="opacity-100" x-transition:leave="transition-opacity ease-in duration-200" x-transition:leave-start="opacity-100" x-transition:leave-end="opacity-0" class="fixed inset-0 bg-black bg-opacity-50 z-30 lg:hidden" style="display: none;">
</div>
<div class="flex-1 flex flex-col min-h-0 p-0 pt-6 w-dvw pl-64" :class="{'pl-20': !isSidebarOpen}">
<main class="flex-1 p-0 pt-0 mr-6 ml-8">
<div class="mx-auto mb-6 flex justify-between items-center">
<div th:replace="~{fragments/breadcrumb :: breadcrumb}"></div>
<div class="flex items-center z-20">
<a href="#" class="group flex items-center text-sm font-semibold leading-6">
<span class="mx-2"><svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" class="h-5 w-5 text-neutral-900 dark:text-gray-200"><circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></svg></span>
</a>
<div th:replace="~{fragments/profile_button_thymeleaf :: userProfileDropdown}"></div>
</div>
</div>
<div th:insert="~{this :: content}" th:remove="tag"></div>
<!-- Fixed toast container (top-right) for FlashMessageHelper messages -->
<div class="fixed top-5 right-5 z-50 space-y-2" id="flash-toast-container">
<div th:if="${!#lists.isEmpty(errors)}" th:insert="~{fragments/alert :: messages(${errors})}"></div>
<div th:if="${!#lists.isEmpty(infos)}" th:insert="~{fragments/alert :: messages(${infos})}"></div>
<div th:if="${!#lists.isEmpty(success)}" th:insert="~{fragments/alert :: messages(${success})}"></div>
</div>
</main>
</div>
</div>
<div th:insert="~{this :: scripts}" th:remove="tag"></div>
</body>