Maileditor Docs

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

.env
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.0

Do 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

src/routes/editor/+page.server.ts
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

src/routes/editor/+page.svelte
<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_id to 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.error in the session response. See Error codes.

On this page