PluginPlatform guides
Svelte
A SvelteKit server load function that returns a signed editor URL to the page.
In SvelteKit a +page.server.ts load function runs on the server for every request, so it can sign the user id and hand the finished URL to the page. No API route and no client-side fetch are needed.
Before you start
Follow the first three steps of the quickstart: create a plugin, add localhost:5173 to its allowed domains, and copy the Plugin ID and Secret.
Configuration
MAILEDITOR_PLUGIN_ID=9f3c1e7a-4b21-4c8e-9a77-1d2f5b6c8e10
MAILEDITOR_PLUGIN_SECRET=your_plugin_secret
MAILEDITOR_EDITOR_BASE_URL=https://maileditor.net
MAILEDITOR_PLUGIN_VERSION=1.0.0Do not prefix these with PUBLIC_. SvelteKit only exposes $env/static/private to server code, which is what keeps the secret out of the browser.
Sign on the server
import { createHmac } from 'node:crypto'
import {
MAILEDITOR_EDITOR_BASE_URL,
MAILEDITOR_PLUGIN_ID,
MAILEDITOR_PLUGIN_SECRET,
MAILEDITOR_PLUGIN_VERSION,
} from '$env/static/private'
import type { PageServerLoad } from './$types'
export const load: PageServerLoad = () => {
const userId = 'customer-user-4471'
const expires = Math.floor(Date.now() / 1000) + 300
const payload = `v1|${Buffer.byteLength(userId)}:${userId}|${expires}`
const signature = createHmac('sha256', MAILEDITOR_PLUGIN_SECRET)
.update(payload)
.digest('hex')
const params = new URLSearchParams({
external_user_id: userId,
identity_expires: String(expires),
identity_signature: signature,
plugin_version: MAILEDITOR_PLUGIN_VERSION,
})
return {
src: `${MAILEDITOR_EDITOR_BASE_URL}/plugin-editor/v1/${MAILEDITOR_PLUGIN_ID}?${params}`,
}
}Replace userId with the signed-in user's id, typically from locals populated in hooks.server.ts.
Render the iframe
<script lang="ts">
let { data } = $props();
</script>
<iframe
src={data.src}
title="Email editor"
allow="clipboard-write; fullscreen"
style="width: 100%; height: 100vh; border: 0"
></iframe>On Svelte 4, use export let data; instead of $props().
Next steps
- Add
template_idto the query string to open one of the user's saved templates. See Embedding the editor. - If the iframe shows "Plugin editor unavailable", read
result.errorin thesessionresponse. See Error codes.

.png)