Skip to content

goobits/theme-engine

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

111 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

@goobits/themes

Theme management for SvelteKit applications with Svelte 5 runes support.

Features

  • Light, dark, and system theme modes with zero-flash SSR
  • Custom color schemes with extensible configuration
  • Reactive theme state using Svelte 5 runes
  • Namespaced local-storage and cookie persistence
  • Fixed light/dark schemes and one-step legacy scheme migration
  • Route-specific theme overrides

Quick Start

1. Install

npm install @goobits/themes

2. Create configsrc/lib/config/theme.ts

import { createThemeConfig } from '@goobits/themes/core';

export const themeConfig = createThemeConfig({
    schemes: {
        default: {}, // All fields optional!
        dark: { displayName: 'Dark Mode', fixedMode: 'dark' },
    },
    defaultMode: 'system',
    defaultScheme: 'default',
    persistence: {
        storageKey: 'my-app-theme',
        themeCookie: 'my-app-theme-mode',
        schemeCookie: 'my-app-theme-scheme',
    },
});

3. Add server hookssrc/hooks.server.ts

import { createThemeHooks } from '@goobits/themes/server';
import { themeConfig } from '$lib/config/theme';

export const handle = createThemeHooks(themeConfig, {
    blockingScript: true
}).transform;

4. Add layout loadersrc/routes/+layout.server.ts

export function load({ locals }) {
    return { preferences: locals.themePreferences };
}

5. Update HTMLsrc/app.html

<html lang="en" class="%sveltekit.theme%"></html>

6. Wrap your appsrc/routes/+layout.svelte

<script>
    import { ThemeProvider } from '@goobits/themes/svelte';
    import { themeConfig } from '$lib/config/theme';
    import '@goobits/themes/themes/bundle.css';

    const { children, data } = $props();
</script>

<ThemeProvider
    config={themeConfig}
    serverPreferences={data.preferences}
>
    {@render children?.()}
</ThemeProvider>

Optional: Goo presets + SSR helpers

<script>
    import '@goobits/themes/themes/goo/bundle.css';
</script>
import { generateBlockingThemeScript } from '@goobits/themes/server/goo';

7. Add controls (optional)

<script>
    import { ThemeToggle, SchemeSelector } from '@goobits/themes/svelte';
</script>

<ThemeToggle />
<SchemeSelector />

That's it! See Getting Started for FOUC prevention and custom themes.

Documentation

Guide Description
Getting Started Full setup with FOUC prevention
API Reference Complete API documentation
Components Built-in components and hooks
Custom Themes Create your own color schemes
Troubleshooting Common issues and solutions

CSS Structure

The theme engine applies classes and attributes to <html>:

/* Target by attribute (recommended) */
[data-theme='dark'] {
    --bg: #000;
}
[data-theme='light'] {
    --bg: #fff;
}

/* Target by class (for system vs explicit) */
.theme-dark {
    /* explicit dark */
}
.theme-system-dark {
    /* system detected dark */
}

/* Scheme-specific */
.scheme-spells {
    --accent: #7c3aed;
}

data-theme always contains the resolved light or dark mode. Scheme identity belongs exclusively in .scheme-* classes.

For a one-time migration from an older local-storage value that contained only a scheme ID, configure legacySchemeStorageKey and optional schemeAliases. The blocking script canonicalizes the value before paint and removes the old key after the new preference is saved.

License

MIT

About

No description, website, or topics provided.

Resources

Contributing

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages