How can I implement dynamic theme switching based on the current route in my Vue application?

For example, I want to apply a specific 'brand theme' when navigating to certain sections (like '/about', '/products'), while maintaining my existing light/dark mode system. What's the best approach to combine route-specific theming with the existing CSS custom properties system?
2 Replies
kapa.ai
kapa.ai2mo ago
Hi @Sagar Kapoor. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- To implement dynamic theme switching based on the current route in your Vue (or Nuxt) application—while maintaining your existing light/dark mode system and leveraging CSS custom properties—the recommended approach is to use Nuxt UI’s runtime theming capabilities via CSS variables and AppConfig. Key steps: 1. Define Brand Themes Using CSS Variables
Nuxt UI uses CSS variables (design tokens) for theming, which are automatically applied and can be customized for both light and dark modes. You can define different color palettes (e.g., for your brand theme) in your app.config.ts under the ui.colors key. This allows you to change semantic color aliases (like primary, neutral, etc.) at runtime without rebuilding your app:
// app.config.ts
export default defineAppConfig({
ui: {
colors: {
primary: 'blue', // default theme
neutral: 'zinc'
}
}
})

// app.config.ts
export default defineAppConfig({
ui: {
colors: {
primary: 'blue', // default theme
neutral: 'zinc'
}
}
})

See more on configuring color aliases 2. Switch Themes Dynamically Based on Route
While Nuxt UI supports runtime configuration, the knowledge sources do not provide a built-in API for per-route theme switching. However, you can programmatically update CSS variables or the AppConfig in a layout or page-level setup, using the useRoute composable to detect the current route and apply the desired theme. For example, you could use a watcher on the route and update the CSS variables directly:
<script setup>
import { useRoute } from 'vue-router'
import { watch } from 'vue'

const route = useRoute()
watch(
() => route.path,
(path) => {
if (['/about', '/products'].includes(path)) {
// Apply brand theme
document.documentElement.style.setProperty('--ui-primary', '#ff6600')
document.documentElement.style.setProperty('--ui-secondary', '#333333')
// ...set other variables as needed
} else {
// Revert to default theme
document.documentElement.style.setProperty('--ui-primary', '#3b82f6')
document.documentElement.style.setProperty('--ui-secondary', '#f472b6')
// ...reset other variables as needed
}
},
{ immediate: true }
)
</script>

<script setup>
import { useRoute } from 'vue-router'
import { watch } from 'vue'

const route = useRoute()
watch(
() => route.path,
(path) => {
if (['/about', '/products'].includes(path)) {
// Apply brand theme
document.documentElement.style.setProperty('--ui-primary', '#ff6600')
document.documentElement.style.setProperty('--ui-secondary', '#333333')
// ...set other variables as needed
} else {
// Revert to default theme
document.documentElement.style.setProperty('--ui-primary', '#3b82f6')
document.documentElement.style.setProperty('--ui-secondary', '#f472b6')
// ...reset other variables as needed
}
},
{ immediate: true }
)
</script>

This approach works seamlessly with the existing light/dark mode system, as you’re only overriding the relevant CSS variables for the current route. The rest of the theme (including dark mode) will continue to function as configured. 3. Maintain Light/Dark Mode
Nuxt UI’s color mode system (integrated with @nuxtjs/color-mode) will continue to handle light/dark switching. Your route-specific overrides will apply on top of the current mode, so you may want to define both light and dark variants for your brand theme variables if needed. You can do this by targeting the .dark selector as well:
:root {
--ui-primary: #ff6600;
}
.dark {
--ui-primary: #ff9900;
}

:root {
--ui-primary: #ff6600;
}
.dark {
--ui-primary: #ff9900;
}

Summary:
- Use CSS variables for theme tokens. - Watch the route and update variables as needed. - Light/dark mode will continue to work, as you’re only overriding the relevant variables. Note:
The knowledge sources do not mention a built-in Nuxt UI API for per-route theme switching, so this manual approach using CSS variables is the most direct and compatible method with the current system. For more advanced scenarios, you may consider using layouts or middleware to encapsulate theme logic per section. References:
- Nuxt UI: CSS Variables and Theming - Nuxt UI: Color Mode Integration ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai2mo ago
<@565461230060306432> Kapa.ai is still learning and improving, please let me know how I did by reacting below.

Did you find this page helpful?