A modern, TypeScript-first Svelte wrapper for the Unlayer email editor.
npm install @mmuneebahmad/unlayer-svelte-wrapper
<script>
import { UnlayerEditor } from '@mmuneebahmad/unlayer-svelte-wrapper';
let editor;
let isEditorReady = false;
function handleEditorLoaded(event) {
isEditorReady = true;
console.log('Editor loaded:', event.detail.editor);
}
async function exportDesign() {
if (editor && isEditorReady) {
const data = await editor.exportHtml();
console.log('Exported:', data);
}
}
</script>
<div style="height: 600px;">
<UnlayerEditor
bind:this={editor}
options={{ displayMode: 'email' }}
on:loaded={handleEditorLoaded}
/>
</div>
<button on:click={exportDesign} disabled={!isEditorReady}>
Export Design
</button>
Prop | Type | Default | Description |
---|---|---|---|
design |
UnlayerDesign | null |
null |
Initial design JSON to load |
tools |
Record<string, any> | null |
null |
Tool whitelist/blacklist configuration |
options |
UnlayerOptions |
{} |
Unlayer initialization options |
Event | Payload | Description |
---|---|---|
loaded |
{ editor: UnlayerInstance } |
Fired when editor is ready |
design-updated |
UnlayerDesign |
Fired when design changes |
export-html |
ExportData |
Fired when HTML is exported |
Method | Parameters | Returns | Description |
---|---|---|---|
exportHtml() |
dispatchEvent?: boolean |
Promise<ExportData> |
Export current design as HTML |
loadDesign() |
design: UnlayerDesign |
void |
Load a design into the editor |
saveDesign() |
- | Promise<UnlayerDesign> |
Get current design JSON |
isReady() |
- | boolean |
Check if editor is ready |
getEditor() |
- | UnlayerInstance | null |
Get raw editor instance |
A pre-built modal for handling design exports.
Prop | Type | Default | Description |
---|---|---|---|
show |
boolean |
false |
Whether modal is visible |
exportData |
ExportData | null |
null |
Export data to display |
Event | Payload | Description |
---|---|---|
close |
void |
Fired when modal is closed |
download |
DownloadEvent |
Fired when download is triggered |
<script>
import { UnlayerEditor } from '@mmuneebahmad/unlayer-svelte-wrapper';
const editorOptions = {
displayMode: 'email',
projectId: 1234,
locale: 'en-US',
appearance: {
theme: 'light',
panels: {
tools: {
dock: 'left'
}
}
},
tools: {
enabled: ['text', 'image', 'button'],
disabled: ['video']
},
mergeTags: [
{
name: 'First Name',
value: '{{first_name}}',
sample: 'John'
}
]
};
</script>
<UnlayerEditor options={editorOptions} />
<script>
import { UnlayerEditor, ExportModal } from '@mmuneebahmad/unlayer-svelte-wrapper';
let editor;
let showExportModal = false;
let exportData = null;
async function handleExport() {
if (editor) {
exportData = await editor.exportHtml();
showExportModal = true;
}
}
</script>
<UnlayerEditor bind:this={editor} />
<button on:click={handleExport}>Export</button>
<ExportModal
bind:show={showExportModal}
{exportData}
on:download={(e) => console.log('Downloaded:', e.detail)}
/>
<script>
import { UnlayerEditor, createSampleDesign } from '@mmuneebahmad/unlayer-svelte-wrapper';
const initialDesign = createSampleDesign();
</script>
<UnlayerEditor design={initialDesign} />
The package includes comprehensive TypeScript definitions:
import type {
UnlayerOptions,
UnlayerDesign,
ExportData,
EditorLoadedEvent
} from '@mmuneebahmad/unlayer-svelte-wrapper';
const options: UnlayerOptions = {
displayMode: 'email',
projectId: 123
};
function handleLoaded(event: CustomEvent<EditorLoadedEvent>) {
const editor = event.detail.editor;
// editor is fully typed
}
The component fills its parent container. Ensure the parent has defined dimensions:
<div class="editor-container">
<UnlayerEditor />
</div>
<style>
.editor-container {
width: 100%;
height: 600px; /* or 100vh for full height */
}
</style>
The component includes built-in error handling with retry functionality:
<UnlayerEditor
on:loaded={handleLoaded}
on:error={handleError}
/>
git checkout -b feature/amazing-feature
)git commit -m 'Add some amazing feature'
)git push origin feature/amazing-feature
)MIT ยฉ [Muneeb Ahmad]
See CHANGELOG.md for details.