<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Nutchapon Makelai</title>
    <description>The latest articles on DEV Community by Nutchapon Makelai (@nnutnonn).</description>
    <link>https://dev.to/nnutnonn</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F941487%2Fb38b67dd-acb8-41e5-acae-b7dcd0a12917.png</url>
      <title>DEV Community: Nutchapon Makelai</title>
      <link>https://dev.to/nnutnonn</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/nnutnonn"/>
    <language>en</language>
    <item>
      <title>Stop flickering theme after page refresh in Sveltekit and Daisy UI</title>
      <dc:creator>Nutchapon Makelai</dc:creator>
      <pubDate>Tue, 14 Nov 2023 09:39:19 +0000</pubDate>
      <link>https://dev.to/nnutnonn/stop-flickering-theme-after-page-refresh-in-sveltekit-and-daisy-ui-2i74</link>
      <guid>https://dev.to/nnutnonn/stop-flickering-theme-after-page-refresh-in-sveltekit-and-daisy-ui-2i74</guid>
      <description>&lt;p&gt;Hi, Sveltian today I would like to share you how to stop theme flickering after we refreshing a page while we using &lt;a href="https://daisyui.com/" rel="noopener noreferrer"&gt;&lt;strong&gt;Daisy UI&lt;/strong&gt;&lt;/a&gt; with &lt;a href="https://kit.svelte.dev/" rel="noopener noreferrer"&gt;&lt;strong&gt;Sveltekit&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  New in Daisy UI 4.0
&lt;/h2&gt;

&lt;p&gt;Now with Daisy UI 4.0 has been release with new component call &lt;a href="https://daisyui.com/components/theme-controller/" rel="noopener noreferrer"&gt;&lt;strong&gt;Theme Controller&lt;/strong&gt;&lt;/a&gt; it bring us to a more easier way to change between two theme in Daisy UI , for more info about what change and what new  in Daisy UI 4.0 let check this &lt;a href="https://daisyui.com/docs/changelog/#400-2023-11-12" rel="noopener noreferrer"&gt;&lt;strong&gt;link&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Let see what Theme Controller can do
&lt;/h2&gt;

&lt;p&gt;Now I expected you has been installing a new Sveltekit project (with a Skeleton Project option selected) &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvpj0ym1fz59dgrzyk210.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvpj0ym1fz59dgrzyk210.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Tailwind CSS and Daisy UI , then we will starting our code&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;checking you tailwind.config.js , need to have at least 2 of any themes (&lt;a href="https://daisyui.com/docs/themes/" rel="noopener noreferrer"&gt;how to setup themes&lt;/a&gt;) &lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;I have set 2 customize theme name '&lt;strong&gt;light&lt;/strong&gt;' and '&lt;strong&gt;dark&lt;/strong&gt;'&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsowec8uu77i8zr65je31.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsowec8uu77i8zr65je31.png" alt="theme name '**light**' and '**dark**'"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;adding attribute &lt;code&gt;data-theme&lt;/code&gt; on &lt;code&gt;html&lt;/code&gt; tag in &lt;code&gt;src/app.html&lt;/code&gt; page&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;for me will set it as '&lt;strong&gt;light&lt;/strong&gt;' theme by default while page is loaded&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9orby2z0i0hayriy8xlv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9orby2z0i0hayriy8xlv.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;build svelte component name 'ModeSwitcher' (this name is up to your decide) and in that svelte component put below code into it and using this component on &lt;code&gt;+layout.svelte&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;I has using  &lt;a href="https://daisyui.com/components/theme-controller/#theme-controller-using-a-swap" rel="noopener noreferrer"&gt;Theme Controller using a swap component&lt;/a&gt; from DaisyUI and set it value to 'dark' as it is my dark mode theme name&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;label class="swap swap-rotate"&amp;gt;
    &amp;lt;!-- this hidden checkbox controls the state --&amp;gt;
    &amp;lt;input
        type="checkbox"
        class="theme-controller"
        value="dark"
    /&amp;gt;

    &amp;lt;!-- sun icon --&amp;gt;
    &amp;lt;svg class="swap-on fill-current w-10 h-10" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"&amp;gt;
        &amp;lt;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" /&amp;gt;
    &amp;lt;/svg&amp;gt;

    &amp;lt;!-- moon icon --&amp;gt;
    &amp;lt;svg class="swap-off fill-current w-10 h-10" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"&amp;gt;
        &amp;lt;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" /&amp;gt;
    &amp;lt;/svg&amp;gt;
&amp;lt;/label&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;now you can running your dev server and using the that input checkbox (or now it is a sun &amp;amp; moon button) to changing between two themes , for me it will change between theme name '&lt;strong&gt;light&lt;/strong&gt;' and '&lt;strong&gt;dark&lt;/strong&gt;'&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxjterjtsts5wskxtkp0q.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxjterjtsts5wskxtkp0q.gif" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;u&gt;BUT!!&lt;/u&gt;&lt;/strong&gt; you will notice that while we reload or refresh the page from a dark theme it will be reloaded back to a default theme that we has been set in &lt;code&gt;html&lt;/code&gt; tag from previously &lt;/p&gt;




&lt;h2&gt;
  
  
  Made theme persistent
&lt;/h2&gt;

&lt;p&gt;firstly I will introduce you to a basically way to persist a theme by using cookie and &lt;code&gt;onMount&lt;/code&gt; function of svelte if self&lt;/p&gt;

&lt;p&gt;let copy a code below and paste it in your current component&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;script&amp;gt;
    import { onMount } from 'svelte';

    let isDark = false;
    onMount(() =&amp;gt; {
        let decodedCookie = decodeURIComponent(document.cookie);
        let ca = decodedCookie.split(';');
        const cookiesObject = ca.map((cookie) =&amp;gt; {
          const [name, value] = cookie.split('=');
          return { name, value };
        });
        const cookieIsDark = cookiesObject.find(cookie=&amp;gt; cookie.name==='isDark');
        isDark = JSON.parse(cookieIsDark ? cookieIsDark.value : "false") ;
    });


    function setModeCookie() {
        const expirationDate = new Date();
        expirationDate.setDate(expirationDate.getDate() + 365);
        document.cookie = `isDark=${isDark}; expires=${expirationDate.toUTCString()}`;
    }
&amp;lt;/script&amp;gt;

&amp;lt;label class="swap swap-rotate"&amp;gt;
    &amp;lt;!-- this hidden checkbox controls the state --&amp;gt;
    &amp;lt;input
        type="checkbox"
        class="theme-controller"
        value="dark"
    /&amp;gt;

    &amp;lt;!-- sun icon --&amp;gt;
    &amp;lt;svg class="swap-on fill-current w-10 h-10" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"&amp;gt;
        &amp;lt;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" /&amp;gt;
    &amp;lt;/svg&amp;gt;

    &amp;lt;!-- moon icon --&amp;gt;
    &amp;lt;svg class="swap-off fill-current w-10 h-10" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"&amp;gt;
        &amp;lt;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" /&amp;gt;
    &amp;lt;/svg&amp;gt;
&amp;lt;/label&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the code while the component is &lt;code&gt;onMount&lt;/code&gt; state it will decoding and get a value of cookie name 'isDark' that data type is boolean and will tell us the page currently in dark mode or not and it value will binding with &lt;code&gt;input&lt;/code&gt; checked state&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;for a first time it will be set to false because page didn't have any cookie yet&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;and after we changing a theme with our theme controller, it will calling &lt;code&gt;setModeCookie&lt;/code&gt; function that will set a cookie name '&lt;strong&gt;isDark&lt;/strong&gt;' with value of our '&lt;strong&gt;isDark&lt;/strong&gt;' variable (that suppose to be true by now because we clicked a theme controller and change a page's theme to dark)&lt;/p&gt;

&lt;p&gt;now if you try to refresh or reload the page, the theme will be back into a theme that we has been using before we refresh or reload the page&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq7tj7vzvv7svnhtjaxd8.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq7tj7vzvv7svnhtjaxd8.gif" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;u&gt;BUT AGAIN!!&lt;/u&gt;&lt;/strong&gt; you will notice some flickering effect after we refresh or reload the page while on 'dark' theme that because the page will be rendered from server side as a 'light' theme and then after 'onMount' is complete the page will get a cookies and set it back to our theme controller to made the page to be in 'dark' theme again  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd4vgaqs9ly51wphgpqrp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd4vgaqs9ly51wphgpqrp.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Stop theme flickering effect!!!
&lt;/h2&gt;

&lt;p&gt;So far we has been using cookie to set a value that telling us, is currently page is in dark mode or not then in Sveltekit we can accessing that cookie on server side too !! &lt;br&gt;
then what we need to do is we will calling that cookie in server side and passing it value back to our page and the page will rendered on value of that passing from server side&lt;/p&gt;

&lt;p&gt;let create new file in &lt;code&gt;src&lt;/code&gt; folder and name it &lt;code&gt;+layout.server.js&lt;/code&gt; and in that file put below code into it&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/** @type {import('./$types').LayoutServerLoad} */
export async function load({ cookies }) {
    const isDark = cookies.get('isDark') ?? "false";
    return { isDark };
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and put this code below into ModeSwitcher component&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;script&amp;gt;
    import { page } from '$app/stores';

    let isDark = JSON.parse($page.data.isDark);

    function setModeCookie() {
        const expirationDate = new Date();
        expirationDate.setDate(expirationDate.getDate() + 365);
        document.cookie = `isDark=${isDark}; expires=${expirationDate.toUTCString()};`;
    }
&amp;lt;/script&amp;gt;

&amp;lt;label class="swap swap-rotate"&amp;gt;
    &amp;lt;!-- this hidden checkbox controls the state --&amp;gt;
    &amp;lt;input
        type="checkbox"
        class="theme-controller"
        value="dark"
    /&amp;gt;

    &amp;lt;!-- sun icon --&amp;gt;
    &amp;lt;svg class="swap-on fill-current w-10 h-10" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"&amp;gt;
        &amp;lt;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" /&amp;gt;
    &amp;lt;/svg&amp;gt;

    &amp;lt;!-- moon icon --&amp;gt;
    &amp;lt;svg class="swap-off fill-current w-10 h-10" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"&amp;gt;
        &amp;lt;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" /&amp;gt;
    &amp;lt;/svg&amp;gt;
&amp;lt;/label&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;then if you see a code in &lt;code&gt;+layout.server.js&lt;/code&gt; we will try to get a value of cookie with name 'isDark' and if it not exist just passing "false" as a string and made our ModeSwitcher component receiving that value by using   &lt;code&gt;import { page } from '$app/stores';&lt;/code&gt; this will get a store of page that we will need to subscribe and call it data by &lt;code&gt;$page.data.isDark&lt;/code&gt; , last but not less we will set that value back to ModeSwitcher component 's variable name 'isDark' and that variable is got binding on our input checkbox of Theme Controller&lt;/p&gt;

&lt;p&gt;that mean while page is rendered, a 'isDark' value will set into a value of our cookie that passing by server side and then it will rendered to correctly theme that suppose to be show in the page with out flickering effect at all&lt;/p&gt;

</description>
      <category>sveltekit</category>
      <category>svelte</category>
      <category>daisyui</category>
      <category>tailwindcss</category>
    </item>
    <item>
      <title>Deploying Sveltekit on IIS !</title>
      <dc:creator>Nutchapon Makelai</dc:creator>
      <pubDate>Sat, 15 Jul 2023 05:34:23 +0000</pubDate>
      <link>https://dev.to/nnutnonn/deploying-sveltekit-on-iis--5gf6</link>
      <guid>https://dev.to/nnutnonn/deploying-sveltekit-on-iis--5gf6</guid>
      <description>&lt;p&gt;This is will be long article because it a self note for deploying Sveltekit project (as node project) on IIS version 10.&lt;br&gt;
For a while I searching thru the internet and asking in &lt;a href="https://discord.com/invite/svelte"&gt;svelte discord&lt;/a&gt; (so good community , if you're svelter don't miss to join in) I found out it have little information about how to deploying Sveltekit on IIS , may be I've so many conditions and requirements to made Sveltekit project working on my IIS server.&lt;/p&gt;


&lt;h2&gt;
  
  
  Conditions and Requirements
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;running with &lt;u&gt;one&lt;/u&gt; port and separate each project by &lt;u&gt;sub-directory.&lt;/u&gt;&lt;br&gt;
&lt;strong&gt;&lt;u&gt;ex.&lt;/u&gt;&lt;/strong&gt;&lt;br&gt;
projectA ==&amp;gt;  &lt;code&gt;https://my.testsites.com:443/projectA&lt;/code&gt;&lt;br&gt;
projectB ==&amp;gt;  &lt;code&gt;https://my.testsites.com:443/projectB&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Need to be Server side rendering (SSR) which is Sveltekit project &lt;a href="https://kit.svelte.dev/docs/page-options#ssr"&gt;suppose to be&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Any form actions are not blocked by Cross-site Request Forgery (CSRF) &lt;a href="https://kit.svelte.dev/docs/configuration#csrf"&gt;protection of Sveltekit project&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;


&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;express.js on sveltekit project&lt;/li&gt;
&lt;li&gt;node.js (recommend &lt;a href="https://nodejs.org/en"&gt;LTS version&lt;/a&gt;) on IIS server globally install&lt;/li&gt;
&lt;li&gt;some demo Sveltekit project, Let using &lt;a href="https://kit.svelte.dev/docs/creating-a-project"&gt;Sveltekit demo project&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;IIS Services -- &lt;a href="https://www.itechguides.com/how-to-install-iis-in-windows-11/#:~:text=How%20Do%20I%20Enable%20IIS,Then%20click%20the%20OK%20button."&gt;how to install IIS&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;after install IIS&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/Azure/iisnode"&gt;iisnode &lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.iis.net/downloads/microsoft/url-rewrite"&gt;urlrewrite&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  How to step by step
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;run &lt;code&gt;npm i&lt;/code&gt; in your sveltekit project folder&lt;/li&gt;
&lt;li&gt;installing additional dependencies

&lt;ul&gt;
&lt;li&gt;adapter-node for sveltekit &lt;code&gt;npm i -D @sveltejs/adapter-node&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;dotenv &lt;code&gt;npm i dotenv&lt;/code&gt; &lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;setup &lt;code&gt;.env&lt;/code&gt; file in your root folder of your project and put this in your &lt;code&gt;.env&lt;/code&gt; file
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ORIGIN=http://localhost:PORT_OF_SITES
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;while &lt;code&gt;PORT_OF_SITES&lt;/code&gt; will be your port number of IIS site you want to deploy to let say it is 443 then it will be&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ORIGIN=http://localhost:443
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;this will be using after we have deploy Svletekit project to IIS and prevent CSRF blocked after any form actions&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In root folder of your project find &lt;code&gt;svelte.config.js&lt;/code&gt; and adding adapter-node and set base path to made it support a sub-directory in Sveltekit, let change all code inside like this
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import adapter from '@sveltejs/adapter-node';

export default {
    kit: {
        adapter: adapter(),
        paths: {
            relative: false,
            base: '/NAME_OF_SUB-DIRECTORY'
        }
    }
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;while &lt;code&gt;NAME_OF_SUB-DIRECTORY&lt;/code&gt; will specifies where your app is served from and allows the app to live on a non-root path&lt;br&gt;
&lt;strong&gt;&lt;u&gt;ex.&lt;/u&gt;&lt;/strong&gt; you want your site address like &lt;code&gt;https://my.sites.com/svelteiis&lt;/code&gt;  then &lt;code&gt;svelte.config.js&lt;/code&gt; code will be like this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import adapter from '@sveltejs/adapter-node';

export default {
    kit: {
        adapter: adapter(),
        paths: {
            relative: false,
            base: '/svelteiis'
        }
    }
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;after we adding adapter-node and adding base path we need to prepend all root-relative links with the &lt;code&gt;base&lt;/code&gt; value &lt;em&gt;&lt;u&gt;or they will point to the root of your domain, not your &lt;code&gt;base&lt;/code&gt; path&lt;/u&gt;&lt;/em&gt; (&lt;a href="https://kit.svelte.dev/docs/configuration#paths"&gt;this is how the Sveltekit and browser work&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;in &lt;code&gt;src\routes\Header.svelte&lt;/code&gt;, &lt;code&gt;src\routes\about\+page.svelte&lt;/code&gt; and  &lt;code&gt;src\routes\sverdle\+page.svelte&lt;/code&gt; we will adding &lt;code&gt;import { base } from '$app/paths';&lt;/code&gt; in &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; tag and adding every &lt;code&gt;&amp;lt;a&amp;gt;&lt;/code&gt; tag with &lt;code&gt;{base}&lt;/code&gt;&lt;br&gt;
&lt;strong&gt;&lt;u&gt;ex.&lt;/u&gt;&lt;/strong&gt; &lt;code&gt;&amp;lt;a href="{base}/"&amp;gt;Home&amp;lt;/a&amp;gt;&lt;/code&gt;, &lt;code&gt;{base}/about"&amp;gt;About&amp;lt;/a&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;next we will build our project as a node project by using &lt;code&gt;npm run build&lt;/code&gt; and let adapter-node handle it's job . . . . . after some times you will have a &lt;code&gt;build&lt;/code&gt; folder appear in your root project like image below&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--IZ6QqQYr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m8sx7x2d96bkbxit8yc0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--IZ6QqQYr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m8sx7x2d96bkbxit8yc0.png" alt=" raw `build` endraw  folder" width="559" height="554"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;let change side to config our IIS , firstly open our IIS and on your left pane just opening till you seen &lt;code&gt;Default Web Site&lt;/code&gt; just right click on it and click &lt;code&gt;explore&lt;/code&gt; like image below&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Tct8PWoK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gausgmc731f8odytfgyj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Tct8PWoK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gausgmc731f8odytfgyj.png" alt="explore a Default Web Site in IIS" width="405" height="564"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;-it will open a new window of file explorer with path &lt;code&gt;C:\inetpub\wwwroot&lt;/code&gt;(let note this as a &lt;code&gt;wwwroot&lt;/code&gt; folder) after that you can copy a &lt;code&gt;build&lt;/code&gt; folder that we has created earlier in our Sveltekit project folder and let changing it name form &lt;code&gt;build&lt;/code&gt; to a name of what your sub-directory you want &lt;em&gt;&lt;u&gt;that will match with &lt;code&gt;base&lt;/code&gt; path that we config earlier&lt;/u&gt;&lt;/em&gt; or it cause some issue on navigating to your site!&lt;br&gt;
after this step your &lt;code&gt;wwwroot&lt;/code&gt; folder will be like image below&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ROMsNJkC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/71fs7rpo0zcsv8ogj4of.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ROMsNJkC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/71fs7rpo0zcsv8ogj4of.png" alt="wwwroot folder" width="800" height="315"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;**you can deploy your project on new IIS site too by creating a new site in IIS and set physicals path to your deploy folder and bring your &lt;code&gt;build&lt;/code&gt; folder into there and following the step by changing &lt;code&gt;build&lt;/code&gt; folder name.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;next we need to copy 2 files form your root project folder, that is &lt;code&gt;.env&lt;/code&gt; file and &lt;code&gt;package.json&lt;/code&gt; file and bring it to your deploying folder in &lt;code&gt;wwwroot&lt;/code&gt; and running just &lt;code&gt;npm i --omit=dev&lt;/code&gt; in this folder to made node downloading only required dependencies
after running npm creating new &lt;code&gt;web.config&lt;/code&gt; file and adding this code into your &lt;code&gt;web.config&lt;/code&gt; file
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;
&amp;lt;configuration&amp;gt;
  &amp;lt;system.webServer&amp;gt;
    &amp;lt;webSocket enabled="false" /&amp;gt;
    &amp;lt;handlers&amp;gt;
      &amp;lt;add name="iisnode" path="server.cjs" verb="*" modules="iisnode" /&amp;gt;
    &amp;lt;/handlers&amp;gt;
    &amp;lt;iisnode node_env="production" nodeProcessCommandLine="C:\Program Files\nodejs\node.exe" /&amp;gt;
    &amp;lt;rewrite&amp;gt; 
        &amp;lt;rules&amp;gt;             
            &amp;lt;rule name="NodeInspector" patternSyntax="ECMAScript" stopProcessing="true"&amp;gt;
                &amp;lt;match url="^server.cjs\/debug[\/]?" /&amp;gt;
                &amp;lt;conditions logicalGrouping="MatchAll" trackAllCaptures="false" /&amp;gt;
            &amp;lt;/rule&amp;gt;

            &amp;lt;rule name="StaticContent"&amp;gt;
                &amp;lt;conditions logicalGrouping="MatchAll" trackAllCaptures="false" /&amp;gt;
                &amp;lt;action type="Rewrite" url="public{PATH_INFO}" /&amp;gt;
            &amp;lt;/rule&amp;gt;

            &amp;lt;rule name="DynamicContent"&amp;gt;
                &amp;lt;conditions logicalGrouping="MatchAll" trackAllCaptures="false"&amp;gt;
                    &amp;lt;add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" /&amp;gt;
                &amp;lt;/conditions&amp;gt;
                &amp;lt;action type="Rewrite" url="server.cjs" /&amp;gt;
            &amp;lt;/rule&amp;gt; 
        &amp;lt;/rules&amp;gt;
        &amp;lt;outboundRules&amp;gt;
            &amp;lt;rule name="back"&amp;gt;
                &amp;lt;match serverVariable="RESPONSE_Location" pattern="(.*)/server.cjs" /&amp;gt;
                &amp;lt;action type="Rewrite" value="{R:1}" /&amp;gt;
            &amp;lt;/rule&amp;gt;
        &amp;lt;/outboundRules&amp;gt;
    &amp;lt;/rewrite&amp;gt;  
    &amp;lt;defaultDocument&amp;gt;
        &amp;lt;files&amp;gt;
            &amp;lt;add value="server.cjs" /&amp;gt;
        &amp;lt;/files&amp;gt;
    &amp;lt;/defaultDocument&amp;gt;
    &amp;lt;security&amp;gt;
      &amp;lt;requestFiltering&amp;gt;
        &amp;lt;hiddenSegments&amp;gt;
          &amp;lt;remove segment="bin" /&amp;gt;
        &amp;lt;/hiddenSegments&amp;gt;
        &amp;lt;requestLimits maxAllowedContentLength="4294967295" /&amp;gt;
      &amp;lt;/requestFiltering&amp;gt;
    &amp;lt;/security&amp;gt;
    &amp;lt;httpErrors existingResponse="PassThrough" /&amp;gt;
  &amp;lt;/system.webServer&amp;gt;
&amp;lt;/configuration&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;after this config your Sveltekit deploy folder will be like a image below &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_yUPc1OW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/15yjgfv1e6vltlaqnvvz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_yUPc1OW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/15yjgfv1e6vltlaqnvvz.png" alt="in project deploy folder" width="800" height="497"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;last but not least we need to have some JavaScript file that will be running after iisnode calling to our project , that made our project can adjust some environment setting
let create a new file name &lt;code&gt;server.cjs&lt;/code&gt; or any other name but if you change the name you need to put that name into a &lt;code&gt;web.config&lt;/code&gt; file from earlier (try search and replace &lt;code&gt;server.cjs&lt;/code&gt; with your new file's name in &lt;code&gt;web.config&lt;/code&gt;)
after creating a &lt;code&gt;server.cjs&lt;/code&gt; file add this code below to your file
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;require('dotenv').config();
const express = require('express')

import('./handler.js')
    .then((handler) =&amp;gt; {
        const app = express();
        // Custom middleware to make routing case-insensitive
        app.use((req, res, next) =&amp;gt; {
            const urlSegments = req.url.split('/');
            urlSegments[1] = urlSegments[1].toLowerCase();
            req.url = urlSegments.join('/');
            next();
        });

        // let SvelteKit handle everything else, including serving prerendered pages and static assets
        app.use(handler.handler);

        app.listen(process.env.PORT, () =&amp;gt; {
            console.log(
                'app start on port ' + process.env.PORT
            );
        });

    }).catch((err) =&amp;gt; console.error(err));
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;this will made your &lt;code&gt;.env&lt;/code&gt; file that you copying from earlier working as aspect and will set your origin of project to prevent CSRF protection from a form actions of the project itself and it will made your site can accessing with case insensitive url at a first sub-directory.&lt;br&gt;
by the way you can disabled case insensitive by comment out below code in server.cjs&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;app.use((req, res, next) =&amp;gt; {
            const urlSegments = req.url.split('/');
            urlSegments[1] = urlSegments[1].toLowerCase();
            req.url = urlSegments.join('/');
            next();
        }); 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;now inside the project folder in &lt;code&gt;wwwroot&lt;/code&gt; will look like this&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--3fm-KxEa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/th11dgdw43ycyke0wb4f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--3fm-KxEa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/th11dgdw43ycyke0wb4f.png" alt="Image description" width="800" height="519"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;after that you can try going to the site that you have deploy by go to &lt;br&gt;
&lt;code&gt;http://localhost/NAME_OF_SUB-DIRECTORY&lt;/code&gt; or &lt;code&gt;http://localhost:YOUR_IIS_PORT/NAME_OF_SUB-DIRECTORY&lt;/code&gt; &lt;br&gt;
and finally you has achieved Sveltekit deploying on IIS !&lt;/p&gt;




&lt;p&gt;If you has any question or suggestion on my walkthrough feel free to giving me a comment below. ;)&lt;/p&gt;

&lt;p&gt;Thanks you&lt;br&gt;
Have a nice day and keep coding&lt;/p&gt;

</description>
      <category>svelte</category>
      <category>javascript</category>
      <category>iis</category>
      <category>sveltekit</category>
    </item>
  </channel>
</rss>
