N
Nuxt2mo ago
Felix

How to set css variables

Hey, how can i set css variables dynamically (data driven) during SSR?
5 Replies
kapa.ai
kapa.ai2mo ago
Hi @Felix. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- To set CSS variables dynamically during SSR in Nuxt, you have several approaches: Using v-bind in style blocks You can use Vue's v-bind function in your style blocks to bind JavaScript variables to CSS properties:
<script setup lang="ts">
const color = ref("red")
</script>

<template>
<div class="text">hello</div>
</template>

<style>
.text {
color: v-bind(color);
}
</style>
<script setup lang="ts">
const color = ref("red")
</script>

<template>
<div class="text">hello</div>
</template>

<style>
.text {
color: v-bind(color);
}
</style>
This approach works with SSR because the value is computed on the server before rendering Stack Overflow Post > Pass a computed property to css url() with v-bind in Vue 3. Using useHead composable For global CSS variables, you can use the useHead composable to inject styles with dynamic values:
<script setup>
const primaryColor = ref('#00DC82')

useHead({
style: [
{
children: `
:root {
--primary-color: ${primaryColor.value};
}
`
}
]
})
</script>
<script setup>
const primaryColor = ref('#00DC82')

useHead({
style: [
{
children: `
:root {
--primary-color: ${primaryColor.value};
}
`
}
]
})
</script>
This will inject the styles during SSR Docs > Getting-started > SEO and Meta. Using a Nitro plugin for more control For more advanced control, you can intercept the rendered HTML with a Nitro plugin:
// server/plugins/my-plugin.ts
export default defineNitroPlugin((nitro) => {
nitro.hooks.hook('render:html', (html) => {
// You can access request data or other server-side variables here
const dynamicColor = '#00DC82' // This could come from a database or other source

html.head.push(`<style>:root { --dynamic-color: ${dynamicColor}; }</style>`)
})
})
// server/plugins/my-plugin.ts
export default defineNitroPlugin((nitro) => {
nitro.hooks.hook('render:html', (html) => {
// You can access request data or other server-side variables here
const dynamicColor = '#00DC82' // This could come from a database or other source

html.head.push(`<style>:root { --dynamic-color: ${dynamicColor}; }</style>`)
})
})
This approach gives you full access to server-side data during rendering Docs > Getting-started > Styling. Using runtime config If your CSS variables depend on environment variables or configuration: 1. Define your variables in nuxt.config.ts:
export default defineNuxtConfig({
runtimeConfig: {
public: {
themeColor: process.env.THEME_COLOR || '#00DC82'
}
}
})
export default defineNuxtConfig({
runtimeConfig: {
public: {
themeColor: process.env.THEME_COLOR || '#00DC82'
}
}
})
2. Access them in your component:
<script setup>
const config = useRuntimeConfig()

useHead({
style: [
{
children: `:root { --theme-color: ${config.public.themeColor}; }`
}
]
})
</script>
<script setup>
const config = useRuntimeConfig()

useHead({
style: [
{
children: `:root { --theme-color: ${config.public.themeColor}; }`
}
]
})
</script>
This ensures your CSS variables are set during SSR based on your runtime configuration Docs > Guide > Going-further > Runtime-config. Choose the approach that best fits your specific use case and data source requirements. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai2mo ago
<@223579303122567168> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
Felix
FelixOP2mo ago
@kapa.ai is it possible to keep the values reactive so that the theme can be adjusted at runtime?
kapa.ai
kapa.ai2mo ago
Let me check the knowledge base for you again. One moment! :books: ---------------------- Yes, it's absolutely possible to keep CSS variables reactive in Nuxt so that the theme can be adjusted at runtime. Nuxt provides several approaches for this: Using appConfig for reactive theming Nuxt UI uses this approach for its theming system. The app.config.ts file allows you to define reactive configuration that can be updated at runtime with hot-module-replacement:
// app.config.ts
export default defineAppConfig({
ui: {
primary: 'green',
gray: 'cool'
}
})
// app.config.ts
export default defineAppConfig({
ui: {
primary: 'green',
gray: 'cool'
}
})
You can then access and update this configuration using the useAppConfig composable and updateAppConfig utility:
<script setup>
const appConfig = useAppConfig()

function changeTheme(newColor) {
updateAppConfig({
ui: {
...appConfig.ui,
primary: newColor
}
})
}
</script>
<script setup>
const appConfig = useAppConfig()

function changeTheme(newColor) {
updateAppConfig({
ui: {
...appConfig.ui,
primary: newColor
}
})
}
</script>
This approach is used by Nuxt UI for its color picker feature Getting-started > Theming. Using public runtimeConfig The public portion of runtimeConfig is reactive on the client side:
<script setup>
const config = useRuntimeConfig()

// Update the theme color
function updateTheme(newColor) {
config.public.themeColor = newColor

// Apply the updated color to CSS variables
document.documentElement.style.setProperty('--theme-color', newColor)
}
</script>
<script setup>
const config = useRuntimeConfig()

// Update the theme color
function updateTheme(newColor) {
config.public.themeColor = newColor

// Apply the updated color to CSS variables
document.documentElement.style.setProperty('--theme-color', newColor)
}
</script>
According to the documentation, "On client-side, only keys in runtimeConfig.public are available, and the object is both writable and reactive" Docs > Guide > Going-further > Runtime Config. Using useState for shared state For theme values that need to be shared between server and client:
<script setup>
// Create a shared state for the theme
const theme = useState('theme', () => 'light')
// Function to toggle theme
function toggleTheme() {
theme.value = theme.value === 'light' ? 'dark' : 'light'

// Apply theme change to CSS variables
document.documentElement.setAttribute('data-theme', theme.value)
}

// Watch for theme changes to update CSS variables
watch(theme, (newTheme) => {
// Update CSS variables based on theme
if (newTheme === 'dark') {
document.documentElement.style.setProperty('--bg-color', '#121212')
document.documentElement.style.setProperty('--text-color', '#ffffff')
} else {
document.documentElement.style.setProperty('--bg-color', '#ffffff')
document.documentElement.style.setProperty('--text-color', '#121212')
}
})
</script>
<script setup>
// Create a shared state for the theme
const theme = useState('theme', () => 'light')
// Function to toggle theme
function toggleTheme() {
theme.value = theme.value === 'light' ? 'dark' : 'light'

// Apply theme change to CSS variables
document.documentElement.setAttribute('data-theme', theme.value)
}

// Watch for theme changes to update CSS variables
watch(theme, (newTheme) => {
// Update CSS variables based on theme
if (newTheme === 'dark') {
document.documentElement.style.setProperty('--bg-color', '#121212')
document.documentElement.style.setProperty('--text-color', '#ffffff')
} else {
document.documentElement.style.setProperty('--bg-color', '#ffffff')
document.documentElement.style.setProperty('--text-color', '#121212')
}
})
</script>
The useState composable creates a reactive state that's shared between server and client Stack Overflow Post > Inconsistent variable values in Nuxt 3 components Part 2. Dark mode toggle example Here's a practical example for toggling dark mode:
<script setup lang="ts">
const colorMode = useColorMode()
const isDark = computed({
get () {
return colorMode.value === 'dark'
},
set () {
colorMode.preference = colorMode.value === 'dark' ? 'light' : 'dark'
}
})
</script>

<template>
<ClientOnly>
<UButton
:icon="isDark ? 'i-heroicons-moon-20-solid' : 'i-heroicons-sun-20-solid'"
color="gray"
variant="ghost"
aria-label="Theme"
@click="isDark = !isDark"
/>
<template #fallback>
<div class="w-8 h-8" />
</template>
</ClientOnly>
</template>
<script setup lang="ts">
const colorMode = useColorMode()
const isDark = computed({
get () {
return colorMode.value === 'dark'
},
set () {
colorMode.preference = colorMode.value === 'dark' ? 'light' : 'dark'
}
})
</script>

<template>
<ClientOnly>
<UButton
:icon="isDark ? 'i-heroicons-moon-20-solid' : 'i-heroicons-sun-20-solid'"
color="gray"
variant="ghost"
aria-label="Theme"
@click="isDark = !isDark"
/>
<template #fallback>
<div class="w-8 h-8" />
</template>
</ClientOnly>
</template>
This example uses the @nuxtjs/color-mode module to handle theme switching Getting-started > Dark mode. Remember that when updating CSS variables at runtime on the client side, you'll need to use JavaScript to update the variables, typically by modifying the style properties on the document root or a specific container element. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai2mo ago
<@223579303122567168> Kapa.ai is still learning and improving, please let me know how I did by reacting below.

Did you find this page helpful?