> ## Documentation Index
> Fetch the complete documentation index at: https://vuemail.dev/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Email Theming

> Apply and customize visual themes for email output.

## Quick start

Import the `EmailTheming` plugin and add it to your extensions:

```vue theme={null}
<script setup lang="ts">
import { EditorProvider } from '@vuemaildev/editor';
import { StarterKit } from '@vuemaildev/editor/extensions';
import { EmailTheming } from '@vuemaildev/editor/plugins';
import { BubbleMenu } from '@vuemaildev/editor/ui';
import '@vuemaildev/editor/themes/default.css';

const extensions = [StarterKit, EmailTheming];
</script>

<template>
  <EditorProvider :extensions="extensions" :content="content">
    <BubbleMenu />
  </EditorProvider>
</template>
```

## How theming works

Themes are CSS-in-JS style objects that map to email component types (headings, paragraphs,
links, buttons, etc.). Each theme defines a set of `CSSProperties` for every supported
component.

During [`composeVueEmail`](https://vuemail.dev/docs/editor/api-reference/compose-vue-email), the `EmailTheming`
plugin acts as a `SerializerPlugin` that resolves styles for each node based on its type and
depth in the document tree. These styles are then **inlined directly** onto the rendered Vuemail
components as `style` attributes. This is necessary because email clients don't
reliably support `<style>` tags or external stylesheets.

The resolved styles are passed to each node's `renderToVueEmail()` method via the `style`
prop, where they can be spread onto the rendered element.

## Built-in themes

The editor ships with two themes:

| Theme | Description |
| - | - |
| `'basic'` | Full styling: typography, spacing, borders, and visual hierarchy. This is the **default**. |
| `'minimal'` | Essentially no styles. Gives you a blank slate to build your own look from scratch. |

Select a theme with `.configure()`:

```ts theme={null}
const extensions = [StarterKit, EmailTheming.configure({ theme: 'basic' })];
```

## Switching themes dynamically

Use a ref to toggle themes at runtime. Key the `EditorProvider` on the theme to apply the new one:

```vue theme={null}
<script setup lang="ts">
import { EditorProvider } from '@vuemaildev/editor';
import { StarterKit } from '@vuemaildev/editor/extensions';
import { EmailTheming } from '@vuemaildev/editor/plugins';
import { BubbleMenu } from '@vuemaildev/editor/ui';
import { computed, ref } from 'vue';

type EditorTheme = 'basic' | 'minimal';

const theme = ref<EditorTheme>('basic');
const extensions = computed(() => [
  StarterKit,
  EmailTheming.configure({ theme: theme.value }),
]);
</script>

<template>
  <div>
    <div :style="{ display: 'flex', gap: '8px', marginBottom: '16px' }">
      <button type="button" @click="theme = 'basic'">Basic</button>
      <button type="button" @click="theme = 'minimal'">Minimal</button>
    </div>
    <EditorProvider :key="theme" :extensions="extensions" :content="content">
      <BubbleMenu />
    </EditorProvider>
  </div>
</template>
```

> [!NOTE]
>
> The `:key="theme"` on `EditorProvider` makes Vue mount a new editor when the theme changes,
> ensuring the new theme is applied cleanly. `EmailEditor` does this on its own when its `theme` prop changes.

## Custom themes

Instead of being limited to built-in presets, you can define custom themes using a CSS-in-JS
object that maps component names to styles.

### Extending a built-in theme

Use `extendTheme` to start from a built-in theme and override specific styles:

```vue theme={null}
<script setup lang="ts">
import { EditorProvider } from '@vuemaildev/editor';
import { StarterKit } from '@vuemaildev/editor/extensions';
import { EmailTheming, extendTheme } from '@vuemaildev/editor/plugins';

const brandTheme = extendTheme('basic', {
  body: { backgroundColor: '#eff6ff' },
  h1: { color: '#1e40af', fontSize: '28px' },
  button: { backgroundColor: '#2563eb', color: '#fff', borderRadius: '6px' },
  link: { color: '#2563eb' },
});

const extensions = [StarterKit, EmailTheming.configure({ theme: brandTheme })];
</script>

<template>
  <EditorProvider :extensions="extensions" :content="content">
    <!-- ... -->
  </EditorProvider>
</template>
```

### Creating a theme from scratch

Use `createTheme` to build a theme without inheriting from a built-in preset.
When no `extends` is set, the `minimal` reset is used as a base:

```ts theme={null}
import { createTheme } from '@vuemaildev/editor/plugins';

const darkTheme = createTheme({
  body: { backgroundColor: '#1a1a2e', color: '#e2e8f0' },
  container: { backgroundColor: '#16213e', color: '#e2e8f0' },
  h1: { color: '#e2e8f0' },
  link: { color: '#60a5fa' },
  button: { backgroundColor: '#3b82f6', color: '#fff', borderRadius: '4px' },
});
```

### Passing a theme config inline

You can also pass a `ThemeConfig` object directly to the `theme` prop without using the
helper functions:

```vue theme={null}
<EmailEditor
  :theme="{
    extends: 'basic',
    styles: {
      body: { backgroundColor: '#f4f4f5' },
      button: { backgroundColor: '#0670DB' },
    },
  }"
/>
```

> [!NOTE]
>
> Custom theme values appear in the inspector UI, and users can still tweak them
> interactively. The inspector doesn't distinguish between built-in and custom values.

## Theme components

Themes define styles for the following email components:

| Component | Description |
| - | - |
| `reset` | CSS reset styles |
| `body` | Email body wrapper |
| `container` | Content container |
| `h1` | Level 1 heading |
| `h2` | Level 2 heading |
| `h3` | Level 3 heading |
| `paragraph` | Text paragraphs |
| `list` | Ordered and unordered lists |
| `listItem` | Individual list items |
| `listParagraph` | Paragraphs inside list items |
| `nestedList` | Nested list styles |
| `blockquote` | Block quotes |
| `codeBlock` | Code blocks |
| `inlineCode` | Inline code |
| `link` | Hyperlinks |
| `button` | Email buttons |
| `section` | Content sections |
| `footer` | Footer area |
| `hr` | Horizontal rules |
| `image` | Images |

## Theme-aware serialization

When `EmailTheming` is in your extensions array, the `composeVueEmail` function automatically
applies theme styles to the exported HTML. No extra configuration is needed.

```ts theme={null}
import { composeVueEmail } from '@vuemaildev/editor/core';

// Theme styles are automatically injected into the HTML output
const { html, text } = await composeVueEmail({ editor });
```

See [Email Export](https://vuemail.dev/docs/editor/features/email-export.md) for more details on the serialization pipeline.

## Examples

See theming in action with a runnable example:

> **[Email Theming](https://vuemail.dev/editor/email-theming)**
>
> Basic/Minimal/Custom theme toggle with live preview.

> **[Custom Themes](https://vuemail.dev/editor/custom-theme)**
>
> Define custom themes with createTheme and extendTheme.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.