refract v0.1 · beta
Guides / Vue

Vue

Same shape as everywhere: a shared theme ref, a watcher that keeps theme.css injected, and getClass in templates. Shown with the Composition API and <script setup>.

1 · A theme ref + provide it

Hold the theme in a ref, provide it to the tree, and mirror theme.css into a <style> with watchEffect — so replacing the ref re-themes the app.

theme.ts
import { ref, type Ref, type InjectionKey } from "vue";
import { createTheme, type Theme } from "@theme-registry/refract";
import { createCssAdapter } from "@theme-registry/refract-css";
import { raw } from "./theme.config";

export const ThemeKey: InjectionKey<Ref<Theme>> = Symbol("theme");
export const createThemeRef = () => ref<Theme>(createTheme(raw, { adapter: createCssAdapter() }));
App.vue
<script setup lang="ts">
import { provide, watchEffect } from "vue";
import { ThemeKey, createThemeRef } from "./theme";

const theme = createThemeRef();
provide(ThemeKey, theme);

watchEffect(() => {                              // keep <style> in sync
  let el = document.getElementById("refract");
  if (!el) { el = document.createElement("style"); el.id = "refract"; document.head.appendChild(el); }
  el.textContent = theme.value.css;
});
</script>

<template><SaveButton /></template>

2 · Use a class

SaveButton.vue
<script setup lang="ts">
import { inject } from "vue";
import { ThemeKey } from "./theme";
const theme = inject(ThemeKey)!;
</script>

<template>
  <button :class="theme.getClass('components', 'buttons', 'primary')">Save</button>
</template>

3 · Switch themes

switch.ts
theme.value = base.override({ colors: { brand: { base: "#e8590c", text: "#ffffff" } } });
// watchEffect re-injects the new theme.css; every :class updates
For dark mode, author modes and toggle data-theme on <html> — a cascade flip, no re-inject. Nuxt / SSR: inject theme.css server-side (a useHead style entry), or emit it at build time and add it to global CSS.
Technical documentation for @theme-registry/refract · all output is compiled client-side by the real library (CSS adapter). The chrome is theme-aware; the render panes carry each preset's own world. · MIT licensed.