SnappSnapp
  • Getting Started
  • Installation
  • Configuration
  • Styling
  • Introduction
  • Custom URLs
  • Authentication
  • Multi-Domain Architecture
  • Team Management
  • Third-Party Integrations
  • Metrics & Analytics
  • API Reference
  • English
  • Italiano
  • Getting Started
  • Installation
  • Configuration
  • Styling
  • Introduction
  • Custom URLs
  • Authentication
  • Multi-Domain Architecture
  • Team Management
  • Third-Party Integrations
  • Metrics & Analytics
  • API Reference
  • English
  • Italiano
  • Guide

    • Getting Started
    • Installation
    • Configuration
    • Styling

Overview

Snapp supports runtime theming through a single CSS file that overrides the application’s design tokens.

There is no rebuild step, no Tailwind recompilation, and no component-level overrides.

Styling is applied by redefining CSS custom properties that Tailwind and the UI layer already consume.

How custom styling is loaded

Snapp injects a stylesheet at the very end of the HTML document.

<!-- Custom Style Override -->
<link rel="stylesheet" href="/custom.css" />

Because this link is placed after the entire application markup, all definitions inside custom.css take precedence via normal CSS cascade rules.

Where custom.css comes from

The /custom.css file is served by Snapp at runtime.

Internally, it is read from:

config/custom.css

This file is typically mounted via Docker.

Example volume mapping:

volumes:
  - ./config/custom.css:/app/config/custom.css

Snapp exposes it through a dedicated endpoint with long-term caching:

  • Content-Type: text/css
  • Cache-Control: max-age=31536000

No application restart is required to change styles; only the file content matters.

What you are expected to put in custom.css

You are expected to redefine only CSS variables, not write component CSS.

The recommended approach is:

  • Generate a theme using a Shadcn-compatible theme generator (for example: https://www.shadcn.io/theme-generator)
  • Copy only the :root { ... } and .dark { ... } blocks
  • Paste them into config/custom.css

Example structure:

:root {
	--background: oklch(...);
	--foreground: oklch(...);
	--primary: oklch(...);
	--radius: 0.25rem;
	--font-sans: 'Lato', sans-serif;
	/* … */
}

.dark {
	--background: oklch(...);
	--foreground: oklch(...);
	/* … */
}

These variables directly replace the defaults shipped with Snapp.

Tailwind integration

Snapp uses Tailwind tokens that are mapped to CSS variables.

The mapping is defined once and reused everywhere:

@theme inline {
	--color-background: var(--background);
	--color-foreground: var(--foreground);
	--color-primary: var(--primary);
	--radius-lg: var(--radius);
	/* … */
}

Because of this:

  • All Tailwind utilities (bg-background, text-foreground, etc.) update automatically
  • All UI components update automatically
  • Charts, sidebar, modals, and forms stay consistent

No Tailwind config changes are required.

Fonts and typography

You can override fonts the same way, using CSS variables:

:root {
	--font-sans: 'Lato', sans-serif;
	--font-serif: 'Merriweather', serif;
	--font-mono: 'Roboto Mono', monospace;
}

If you import fonts from Google Fonts or other providers, do it at the top of custom.css.

Dark mode

Dark mode is handled through the .dark selector.

Snapp toggles the dark class on the root element. Your responsibility is only to define the variables.

There is no JavaScript or theme switch logic to implement.

What this system does not allow

  • No per-component CSS overrides
  • No Tailwind rebuilds
  • No runtime class injection
  • No inline style mutation

Styling is declarative, global, and token-based by design.

If a value is not exposed as a CSS variable, it is not meant to be themed.

Prev
Configuration