Index of every page on this site: llms.txt

Nuxt OG Image supports modern CSS via Tailwind v4, UnoCSS, and standard CSS. Your level of CSS support depends on the chosen renderer.

Layout Support

FeatureTakumiSatoriBrowser
Flexbox✅✅✅
CSS Grid✅✅✅
Block/Inline✅✅✅
Position Absolute✅✅✅

Satori layout: Satori 0.47.1 or later supports block, inline, flexbox, and grid layout. Bare elements use native HTML layout defaults. Use display: flex and flex-direction: column when you need a flex column.

Use the Browser renderer when you need browser CSS behavior.

Build-time Transformations

Nuxt OG Image performs "automagic" CSS transformations during the build process to ensure cross-renderer compatibility.

CSS Downleveling & Polyfills

The module uses Lightning CSS to process styles for simpler renderers like Satori:

  • Color Downleveling: Automatically converts modern colors (oklch(), lab(), p3) to standard hex or rgba().
  • Logical Properties: Expands properties like padding-inline and margin-block to physical counterparts.
  • Individual Transforms: Preserves native translate, rotate, and scale properties.
  • Color Mix: Evaluates and replaces color-mix() functions with static color values.
  • Calc Evaluation: Resolves simple calc() expressions at build time.

Unsupported Classes

The build process filters out utility classes that static renderers don't support, such as animations and transitions, to prevent rendering errors.

Tailwind CSS & UnoCSS

Use Tailwind/UnoCSS classes directly in your templates without extra configuration.

<div class="bg-blue-500 text-white p-12 flex flex-col items-center justify-center">
  <h1 class="text-6xl font-bold shadow-xl">Hello World</h1>
</div>

The module extracts classes from your OG components at build time and compiles them using your project's CSS engine.

Theme Customizations

The module automatically resolves custom theme values, including Tailwind v4 variables defined in your @theme block:

assets/css/main.css
@import "tailwindcss";

@theme {
  --color-brand: #ff6600;
}
<template>
  <div class="bg-brand text-white">
    Custom Theme Classes!
  </div>
</template>

Auto-detection

The module automatically detects your CSS framework:

  • Tailwind v4: Active if you install tailwindcss and use @import "tailwindcss" in your CSS.
  • UnoCSS: Active if you enable @unocss/nuxt.
  • Nuxt UI v3: Automatically imports colors and theme variables.

Theme Switching (data-theme)

By default, OG images render with dark-mode semantic tokens (e.g. Nuxt UI's bg-inverted, text-default). To opt into theme-aware token resolution, set data-theme on the root element of your component. Tailwind v4 only.

Static data-theme

Hard-code a theme on the root element:

components/OgImage/MyImage.satori.vue
<template>
  <div data-theme="light" class="w-full h-full bg-default text-default p-10">
    <div class="bg-inverted text-inverted p-6 rounded-lg">
      Light mode tokens
    </div>
  </div>
</template>

Semantic tokens like bg-inverted, text-muted, border-accented resolve against the chosen theme: data-theme="light" produces light-mode values, data-theme="dark" produces dark-mode values.

Dynamic data-theme (per-image color mode)

Bind :data-theme to a prop to swap themes per OG image:

components/OgImage/MyImage.satori.vue
<script lang="ts" setup>
defineProps<{ colorMode?: 'light' | 'dark' }>()
</script>

<template>
  <div :data-theme="colorMode" class="w-full h-full bg-default text-default p-10">
    <div class="bg-inverted text-inverted p-6 rounded-lg">
      hello {{ colorMode }}
    </div>
  </div>
</template>
pages/light.vue
<script setup lang="ts">
defineOgImage('MyImage', { colorMode: 'light' })
</script>
pages/dark.vue
<script setup lang="ts">
defineOgImage('MyImage', { colorMode: 'dark' })
</script>

When the build detects a :data-theme binding on the root element, it resolves classes for both themes at build time and emits paired bg-[#...] dark:bg-[#...] arbitrary classes. The renderer then picks the correct value based on the colorMode prop you pass to defineOgImage.

The dynamic binding only works on the root element of the OG component. Nested elements inherit the resolved theme from the build pass.
Templates that don't set data-theme keep the existing dark-mode default; this feature is opt-in and non-breaking.

Inline Styles

Use the :style binding for dynamic values that change based on props.

<template>
  <div :style="{ backgroundColor: themeColor }" class="w-full h-full flex items-center justify-center">
    <h1 style="color: white; font-size: 80px;">
      {{ title }}
    </h1>
  </div>
</template>

<style> tag support

You can use scoped or global <style> tags within your components. The module processes and applies these directly to the rendered image.

Standard CSS selectors work across all renderers, though Satori has limited support for advanced selectors like :nth-child or complex combinators.
Was this page helpful?