Hello, Sveltian at this time I wish to share you the right way to cease theme flickering after we refreshing a web page whereas we utilizing Daisy UI with Sveltekit
New in Daisy UI 4.0
Now with Daisy UI 4.0 has been launch with new part name Theme Controller it deliver us to a extra simpler option to change between two theme in Daisy UI , for more information about what change and what new in Daisy UI 4.0 let test this link
Let see what Theme Controller can do
Now I anticipated you has been putting in a brand new Sveltekit undertaking (with a Skeleton Mission possibility chosen)
Tailwind CSS and Daisy UI , then we are going to beginning our code
I’ve set 2 customise theme identify ‘mild‘ and ‘darkish‘
- including attribute
data-theme
onhtml
tag insrc/app.html
web page
for me will set it as ‘mild‘ theme by default whereas web page is loaded
- construct svelte part identify ‘ModeSwitcher’ (this identify is as much as your resolve) and in that svelte part put beneath code into it and utilizing this part on
+format.svelte
I has utilizing Theme Controller using a swap component from DaisyUI and set it worth to ‘darkish’ as it’s my darkish mode theme identify
<label class="swap swap-rotate">
<!-- this hidden checkbox controls the state -->
<enter
sort="checkbox"
class="theme-controller"
worth="darkish"
/>
<!-- solar icon -->
<svg class="swap-on fill-current w-10 h-10" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<path d="M5.64,17l-.71.71a1,1,0,0,0,0,1.41,1,1,0,0,0,1.41,0l.71-.71A1,1,0,0,0,5.64,17ZM5,12a1,1,0,0,0-1-1H3a1,1,0,0,0,0,2H4A1,1,0,0,0,5,12Zm7-7a1,1,0,0,0,1-1V3a1,1,0,0,0-2,0V4A1,1,0,0,0,12,5ZM5.64,7.05a1,1,0,0,0,.7.29,1,1,0,0,0,.71-.29,1,1,0,0,0,0-1.41l-.71-.71A1,1,0,0,0,4.93,6.34Zm12,.29a1,1,0,0,0,.7-.29l.71-.71a1,1,0,1,0-1.41-1.41L17,5.64a1,1,0,0,0,0,1.41A1,1,0,0,0,17.66,7.34ZM21,11H20a1,1,0,0,0,0,2h1a1,1,0,0,0,0-2Zm-9,8a1,1,0,0,0-1,1v1a1,1,0,0,0,2,0V20A1,1,0,0,0,12,19ZM18.36,17A1,1,0,0,0,17,18.36l.71.71a1,1,0,0,0,1.41,0,1,1,0,0,0,0-1.41ZM12,6.5A5.5,5.5,0,1,0,17.5,12,5.51,5.51,0,0,0,12,6.5Zm0,9A3.5,3.5,0,1,1,15.5,12,3.5,3.5,0,0,1,12,15.5Z" />
</svg>
<!-- moon icon -->
<svg class="swap-off fill-current w-10 h-10" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<path d="M21.64,13a1,1,0,0,0-1.05-.14,8.05,8.05,0,0,1-3.37.73A8.15,8.15,0,0,1,9.08,5.49a8.59,8.59,0,0,1,.25-2A1,1,0,0,0,8,2.36,10.14,10.14,0,1,0,22,14.05,1,1,0,0,0,21.64,13Zm-9.5,6.69A8.14,8.14,0,0,1,7.08,5.22v.27A10.15,10.15,0,0,0,17.22,15.63a9.79,9.79,0,0,0,2.1-.22A8.11,8.11,0,0,1,12.14,19.73Z" />
</svg>
</label>
now you may operating your dev server and utilizing the that enter checkbox (or now it’s a solar & moon button) to altering between two themes , for me it is going to change between theme identify ‘mild‘ and ‘darkish‘
BUT!! you’ll discover that whereas we reload or refresh the web page from a darkish theme will probably be reloaded again to a default theme that we has been set in html
tag from beforehand
Made theme persistent
firstly I’ll introduce you to a principally option to persist a theme through the use of cookie and onMount
operate of svelte if self
let copy a code beneath and paste it in your present part
<script>
import { onMount } from 'svelte';
let isDark = false;
onMount(() => {
let decodedCookie = decodeURIComponent(doc.cookie);
let ca = decodedCookie.break up(';');
const cookiesObject = ca.map((cookie) => {
const [name, value] = cookie.break up('=');
return { identify, worth };
});
const cookieIsDark = cookiesObject.discover(cookie=> cookie.identify==='isDark');
isDark = JSON.parse(cookieIsDark ? cookieIsDark.worth : "false") ;
});
operate setModeCookie() {
const expirationDate = new Date();
expirationDate.setDate(expirationDate.getDate() + 365);
doc.cookie = `isDark=${isDark}; expires=${expirationDate.toUTCString()}`;
}
</script>
<label class="swap swap-rotate">
<!-- this hidden checkbox controls the state -->
<enter
sort="checkbox"
class="theme-controller"
worth="darkish"
/>
<!-- solar icon -->
<svg class="swap-on fill-current w-10 h-10" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<path d="M5.64,17l-.71.71a1,1,0,0,0,0,1.41,1,1,0,0,0,1.41,0l.71-.71A1,1,0,0,0,5.64,17ZM5,12a1,1,0,0,0-1-1H3a1,1,0,0,0,0,2H4A1,1,0,0,0,5,12Zm7-7a1,1,0,0,0,1-1V3a1,1,0,0,0-2,0V4A1,1,0,0,0,12,5ZM5.64,7.05a1,1,0,0,0,.7.29,1,1,0,0,0,.71-.29,1,1,0,0,0,0-1.41l-.71-.71A1,1,0,0,0,4.93,6.34Zm12,.29a1,1,0,0,0,.7-.29l.71-.71a1,1,0,1,0-1.41-1.41L17,5.64a1,1,0,0,0,0,1.41A1,1,0,0,0,17.66,7.34ZM21,11H20a1,1,0,0,0,0,2h1a1,1,0,0,0,0-2Zm-9,8a1,1,0,0,0-1,1v1a1,1,0,0,0,2,0V20A1,1,0,0,0,12,19ZM18.36,17A1,1,0,0,0,17,18.36l.71.71a1,1,0,0,0,1.41,0,1,1,0,0,0,0-1.41ZM12,6.5A5.5,5.5,0,1,0,17.5,12,5.51,5.51,0,0,0,12,6.5Zm0,9A3.5,3.5,0,1,1,15.5,12,3.5,3.5,0,0,1,12,15.5Z" />
</svg>
<!-- moon icon -->
<svg class="swap-off fill-current w-10 h-10" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<path d="M21.64,13a1,1,0,0,0-1.05-.14,8.05,8.05,0,0,1-3.37.73A8.15,8.15,0,0,1,9.08,5.49a8.59,8.59,0,0,1,.25-2A1,1,0,0,0,8,2.36,10.14,10.14,0,1,0,22,14.05,1,1,0,0,0,21.64,13Zm-9.5,6.69A8.14,8.14,0,0,1,7.08,5.22v.27A10.15,10.15,0,0,0,17.22,15.63a9.79,9.79,0,0,0,2.1-.22A8.11,8.11,0,0,1,12.14,19.73Z" />
</svg>
</label>
Within the code whereas the part is onMount
state it is going to decoding and get a worth of cookie identify ‘isDark’ that knowledge sort is boolean and can inform us the web page at the moment in darkish mode or not and it worth will binding with enter
checked state
for a primary time will probably be set to false as a result of web page did not have any cookie but
and after we altering a theme with our theme controller, it is going to calling setModeCookie
operate that may set a cookie identify ‘isDark‘ with worth of our ‘isDark‘ variable (that suppose to be true by now as a result of we clicked a theme controller and alter a web page’s theme to darkish)
now if you happen to attempt to refresh or reload the web page, the theme might be again right into a theme that we has been utilizing earlier than we refresh or reload the web page
BUT AGAIN!! you’ll discover some flickering impact after we refresh or reload the web page whereas on ‘darkish’ theme that as a result of the web page might be rendered from server aspect as a ‘mild’ theme after which after ‘onMount’ is full the web page will get a cookies and set it again to our theme controller to made the web page to be in ‘darkish’ theme once more
Cease theme flickering impact!!!
To this point we has been utilizing cookie to set a worth that telling us, is at the moment web page is in darkish mode or not then in Sveltekit we are able to accessing that cookie on server aspect too !!
then what we have to do is we are going to calling that cookie in server aspect and passing it worth again to our web page and the web page will rendered on worth of that passing from server aspect
let create new file in src
folder and identify it +format.server.js
and in that file put beneath code into it
/** @sort {import('./$varieties').LayoutServerLoad} */
export async operate load({ cookies }) {
const isDark = cookies.get('isDark') ?? "false";
return { isDark };
}
and put this code beneath into ModeSwitcher part
<script>
import { web page } from '$app/shops';
let isDark = JSON.parse($web page.knowledge.isDark);
operate setModeCookie() {
const expirationDate = new Date();
expirationDate.setDate(expirationDate.getDate() + 365);
doc.cookie = `isDark=${isDark}; expires=${expirationDate.toUTCString()};`;
}
</script>
<label class="swap swap-rotate">
<!-- this hidden checkbox controls the state -->
<enter
sort="checkbox"
class="theme-controller"
worth="darkish"
/>
<!-- solar icon -->
<svg class="swap-on fill-current w-10 h-10" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<path d="M5.64,17l-.71.71a1,1,0,0,0,0,1.41,1,1,0,0,0,1.41,0l.71-.71A1,1,0,0,0,5.64,17ZM5,12a1,1,0,0,0-1-1H3a1,1,0,0,0,0,2H4A1,1,0,0,0,5,12Zm7-7a1,1,0,0,0,1-1V3a1,1,0,0,0-2,0V4A1,1,0,0,0,12,5ZM5.64,7.05a1,1,0,0,0,.7.29,1,1,0,0,0,.71-.29,1,1,0,0,0,0-1.41l-.71-.71A1,1,0,0,0,4.93,6.34Zm12,.29a1,1,0,0,0,.7-.29l.71-.71a1,1,0,1,0-1.41-1.41L17,5.64a1,1,0,0,0,0,1.41A1,1,0,0,0,17.66,7.34ZM21,11H20a1,1,0,0,0,0,2h1a1,1,0,0,0,0-2Zm-9,8a1,1,0,0,0-1,1v1a1,1,0,0,0,2,0V20A1,1,0,0,0,12,19ZM18.36,17A1,1,0,0,0,17,18.36l.71.71a1,1,0,0,0,1.41,0,1,1,0,0,0,0-1.41ZM12,6.5A5.5,5.5,0,1,0,17.5,12,5.51,5.51,0,0,0,12,6.5Zm0,9A3.5,3.5,0,1,1,15.5,12,3.5,3.5,0,0,1,12,15.5Z" />
</svg>
<!-- moon icon -->
<svg class="swap-off fill-current w-10 h-10" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<path d="M21.64,13a1,1,0,0,0-1.05-.14,8.05,8.05,0,0,1-3.37.73A8.15,8.15,0,0,1,9.08,5.49a8.59,8.59,0,0,1,.25-2A1,1,0,0,0,8,2.36,10.14,10.14,0,1,0,22,14.05,1,1,0,0,0,21.64,13Zm-9.5,6.69A8.14,8.14,0,0,1,7.08,5.22v.27A10.15,10.15,0,0,0,17.22,15.63a9.79,9.79,0,0,0,2.1-.22A8.11,8.11,0,0,1,12.14,19.73Z" />
</svg>
</label>
then if you happen to see a code in +format.server.js
we are going to attempt to get a worth of cookie with identify ‘isDark’ and if it not exist simply passing “false” as a string and made our ModeSwitcher part receiving that worth through the use of import { web page } from '$app/shops';
this may get a retailer of web page that we might want to subscribe and name it knowledge by $web page.knowledge.isDark
, final however not much less we are going to set that worth again to ModeSwitcher part ‘s variable identify ‘isDark’ and that variable is bought binding on our enter checkbox of Theme Controller
that imply whereas web page is rendered, a ‘isDark’ worth will set into a worth of our cookie that passing by server aspect after which it is going to rendered to accurately theme that suppose to be present within the web page with out flickering impact in any respect