Skip to main content
RapidDev - Software Development Agency
lovable-issues

How to Customize Themes, Colors, and UI Styles in Lovable Projects

Lovable's theme system is controlled through Design view → Themes tab, where you set colors, fonts, spacing, and border radius without spending credits. For deeper customization, edit the CSS variables in your project's globals.css or tailwind.config.ts file. Lovable uses shadcn/ui (built on Radix UI) for components, so theming works by overriding CSS custom properties that cascade through every component automatically.

Book a free consultation
4.9Clutch rating
600+Happy partners
17+Countries served
190+Team members
Intermediate9 min read~10 minAll Lovable versionsMarch 2026RapidDev Engineering Team
TL;DR

Lovable's theme system is controlled through Design view → Themes tab, where you set colors, fonts, spacing, and border radius without spending credits. For deeper customization, edit the CSS variables in your project's globals.css or tailwind.config.ts file. Lovable uses shadcn/ui (built on Radix UI) for components, so theming works by overriding CSS custom properties that cascade through every component automatically.

Why theming in Lovable requires understanding CSS variables and shadcn/ui

Lovable generates projects using shadcn/ui, a component library built on Radix UI primitives and styled with Tailwind CSS. The theming system works through CSS custom properties (variables) defined in your globals.css file. When you change a theme variable, every component that references it updates automatically. The Design view → Themes tab provides a visual interface for editing these variables. You can change primary colors, background colors, fonts, spacing, and border radius — all without writing code. These changes cost no credits and take effect immediately in the preview. However, the visual Themes tab covers common settings. For advanced customization — like creating a complete dark mode toggle, adding custom color palettes beyond the defaults, or overriding specific component styles — you need to edit the CSS variables directly in globals.css or update the Tailwind configuration. Understanding this two-layer system (visual Themes tab for common changes, CSS variables for everything else) is key to getting the exact look you want.

  • Theme changes in Design view not reflected — browser cache showing old styles
  • Custom CSS overridden by shadcn/ui default styles — CSS specificity conflict
  • Dark mode not toggling — the dark class not applied to the HTML root element
  • Tailwind classes not matching theme colors — custom color names not registered in tailwind.config.ts
  • Font changes not applying — custom font not loaded before the page renders

Error messages you might see

Unknown at rule @tailwind

Your CSS editor or linter does not recognize Tailwind directives. This is a tooling warning, not an actual error — the build will still work. You can safely ignore it or configure your editor's CSS validation.

The 'theme()' function is deprecated in Tailwind CSS v4

If your project uses Tailwind v4, the theme() function syntax has changed. Use CSS variable references (var(--color-primary)) directly instead of theme(colors.primary) in your CSS.

Cannot find module '@/components/ui/button'

A shadcn/ui component is missing from your project. Prompt Lovable to add the missing component, or check that the import path matches your file structure.

Before you start

  • A Lovable project open in the editor
  • Familiarity with the Design view (click + next to Preview → Design view)
  • Your desired color palette (hex codes or HSL values)
  • If adding custom fonts: the font files uploaded to /public/fonts or a Google Fonts URL

How to fix it

1

Use the Design view Themes tab for basic theme changes

The Themes tab provides a visual, no-code interface for the most common style changes — no credits required

Click the + button next to the Preview panel and select Design view. Switch to the Themes tab. Here you can change: primary color (buttons, links, active states), secondary color, accent color, background and foreground colors, default font family, base font size, spacing scale, and border radius. Changes appear instantly in the preview. This is the fastest way to customize your app's look without touching code. Once you are satisfied, the changes are saved to your project's CSS variables automatically.

Expected result: Your app's colors, fonts, and spacing update immediately in the preview without any code changes.

2

Edit CSS custom properties in globals.css for advanced theming

The Themes tab covers common settings — for full control, you edit the CSS variables directly

Open your project in Dev Mode and find src/index.css or src/globals.css. This file contains the :root CSS variables that define your theme. Each variable controls a specific aspect of the UI — for example, --background sets the page background, --primary sets the main action color, and --ring sets the focus outline color. You can add new variables, change existing ones, and create separate sets for light and dark modes. Values are in HSL format (hue, saturation, lightness) which makes it easy to create consistent color palettes.

Before
typescript
:root {
--background: 0 0% 100%;
--foreground: 222.2 84% 4.9%;
--primary: 222.2 47.4% 11.2%;
--primary-foreground: 210 40% 98%;
}
After
typescript
:root {
--background: 0 0% 100%;
--foreground: 240 10% 3.9%;
--primary: 262 83% 58%; /* Custom purple primary */
--primary-foreground: 0 0% 100%;
--secondary: 240 5% 96%;
--accent: 262 83% 90%; /* Lighter purple for accents */
--ring: 262 83% 58%; /* Focus rings match primary */
}
.dark {
--background: 240 10% 3.9%;
--foreground: 0 0% 98%;
--primary: 262 83% 68%; /* Slightly lighter purple for dark mode */
--primary-foreground: 0 0% 100%;
--secondary: 240 4% 16%;
--accent: 262 83% 20%;
--ring: 262 83% 68%;
}

Expected result: All shadcn/ui components automatically pick up the new colors. Buttons, links, cards, and form elements reflect your custom palette.

3

Implement a dark mode toggle

Users increasingly expect dark mode support — the CSS variables are already set up for it

Lovable's theme system supports dark mode through the .dark class on the HTML root element. Create a toggle component that adds or removes this class and persists the user's preference in localStorage. The CSS variables you defined in the .dark block in globals.css will apply whenever the .dark class is present. You can also detect the user's system preference with the prefers-color-scheme media query as the default.

Before
typescript
// No dark mode support
function App() {
return <div className="min-h-screen">...</div>;
}
After
typescript
// Dark mode toggle with localStorage persistence
import { useState, useEffect } from 'react';
import { Moon, Sun } from 'lucide-react';
import { Button } from '@/components/ui/button';
function ThemeToggle() {
const [isDark, setIsDark] = useState(() => {
const saved = localStorage.getItem('theme');
return saved === 'dark' || (!saved && window.matchMedia('(prefers-color-scheme: dark)').matches);
});
useEffect(() => {
document.documentElement.classList.toggle('dark', isDark);
localStorage.setItem('theme', isDark ? 'dark' : 'light');
}, [isDark]);
return (
<Button variant="ghost" size="icon" onClick={() => setIsDark(!isDark)}>
{isDark ? <Sun className="h-5 w-5" /> : <Moon className="h-5 w-5" />}
</Button>
);
}

Expected result: Clicking the toggle switches between light and dark mode. The preference persists across page reloads.

4

Add custom colors to Tailwind configuration

Custom Tailwind classes like bg-brand or text-brand-light require registration in the Tailwind config

If you want to use custom color names in Tailwind utility classes (beyond the theme variables), extend the Tailwind configuration. Open tailwind.config.ts and add your custom colors under theme.extend.colors. Reference your CSS variables so the colors stay in sync with the theme system. This lets you use classes like bg-brand, text-brand-foreground, and hover:bg-brand-dark throughout your components. If customizing the theme system across multiple components gets complex, RapidDev's engineers have configured custom design systems across 600+ Lovable projects.

Before
typescript
// Default tailwind.config.ts — no custom colors
export default {
content: ['./src/**/*.{ts,tsx}'],
theme: {
extend: {},
},
};
After
typescript
// Extended with custom brand colors referencing CSS variables
export default {
darkMode: 'class',
content: ['./src/**/*.{ts,tsx}'],
theme: {
extend: {
colors: {
brand: {
DEFAULT: 'hsl(var(--primary))',
foreground: 'hsl(var(--primary-foreground))',
light: 'hsl(var(--accent))',
},
},
},
},
};

Expected result: You can use bg-brand, text-brand-foreground, and bg-brand-light classes throughout your components.

Complete code example

src/components/ThemeToggle.tsx
1import { useState, useEffect } from 'react';
2import { Moon, Sun } from 'lucide-react';
3import { Button } from '@/components/ui/button';
4
5/**
6 * Theme toggle component for light/dark mode.
7 * Persists preference in localStorage.
8 * Falls back to system preference on first visit.
9 *
10 * Usage: <ThemeToggle /> place in your header/nav.
11 * Requires .dark CSS variables defined in globals.css.
12 */
13export function ThemeToggle() {
14 const [isDark, setIsDark] = useState(() => {
15 if (typeof window === 'undefined') return false;
16 const saved = localStorage.getItem('theme');
17 if (saved) return saved === 'dark';
18 // Respect system preference as default
19 return window.matchMedia('(prefers-color-scheme: dark)').matches;
20 });
21
22 useEffect(() => {
23 const root = document.documentElement;
24 if (isDark) {
25 root.classList.add('dark');
26 } else {
27 root.classList.remove('dark');
28 }
29 localStorage.setItem('theme', isDark ? 'dark' : 'light');
30 }, [isDark]);
31
32 return (
33 <Button
34 variant="ghost"
35 size="icon"
36 onClick={() => setIsDark((prev) => !prev)}
37 aria-label={isDark ? 'Switch to light mode' : 'Switch to dark mode'}
38 >
39 {isDark ? (
40 <Sun className="h-5 w-5 transition-transform" />
41 ) : (
42 <Moon className="h-5 w-5 transition-transform" />
43 )}
44 </Button>
45 );
46}

Best practices to prevent this

  • Start with the Design view → Themes tab for color, font, and spacing changes — it is the fastest method and costs no credits
  • Use HSL values for CSS variables — they make it easy to create lighter and darker variants of the same hue
  • Always define both :root (light) and .dark (dark) variables in globals.css so dark mode works out of the box
  • Reference CSS variables in Tailwind config (hsl(var(--primary))) to keep Tailwind classes in sync with your theme
  • Persist the user's dark mode preference in localStorage and respect prefers-color-scheme as the initial default
  • Test theme changes across all major components (buttons, forms, cards, navigation) — not just the homepage
  • Use the Visual Edits tab (Design view) for one-off style overrides on specific elements without writing CSS

Still stuck?

Copy one of these prompts to get a personalized, step-by-step explanation.

ChatGPT Prompt

I have a Lovable (lovable.dev) project using Vite + React + TypeScript + Tailwind CSS + shadcn/ui. I want to customize the theme. Here is my current globals.css: [paste your globals.css or index.css file] Here is my tailwind.config.ts: [paste your Tailwind config] I want these changes: - Primary color: [your hex/HSL color] - Secondary color: [your color] - Font: [your preferred font] - Dark mode: [yes/no] Please: 1. Convert my colors to HSL format for CSS variables 2. Update globals.css with both light and dark mode variables 3. Update tailwind.config.ts with custom color references 4. Create a dark mode toggle component 5. Show me which shadcn/ui components will automatically update

Lovable Prompt

Update my project's theme to use a custom color palette. Change the primary color to [YOUR HEX COLOR] and update all related CSS variables in globals.css for both light and dark mode. Make sure the --primary, --primary-foreground, --accent, --ring, and --secondary variables are all consistent with the new palette. Add a ThemeToggle component that switches between light and dark mode, persists the preference in localStorage, and defaults to the user's system preference. Use the Moon and Sun icons from lucide-react.

Frequently asked questions

How do I change colors in a Lovable project?

The easiest way is Design view → Themes tab: click the + button next to Preview, select Design view, and switch to the Themes tab. Change primary, secondary, background, and accent colors visually — no credits needed. For more control, edit the CSS variables in globals.css directly.

How does dark mode work in Lovable projects?

Lovable uses the .dark class on the HTML root element. Define a separate set of CSS variables under .dark in globals.css. When the .dark class is present, all shadcn/ui components automatically switch to the dark color values. Create a toggle component that adds/removes the class.

Can I use custom fonts in Lovable?

Yes. Either add a Google Fonts link tag to index.html or upload font files to /public/fonts and add @font-face rules in globals.css. Then update the --font-sans CSS variable or the font-family in your Tailwind config to reference the new font.

Why are my CSS changes not showing up in the preview?

Try a hard refresh (Ctrl+Shift+R) — the browser may be caching old styles. Also check that your CSS changes are in the correct file (globals.css) and that Tailwind classes in your components reference the right variable names. Changes in the Themes tab should appear instantly.

Does the Design view Themes tab cost credits?

No. Visual editing in the Design view (both Themes tab and Visual Edits tab) does not cost any credits. Only AI-powered agent prompts and dynamic element changes consume credits.

How do I customize shadcn/ui component styles in Lovable?

shadcn/ui components use CSS variables for theming. Change the variables in globals.css to update all components at once. For individual component overrides, edit the component file directly in Dev Mode — shadcn/ui components live in your project's src/components/ui folder as plain React code you own.

What if I need a complex custom design system that goes beyond basic theming?

For enterprise-level design systems with reusable component libraries and strict brand guidelines, RapidDev's engineers have implemented custom design systems across 600+ Lovable projects. They can set up a consistent theme architecture that scales across your entire application.

RapidDev

Talk to an Expert

Our team has built 600+ apps. Get personalized help with your issue.

Book a free consultation

Need help with your Lovable project?

Our experts have built 600+ apps and can solve your issue fast. Book a free consultation — no strings attached.

Book a free consultation

We put the rapid in RapidDev

Need a dedicated strategic tech and growth partner? Discover what RapidDev can do for your business! Book a call with our team to schedule a free, no-obligation consultation. We'll discuss your project and provide a custom quote at no cost.