This project is a SvelteKit starter that demonstrates how to implement a robust color theme solution that persists on the server to prevent a flash of unstyled content (FOUC). It uses a Svelte 5 rune-like class to manage the theme, persisting it to both browser localStorage and a cookie.
localStorage for fast client-side access and a cookie to send the theme to the server.light, dark, and blood themes out of the box.The core of the theme management system is the LocalStorage class located in src/lib/runes/localStorage.svelte.ts. This class is instantiated as a theme object, which is then used throughout the application.
When the theme.value is changed, the LocalStorage class does the following:
window.localStorage.data-theme attribute on the <html> element.The src/hooks.server.ts file contains a handle function that reads the theme cookie on the server and sets event.locals.theme. This makes the theme available to all server-side code.
The actual themes are defined in src/app.css. Each theme is a set of CSS custom properties under a html[data-theme='...'] selector.
The src/lib/Header/ToggleDarkMode.svelte component provides an example of how to use the theme object to change the current theme.
Clone the repository:
git clone https://github.com/WayneMorganUK/sveltekit-color-themes.git
Install the dependencies:
cd sveltekit-color-themes
pnpm install
Run the development server:
pnpm dev
To add a new theme, you need to do the following:
Define the theme in src/app.css:
Add a new selector for your theme and define the CSS custom properties for it. For example, to add a "forest" theme:
html[data-theme='forest'] {
--color-text-base: #f0f0f0;
--color-base: #2a3d2a;
/* ...and so on */
}
Update the theme toggling logic:
In src/lib/Header/ToggleDarkMode.svelte (or wherever you handle theme changes), add your new theme to the rotation.
function changeTheme() {
if (theme.value == 'light') {
theme.value = 'dark';
} else if (theme.value == 'dark') {
theme.value = 'blood';
} else if (theme.value == 'blood') {
theme.value = 'forest'; // Add your new theme here
} else {
theme.value = 'light';
}
}
This project is configured to be deployed to various platforms using SvelteKit adapters. The code includes logic to detect the deployment platform and use the correct adapter.
The following platforms are supported out of the box:
The deployment platform is detected using the following environment variables:
process.env.VERCEL === '1'process.env.NETLIFY === 'TRUE'process.env.CF_PAGES === '1'process.env.CF_WORKERS_CI === '1'netlify.toml.wrangler.jsonc. If you are using pnpm, you may need to change the deploy command in your Cloudflare dashboard from npx wrangler deploy to pnpx wrangler deploy --config ./cf_workers/wrangler.jsonc.wrangler.toml to avoid conflicts with Cloudflare Workers configuration.