N
Nuxt3mo ago
SamKaizen

Referencing css variables directly in app.config.ts

Hello Kapa I have a neutral palette defined in my custom theme under assets/themes/default.css where i want to map neutral to a custom palette so i checked there does not seem to be a --ui-neutral in https://ui.nuxt.com/getting-started/theme#theme where it mentions "This is how the @theme is generated for each color alias:" so inconvenient but fine i mapped the full -50 to -950 mapping using the tailwind color vars now I'd like those to be picked up in app.config.ts like
colors: {
// NOTE : ideally this should have been overwritten by the appropriate theme so keep an eye for unexpected rose accents :P
primary: "rose",
neutral: var(--ui-color-neutral),
},
colors: {
// NOTE : ideally this should have been overwritten by the appropriate theme so keep an eye for unexpected rose accents :P
primary: "rose",
neutral: var(--ui-color-neutral),
},
where rose is the fallback primary color but this doesn't work.. any way to define the app.config.ts entries using css vars previously defined?
Nuxt UI
Theme - Nuxt UI
Learn how to customize Nuxt UI components using Tailwind CSS v4, CSS variables and the Tailwind Variants API for powerful and flexible theming.
23 Replies
kapa.ai
kapa.ai3mo ago
Hi @SamKaizen. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- You cannot reference CSS variables (like var(--ui-color-neutral)) directly in your app.config.ts for Nuxt UI theming. The colors object in app.config.ts only accepts color names from the default Tailwind palette (e.g., 'rose', 'zinc', 'slate', etc.) or custom color names that you have defined in your CSS theme. It does not support referencing CSS variables directly in the config file. For example, this is valid:
export default defineAppConfig({
ui: {
colors: {
primary: 'rose',
neutral: 'zinc'
}
}
})
export default defineAppConfig({
ui: {
colors: {
primary: 'rose',
neutral: 'zinc'
}
}
})
But this is not valid:
export default defineAppConfig({
ui: {
colors: {
primary: 'rose',
neutral: 'var(--ui-color-neutral)' // ❌ Not supported
}
}
})
export default defineAppConfig({
ui: {
colors: {
primary: 'rose',
neutral: 'var(--ui-color-neutral)' // ❌ Not supported
}
}
})
If you want to use a custom palette for neutral, you should define the palette in your CSS (using the @theme directive) and then reference the palette name (e.g., 'zinc', 'slate', or your custom name) in app.config.ts. The mapping between the alias (neutral) and the palette (e.g., 'zinc') happens at the config level, not via CSS variables. If you need to override the actual color values or shades, you should do so in your CSS file, not in app.config.ts. For example:
@theme static {
--color-neutral-50: #f5f5f5;
--color-neutral-100: #e5e5e5;
/* ... */
--color-neutral-950: #111111;
}
@theme static {
--color-neutral-50: #f5f5f5;
--color-neutral-100: #e5e5e5;
/* ... */
--color-neutral-950: #111111;
}
Then in app.config.ts:
export default defineAppConfig({
ui: {
colors: {
neutral: 'neutral' // This will use your custom palette defined in CSS
}
}
})
export default defineAppConfig({
ui: {
colors: {
neutral: 'neutral' // This will use your custom palette defined in CSS
}
}
})
Summary:
You cannot use var(--ui-color-neutral) or any CSS variable directly in app.config.ts. You must use palette names, and the actual color values should be defined in your CSS theme file. This is a current limitation of the Nuxt UI theming system as described in the documentation Getting-started > Theme and Getting-started > Colors. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai3mo ago
<@422361058246918146> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
SamKaizen
SamKaizenOP3mo ago
ok @kapa.ai then how would you manage runtime switching of the neutral colour to use via a theme switcher kind of component : I plan to have assets/theme/default.css and assets/theme/custom.css for the app with both the themes being light}dark mode aware.. how would the switch work?
kapa.ai
kapa.ai3mo ago
Let me check the knowledge base for you again. One moment! :books: ---------------------- To implement runtime switching between different neutral color palettes (e.g., from assets/theme/default.css to assets/theme/custom.css), the recommended approach in Nuxt UI is to dynamically load or swap your CSS files at runtime. Nuxt UI does not provide a built-in API for switching the color palette alias (like neutral) at runtime via app.config.ts, since this config is static and evaluated at build time, not at runtime Getting-started > Theme. How to achieve runtime theme switching: 1. Define your themes in separate CSS files
For example, assets/theme/default.css and assets/theme/custom.css, each containing your @theme definitions and CSS variables for both light and dark modes. 2. Dynamically load the desired theme CSS at runtime
You can use a theme switcher component to change which CSS file is loaded. This is typically done by manipulating a <link rel="stylesheet"> tag in the document head. Example (pseudo-code for a Vue component):
<template>
<UButton @click="switchTheme">Switch Theme</UButton>
</template>

<script setup>
const currentTheme = ref('default')

function switchTheme() {
currentTheme.value = currentTheme.value === 'default' ? 'custom' : 'default'
const themeLink = document.getElementById('theme-stylesheet')
themeLink.href = `/assets/theme/${currentTheme.value}.css`
}
</script>

<template>
<UButton @click="switchTheme">Switch Theme</UButton>
</template>

<script setup>
const currentTheme = ref('default')

function switchTheme() {
currentTheme.value = currentTheme.value === 'default' ? 'custom' : 'default'
const themeLink = document.getElementById('theme-stylesheet')
themeLink.href = `/assets/theme/${currentTheme.value}.css`
}
</script>

In your app.vue or layout, include:
<link id="theme-stylesheet" rel="stylesheet" href="/assets/theme/default.css">

<link id="theme-stylesheet" rel="stylesheet" href="/assets/theme/default.css">

3. Ensure both themes are light/dark mode aware
Each CSS file should define the appropriate variables for both .dark and default modes, as shown in the docs Getting-started > CSS Variables. Important notes: - You cannot change the color alias mapping (e.g., neutral: 'zinc') at runtime via app.config.ts—this is static. - All theme switching must be handled at the CSS level by swapping the loaded stylesheet. - Nuxt UI components will automatically pick up the new CSS variables once the stylesheet is swapped, as they rely on CSS variables for theming. This approach is consistent with how Nuxt UI and its design tokens are intended to be used Getting-started > Theme Getting-started > CSS Variables. If you need a more advanced or dynamic solution, such as merging or toggling classes, the knowledge sources do not provide explicit guidance for that scenario. The documented and supported method is CSS variable and stylesheet swapping. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai3mo ago
<@422361058246918146> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
SamKaizen
SamKaizenOP3mo ago
@kapa.ai in that case only one theme css file say for default needs to be imported in main.css? or both?
kapa.ai
kapa.ai3mo ago
Let me check the knowledge base for you again. One moment! :books: ---------------------- You should only import one theme CSS file (e.g., the default theme) in your main.css for initial loading. If you want to support runtime theme switching, you should dynamically load the other theme CSS files as needed, rather than importing both in main.css. This ensures that only the active theme's CSS variables are applied and avoids conflicts between themes. The knowledge sources describe importing your main theme CSS in main.css like this:
@import "tailwindcss";
@import "@nuxt/ui";
@import "~/assets/theme/default.css";
@import "tailwindcss";
@import "@nuxt/ui";
@import "~/assets/theme/default.css";
or
@import "tailwindcss";
@import "@nuxt/ui-pro";
@import "~/assets/theme/default.css";
@import "tailwindcss";
@import "@nuxt/ui-pro";
@import "~/assets/theme/default.css";
There is no mention in the documentation of importing multiple theme CSS files at once for runtime switching. Instead, you should load only the active theme's CSS file to ensure correct variable application Getting-started > Theme. If you need to switch themes at runtime, you would handle loading the alternate CSS file dynamically (for example, by swapping a <link> tag), not by importing both in main.css. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai3mo ago
<@422361058246918146> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
SamKaizen
SamKaizenOP3mo ago
@kapa.ai mmm i'm still having trouble with overriding neutral.. in default.css both :root and .dark i have --quill-neutral: var(--color-emerald); then in main.css i have in @theme --color-neutral: var(--quill-neutral); then in app.config.ts i have
ui: {
colors: {
// NOTE : ideally this should have been overwritten by the appropriate theme so keep an eye for unexpected rose accents :P
primary: "rose",
neutral: "neutral",
},
...
}
ui: {
colors: {
// NOTE : ideally this should have been overwritten by the appropriate theme so keep an eye for unexpected rose accents :P
primary: "rose",
neutral: "neutral",
},
...
}
but it i still showing the default slate? instead of emerald?
kapa.ai
kapa.ai3mo ago
Let me check the knowledge base for you again. One moment! :books: ---------------------- Based on the knowledge sources, your approach is close, but there are some important details about how Nuxt UI resolves color aliases and CSS variables: - The colors object in app.config.ts maps the alias (like neutral) to a palette name (like 'slate', 'emerald', etc.), not to a CSS variable.
- When you set neutral: "neutral", Nuxt UI expects a palette named neutral to be defined in your theme (by default, this is slate).
- Overriding --color-neutral in your CSS does not change the palette that Nuxt UI uses for the neutral alias unless you also override all the required palette shades (e.g., --color-neutral-50, --color-neutral-100, ..., --color-neutral-950Getting-started > Theme. Why you see slate:
If you only override --color-neutral, but not the full palette (--color-neutral-50 to --color-neutral-950), Nuxt UI will still use the default slate palette for all the shades, so your UI will look like slate, not emerald. How to override neutral with emerald: 1. In your main.css or theme CSS, map all neutral shades to emerald:
@theme static {
--color-neutral-50: var(--color-emerald-50);
--color-neutral-100: var(--color-emerald-100);
--color-neutral-200: var(--color-emerald-200);
--color-neutral-300: var(--color-emerald-300);
--color-neutral-400: var(--color-emerald-400);
--color-neutral-500: var(--color-emerald-500);
--color-neutral-600: var(--color-emerald-600);
--color-neutral-700: var(--color-emerald-700);
--color-neutral-800: var(--color-emerald-800);
--color-neutral-900: var(--color-emerald-900);
--color-neutral-950: var(--color-emerald-950);
}
@theme static {
--color-neutral-50: var(--color-emerald-50);
--color-neutral-100: var(--color-emerald-100);
--color-neutral-200: var(--color-emerald-200);
--color-neutral-300: var(--color-emerald-300);
--color-neutral-400: var(--color-emerald-400);
--color-neutral-500: var(--color-emerald-500);
--color-neutral-600: var(--color-emerald-600);
--color-neutral-700: var(--color-emerald-700);
--color-neutral-800: var(--color-emerald-800);
--color-neutral-900: var(--color-emerald-900);
--color-neutral-950: var(--color-emerald-950);
}
2. In app.config.ts, keep:
ui: {
colors: {
primary: "rose",
neutral: "neutral", // This will now use your remapped emerald palette
},
}
ui: {
colors: {
primary: "rose",
neutral: "neutral", // This will now use your remapped emerald palette
},
}
This way, when Nuxt UI looks up the neutral palette, it will use your emerald-mapped variables for all shades, and your UI will reflect the emerald color instead of slate Getting-started > Theme. Summary:
You must override the full set of --color-neutral-* variables to change the neutral palette. Overriding only --color-neutral or using a custom variable like --quill-neutral is not enough for Nuxt UI's theming system to pick up the change. If you follow this approach, your neutral alias will use emerald as intended. If you still see slate, double-check that your CSS is loaded after the default theme and that your variables are not being overridden elsewhere. Reference: Getting-started > Theme ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai3mo ago
<@422361058246918146> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
SamKaizen
SamKaizenOP3mo ago
@kapa.ai so seems like text-neutral-400 etc is mapping as expected but bg-default is not using any neutral palette shade?
kapa.ai
kapa.ai3mo ago
Let me check the knowledge base for you again. One moment! :books: ---------------------- You're correct: in Nuxt UI, classes like text-neutral-400 map directly to the corresponding neutral palette shade (e.g., --color-neutral-400), so if you've remapped the neutral palette in your CSS, those will reflect your changes. However, bg-default does not use a neutral palette shade directly. Instead, it uses the design token --ui-bg, which is mapped in your CSS to a specific color variable. By default, --ui-bg is set to --ui-color-neutral-50 for light mode and --ui-color-neutral-950 for dark mode, but you can override this in your CSS. For example, from the documentation:
:root {
--ui-bg: var(--ui-color-neutral-50);
--ui-text: var(--ui-color-neutral-900);
}
.dark {
--ui-bg: var(--ui-color-neutral-950);
--ui-border: var(--ui-color-neutral-900);
}
:root {
--ui-bg: var(--ui-color-neutral-50);
--ui-text: var(--ui-color-neutral-900);
}
.dark {
--ui-bg: var(--ui-color-neutral-950);
--ui-border: var(--ui-color-neutral-900);
}
So, if you want bg-default to use a specific shade from your remapped neutral palette, make sure that --ui-bg is set to the desired --ui-color-neutral-* variable in your theme CSS Getting-started > CSS Variables > Neutral. Summary:
- text-neutral-400 uses your remapped palette. - bg-default uses --ui-bg, which you can set to any neutral shade you want by overriding --ui-bg in your CSS. If you want bg-default to match a specific neutral shade, update your CSS like this:
:root {
--ui-bg: var(--ui-color-neutral-100); /* or whichever shade you want */
}
:root {
--ui-bg: var(--ui-color-neutral-100); /* or whichever shade you want */
}
This will ensure bg-default reflects your custom neutral palette as well. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai3mo ago
<@422361058246918146> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
SamKaizen
SamKaizenOP3mo ago
@kapa.ai ok so we defined a neutral palette (mapped to emerald explicitly) this is --color-neutral so all utilities like bg-neutral-600 or text-neutral-400 will work but by default on dark mode --ui-bg is supposed to be --ui-color-neutral the way to set that is via app.config.ts ui -> colors -> neutral right? then why isn't this being picked up? what is the nuxt ui way to set ui-color-neutral palette in this case?
kapa.ai
kapa.ai3mo ago
Let me check the knowledge base for you again. One moment! :books: ---------------------- In Nuxt UI, setting the neutral palette in app.config.ts under ui.colors.neutral only tells Nuxt UI which palette name to use for the neutral alias (e.g., 'slate', 'emerald', or a custom palette name). This affects all Tailwind utilities like bg-neutral-600 or text-neutral-400, which will use the remapped palette if you have overridden the --color-neutral-* variables in your CSS Getting-started > Theme. However, the design token --ui-bg (used by bg-default) is not set by the app.config.ts color alias. Instead, it is mapped in your CSS, typically in your main.css or theme file, like this:
:root {
--ui-bg: var(--ui-color-neutral-50);
}
.dark {
--ui-bg: var(--ui-color-neutral-950);
}
:root {
--ui-bg: var(--ui-color-neutral-50);
}
.dark {
--ui-bg: var(--ui-color-neutral-950);
}
If you want --ui-bg to use a specific shade from your remapped neutral palette (which you mapped to emerald), you must explicitly set --ui-bg in your CSS to the desired --ui-color-neutral-* variable. The app.config.ts setting does not control this mapping; it only controls which palette is used for the neutral alias in Tailwind utilities. Summary:
- app.config.tsui.colors.neutral sets the palette for Tailwind utilities like bg-neutral-600, text-neutral-400, etc. - The mapping for --ui-bg (used by bg-default) must be set in your CSS, not in app.config.ts. - To have bg-default use your custom neutral palette, set --ui-bg to the appropriate --ui-color-neutral-* variable in your CSS. This is the Nuxt UI way to control the background design token and ensure it uses your custom palette Getting-started > CSS Variables > Neutral Getting-started > Theme. If you have done this and it is still not being picked up, double-check the order of your CSS imports and ensure your overrides are not being overwritten by other styles. If the documentation does not cover a specific edge case, it may be a limitation or require further investigation. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai3mo ago
<@422361058246918146> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
SamKaizen
SamKaizenOP3mo ago
@kapa.ai ok then where is ui-color-neutral design token set coz it seems to me that's what we need to be explicitly setting? but if i simply set in app,config.ts ui colors neutral as blue it changes bg-default perfectly fine?
kapa.ai
kapa.ai3mo ago
Let me check the knowledge base for you again. One moment! :books: ---------------------- The design token --ui-color-neutral is generated by Nuxt UI based on the palette you specify in your app.config.ts under ui.colors.neutral. When you set, for example:
export default defineAppConfig({
ui: {
colors: {
neutral: 'blue'
}
}
})
export default defineAppConfig({
ui: {
colors: {
neutral: 'blue'
}
}
})
Nuxt UI will generate the --ui-color-neutral (and all its shades, like --ui-color-neutral-50, --ui-color-neutral-100, etc.) using the Tailwind blue palette. This means all references to --ui-color-neutral and its shades in your CSS (including those used by design tokens like --ui-bg) will now use the blue palette. That’s why setting neutral: 'blue' in your config changes the appearance of bg-default and other design tokens that depend on the neutral palette Getting-started > Theme. In summary:
- --ui-color-neutral and its shades are set automatically by Nuxt UI based on the palette name you provide in app.config.ts under ui.colors.neutral. - Setting neutral: 'blue' in your config will make all design tokens and utilities that depend on the neutral palette use the blue palette instead. - You do not need to set --ui-color-neutral manually in your CSS unless you want to override the generated value. This behavior is by design and is documented in the Nuxt UI theming system Getting-started > Theme. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai3mo ago
<@422361058246918146> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
SamKaizen
SamKaizenOP3mo ago
@kapa.ai figured it out i think neutral is a reserved word for defining new tailwind color palettes .. renaming the custom palette to something placeholder like 'qbd' and then using ui -> colors -> neutral as qbd successfully had the background and texts and everything changed
kapa.ai
kapa.ai3mo ago
Let me check the knowledge base for you again. One moment! :books: ---------------------- You're absolutely correct, and your solution aligns with how Nuxt UI's theming system is designed to work. In Nuxt UI, the neutral alias is reserved and maps to a palette name (like slate, zinc, etc.) from the Tailwind palette or a custom palette you define. If you want to use your own custom palette, you should: 1. Define your custom palette (e.g., qbd) in your CSS using the @theme directive, providing all the required shades (e.g., --color-qbd-50, --color-qbd-100, etc.). 2. Set the neutral alias to your custom palette name in app.config.ts:
export default defineAppConfig({
ui: {
colors: {
neutral: 'qbd'
}
}
})

export default defineAppConfig({
ui: {
colors: {
neutral: 'qbd'
}
}
})

This tells Nuxt UI to use your custom palette (qbd) wherever the neutral alias is referenced, including for design tokens like --ui-color-neutral-*, which are then used by background, text, and border utilities as well as design tokens like bg-default and text-default Getting-started > Theme. If you try to define a new palette with the name neutral, it will conflict with the reserved alias and not work as expected. Using a unique name for your custom palette and mapping the alias in the config is the correct approach. Great job figuring this out! ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai3mo ago
<@422361058246918146> Kapa.ai is still learning and improving, please let me know how I did by reacting below.

Did you find this page helpful?