Skip to main content

Overview

The Renderer class is the core of Better Svelte Email. It converts Svelte components into email-safe HTML with fully inlined Tailwind CSS styles, ensuring maximum compatibility across email clients.

Import

import Renderer from 'better-svelte-email/renderer';

Constructor

The Renderer constructor supports two overloads for backward compatibility:

Constructor Overload 1: With RendererOptions

new Renderer(options?: RendererOptions)
options
RendererOptions
Configuration options for the renderer. See RendererOptions for details.

Constructor Overload 2: Legacy TailwindConfig (Deprecated)

new Renderer(tailwindConfig?: TailwindConfig)
tailwindConfig
TailwindConfig
Tailwind CSS configuration object (v3). This overload is maintained for backward compatibility. Use the RendererOptions overload instead.
The constructor automatically detects which overload you’re using based on the argument provided. If the object contains tailwindConfig, customCSS, or baseFontSize properties, it’s treated as RendererOptions. Otherwise, it’s treated as a legacy TailwindConfig.

Methods

render()

Renders a Svelte component to email-safe HTML with inlined Tailwind CSS.
render(component: any, options?: RenderOptions): Promise<string>
component
any
required
The Svelte component to render. Import your .svelte file and pass it directly.
options
RenderOptions
Options for rendering the component. See RenderOptions for details.
return
Promise<string>
A promise that resolves to an email-safe HTML string with inlined styles and XHTML 1.0 Transitional DOCTYPE.

What render() does automatically

The render() method performs several transformations to ensure email compatibility:
  • Inlines Tailwind classes - Converts all Tailwind utility classes to inline style attributes
  • Extracts media queries - Places non-inlinable styles (responsive classes, pseudo-classes) into a <style> tag in the <head>
  • Replaces DOCTYPE - Changes DOCTYPE to XHTML 1.0 Transitional for better email client compatibility
  • Removes comments - Strips HTML comments from the output
  • Cleans Svelte artifacts - Removes Svelte-specific attributes and markers
  • Resolves CSS variables - Resolves custom properties defined in customCSS or Tailwind config
  • Applies global styles - Inlines styles from global selectors (*, element selectors, :root)
If you use non-inlinable Tailwind classes (like responsive utilities or hover states), your component must include a <head> element. The renderer will inject a <style> tag with media queries into it. Without a <head>, the render will throw an error.

Usage Examples

Basic usage

import Renderer from 'better-svelte-email/renderer';
import WelcomeEmail from '$lib/emails/welcome.svelte';

const renderer = new Renderer();
const html = await renderer.render(WelcomeEmail);

With custom Tailwind configuration

import Renderer from 'better-svelte-email/renderer';
import EmailComponent from '$lib/emails/email.svelte';

const renderer = new Renderer({
  tailwindConfig: {
    theme: {
      extend: {
        colors: {
          brand: '#FF3E00'
        }
      }
    }
  }
});

const html = await renderer.render(EmailComponent);

With custom CSS (e.g., app theme variables)

import Renderer from 'better-svelte-email/renderer';
import EmailComponent from '$lib/emails/email.svelte';
import layoutStyles from 'src/routes/layout.css?raw';

const renderer = new Renderer({
  customCSS: layoutStyles
});

const html = await renderer.render(EmailComponent);

With component props

import Renderer from 'better-svelte-email/renderer';
import PasswordReset from '$lib/emails/password-reset.svelte';

const renderer = new Renderer();
const html = await renderer.render(PasswordReset, {
  props: {
    username: 'john_doe',
    resetUrl: 'https://example.com/reset?token=abc123'
  }
});

Complete example with all options

import Renderer from 'better-svelte-email/renderer';
import EmailComponent from '$lib/emails/email.svelte';
import layoutStyles from 'src/routes/layout.css?raw';

const renderer = new Renderer({
  tailwindConfig: {
    theme: {
      extend: {
        colors: {
          brand: '#FF3E00'
        }
      }
    }
  },
  customCSS: layoutStyles,
  baseFontSize: 16
});

const html = await renderer.render(EmailComponent, {
  props: { name: 'John' }
});

Using CSS variables with @property

import Renderer from 'better-svelte-email/renderer';
import EmailComponent from '$lib/emails/email.svelte';

const renderer = new Renderer({
  tailwindConfig: {
    theme: {
      extend: {
        colors: {
          'custom-color': 'var(--my-color)'
        }
      }
    }
  },
  customCSS: '@property --my-color { syntax: "<color>"; inherits: false; initial-value: #00ff00; }'
});

const html = await renderer.render(EmailComponent);

Type Definitions

export type TailwindConfig = Omit<Config, 'content'>;

export default class Renderer {
  constructor(tailwindConfig?: TailwindConfig);
  constructor(options?: RendererOptions);
  
  render(component: any, options?: RenderOptions): Promise<string>;
}

See Also

Build docs developers (and LLMs) love