Pricing

Add the theme editor to a React app built with Vite.

This page sets up the editor in a React app built with Vite. For Next.js, see Next.js.

Before you start

  • Vite 6 or later, React 19 and Node.js 22.12 or later.
  • A Vite app. No app yet? See Create a project.
  • A project set up with slabui init. The plugin reads its slabui.json to find your theme.

Install

Install the package

pnpm add @slabui/theme-react

Install it as a regular dependency: your app imports <ThemeEditor />. In the build, the editor renders nothing.

Add the plugin

vite.config.ts
import { themes } from "@slabui/theme-react/vite"
import tailwindcss from "@tailwindcss/vite"
import react from "@vitejs/plugin-react"
import { defineConfig } from "vite"
 
export default defineConfig({
  plugins: [react(), tailwindcss(), themes()],
})

The editor works only in vite (dev), not in vite build or vite preview. The plugin also turns on the theme set in SLABUI_THEME, in development and in the build; see Apply a theme.

Render the editor

src/main.tsx
import { ThemeEditor } from "@slabui/theme-react"
import { StrictMode } from "react"
import { createRoot } from "react-dom/client"
 
import { App } from "./app"
import "./index.css"
 
createRoot(document.getElementById("root") as HTMLElement).render(
  <StrictMode>
    <App />
    <ThemeEditor />
  </StrictMode>,
)

Render it once, next to your app, so it stays mounted when your routes change.

Open the editor

pnpm dev

Open your app and click the button on the left edge of the page. The first time, sign in to your SlabUI account (the same login as npx slabui login).

An app page with the theme editor button on its left edge

Apply a theme

Themes created in the Themes section of the editor are turned on with SLABUI_THEME, one per deploy. The plugin reads it from the environment and from your .env files (.env, .env.production…), like Vite's own variables:

.env.production
SLABUI_THEME=ocean

The plugin also reads VITE_SLABUI_THEME, which Vite exposes to your app as import.meta.env.VITE_SLABUI_THEME. When both are set, SLABUI_THEME wins.

You can also set the theme in the theme option. An attribute already written in index.html wins over both:

vite.config.ts
themes({ theme: process.env.BRAND ?? "ocean" })

Options

The plugin works without options in a project set up with slabui init: it reads your slabui.json and knows where your theme is. To keep your theme somewhere else, pass the options to themes():

vite.config.ts
export default defineConfig({
  plugins: [
    react(),
    tailwindcss(),
    themes({
      css: "src/styles/globals.css",
      dir: "src/styles/themes",
    }),
  ],
})
  • css: the file where your theme is saved. Defaults to the css field of slabui.json.
  • dir: the folder where extra themes are saved. Defaults to themes/ in your styles alias.
  • reference: the theme that Restore defaults brings back. Defaults to the SlabUI default theme.
  • theme: the theme applied to your app. Defaults to SLABUI_THEME or VITE_SLABUI_THEME, from the environment or the .env files.

Paths are relative to Vite's root and may use the aliases of your tsconfig.json.

Themes folder

Themes created in the Themes section of the editor are saved in the dir option or, without it, in themes/ inside the styles alias of slabui.json. With "styles": "@/styles" and "@/*": ["./src/*"] in tsconfig.json, that is src/styles/themes. The folder is created with the first theme.

Monorepos

The plugin reads slabui.json and tsconfig.json from Vite's root: the app's folder when you run vite from there or with pnpm --filter <app> dev.