A lightweight, production-ready Svelte wrapper around Unlayer's embeddable email editor. Built with Svelte 5, TypeScript, and modern development practices.
npm install unlayer-svelte-sdk
<script lang="ts">
import UnlayerEditor from 'unlayer-svelte-sdk';
</script>
<UnlayerEditor />
<script lang="ts">
import UnlayerEditor from 'unlayer-svelte-sdk';
import type { Design } from 'unlayer-svelte-sdk';
let initialDesign: Design = {
body: {
rows: [
{
cells: [
{
content: {
blocks: [
{
type: "text",
data: {
text: "Hello World!",
textAlign: "center",
fontSize: "24px"
}
}
]
}
}
]
}
]
}
};
function handleExport(event: CustomEvent<{ html: string; design: Design }>) {
const { html, design } = event.detail;
console.log('HTML:', html);
console.log('Design:', design);
}
</script>
<UnlayerEditor
design={initialDesign}
on:export-html={handleExport}
/>
<script lang="ts">
import UnlayerEditor from 'unlayer-svelte-sdk';
let editorRef: UnlayerEditor;
async function exportHtml() {
const result = await editorRef.exportHtml();
console.log(result.html);
}
function loadDesign(design: Design) {
editorRef.loadDesign(design);
}
</script>
<UnlayerEditor bind:this={editorRef} />
Prop | Type | Default | Description |
---|---|---|---|
design |
Design |
undefined |
Initial design JSON to load into the editor |
tools |
ToolConfig |
undefined |
Tool whitelist/blacklist configuration |
options |
UnlayerOptions |
{} |
Unlayer initialization options |
autoLoad |
boolean |
true |
Automatically load design on mount and prop changes |
class |
string |
'' |
CSS class for styling |
Event | Detail | Description |
---|---|---|
loaded |
{ editor: UnlayerEditor } |
Fired when the editor is ready |
design-updated |
{ design: Design } |
Fired when design changes |
export-html |
{ html: string; design: Design } |
Fired when HTML is exported |
error |
{ message: string } |
Fired when editor encounters an error |
The component exposes the following methods via binding:
interface UnlayerEditorMethods {
exportHtml(): Promise<{ html: string; design: Design }>;
loadDesign(newDesign: Design): void;
saveDesign(): Promise<Design>;
retryLoad(): void;
}
<UnlayerEditor
options={{
displayMode: 'email',
locale: 'en-US',
features: {
preview: true,
imageEditor: true,
stockImages: true
}
}}
/>
<UnlayerEditor
tools={{
image: { enabled: true, position: 1 },
text: { enabled: true, position: 2 },
button: { enabled: true, position: 3 }
}}
/>
<UnlayerEditor
options={{
customCSS: ['.custom-class { color: red; }'],
customJS: ['console.log("Editor loaded!");'],
features: {
textEditor: {
spellChecker: true,
thesaurus: true
}
}
}}
/>
UnlayerEditor.svelte
โโโ Props Interface (design, tools, options, autoLoad, class)
โโโ Event Dispatcher (loaded, design-updated, export-html, error)
โโโ Internal State Management
โโโ Unlayer Script Loading (CDN with fallbacks)
โโโ Editor Initialization
โโโ Method Exports (exportHtml, loadDesign, saveDesign, retryLoad)
โโโ Lifecycle Management (onMount, onDestroy)
git clone <repository-url>
cd unlayer-svelte-sdk
npm install
npm run dev
- Start demo development servernpm run build
- Build library for distributionnpm run build:demo
- Build demo applicationnpm run check
- Type checking and validationnpm run package
- Create NPM packageunlayer-svelte-sdk/
โโโ src/
โ โโโ lib/
โ โ โโโ UnlayerEditor.svelte # Main component
โ โโโ types/
โ โ โโโ unlayer.d.ts # Type definitions
โ โโโ assets/
โ โ โโโ welcome.json # Sample design
โ โโโ App.svelte # Demo application
โ โโโ index.ts # Package exports
โ โโโ main.ts # Demo entry point
โโโ dist/ # Library build output
โโโ dist-demo/ # Demo build output
โโโ package.json # Package configuration
โโโ vite.config.ts # Library build config
โโโ vite.demo.config.ts # Demo build config
โโโ tsconfig.build.json # Library TypeScript config
โโโ README.md # Documentation
<script lang="ts">
function handleError(event: CustomEvent<{ message: string }>) {
console.error('Editor error:', event.detail.message);
// Show user-friendly error message
}
</script>
<UnlayerEditor on:error={handleError} />
<script lang="ts">
let isEditorReady = false;
function handleLoaded(event: CustomEvent<{ editor: any }>) {
isEditorReady = true;
}
</script>
{#if isEditorReady}
<UnlayerEditor on:loaded={handleLoaded} />
{:else}
<div>Loading editor...</div>
{/if}
<script lang="ts">
let currentDesign: Design;
function handleDesignUpdate(event: CustomEvent<{ design: Design }>) {
currentDesign = event.detail.design;
// Save to localStorage or send to server
}
</script>
<UnlayerEditor
design={currentDesign}
on:design-updated={handleDesignUpdate}
/>
The repository includes a complete demo application showcasing all features:
# Build the library
npm run build
# Build the demo
npm run build:demo
# Create NPM package
npm run package
MIT License - see LICENSE file for details.
git checkout -b feature/amazing-feature
)git commit -m 'Add amazing feature'
)git push origin feature/amazing-feature
)Built with โค๏ธ using Svelte 5 and Unlayer Email Editor
This project follows the Conventional Commits specification for commit messages.