Skip to content

DevelopersMailblocks SDK

Everything you need to embed the editor. If something is missing, write to us and we will add it here.

Quick start

Add the loader, give the editor an element with a height, and mount it with your public key. You find the key in your dashboard under Plugin.

<div id="editor" style="height: 720px"></div>

<script src="https://customer.mailblocks.app/sdk/v1.js"></script>
<script>
  const editor = Mailblocks.mount('#editor', {
    publicKey: 'pk_live_…',
    user: { id: 'user-42' },
    design: savedDesign,            // optional: design JSON or MJML
    placeholders: [
      { label: 'Contact', items: [{ label: 'First name', value: '{{first_name}}' }] },
    ],
    onReady: ({ plan }) => console.log('Editor ready on', plan),
    onSave: ({ html, design }) => saveTemplate({ html, design }),
    onError: ({ code, message }) => console.warn(code, message),
  });
</script>

React and Vue

The SDK has no dependencies, so wrap it the way you wrap any widget: mount on first render, destroy on unmount.

import { useEffect, useRef } from 'react';

export function EmailEditor({ user, design, onSave }) {
  const element = useRef(null);

  useEffect(() => {
    const editor = window.Mailblocks.mount(element.current, {
      publicKey: process.env.NEXT_PUBLIC_MAILBLOCKS_KEY,
      user: { id: user.id, signature: user.mailblocksSignature },
      design,
      onSave,
    });

    return () => editor.destroy();
  }, []);

  return <div ref={element} style={{ height: 720 }} />;
}

Options

Only publicKey and user.id are required.

OptionTypeDescription
publicKeystringYour licence public key (pk_live_…). Safe to use in the browser.
userobject{ id, signature? } identifying the person editing. The id counts towards monthly active users.
designstringA saved design JSON or an MJML template to open.
designIdstringA stable id for the design, used to offer restoring an unsaved draft.
localestringInterface language: en, es, fr, de, pt, ro or el.
placeholdersarrayMerge tags, flat or grouped: [{ label, items: [{ label, value, insert? }] }].
themeobjectColours, fonts and radius for the editor chrome. Applied on plans with white labelling.
storagestring | false | object"mailblocks" (default), false, or { endpoints, auth } for your own image storage.
toolbarobject{ save?: boolean, back?: boolean } to show or hide the toolbar buttons.
aifalse | objectfalse to hide the AI builder, or { presets, sentence, texts } to customise it.

Events

Pass callbacks as onReady, onSave and so on, or subscribe with editor.on(name, callback).

ready
The editor is loaded. Receives { plan, features, development }.
save
The user saved, or you called save(). Receives { html, design }.
change
The design changed since it was opened.
error
The editor could not start or load the design. Receives { code, message }.
back
The user pressed the back button.
generated
The AI builder produced a template. Receives { mjml }.

Methods

save()
Saves and resolves with { html, design }.
load()
Replaces the open design with a design JSON or an MJML template.
destroy()
Removes the editor and its listeners.
const { html, design } = await editor.save();

editor.load(previouslySavedDesign);

const stop = editor.on('change', () => markUnsaved());
stop();

editor.destroy();

Signed user ids

Sign the user id with your secret key on your server and pass the signature. Turn on “Require signed user ids” in your dashboard to refuse unsigned sessions. Never put the secret key in browser code.

// Laravel, in the controller that renders the page with the editor
$signature = hash_hmac('sha256', (string) $user->id, config('services.mailblocks.secret'));

return view('templates.edit', [
    'mailblocksUser' => ['id' => (string) $user->id, 'signature' => $signature],
]);

Domains

Add every host name that runs the editor in your dashboard. localhost, 127.0.0.1 and *.test, *.local and *.localhost always work and are not counted. Wildcards such as *.example.com cover every subdomain and are included from the Growth plan.

Image storage

By default images are stored by Mailblocks. To use your own storage, pass endpoints compatible with the file manager protocol and allow requests from the editor origin with CORS.

How the frame is protected

The editor runs in an iframe from our domain. It renders only for the origins on your licence, talks to your page through postMessage scoped to that origin, and its code is served through short-lived signed URLs.

Error codes

unauthorized_origin
The page is not on a domain authorised for this licence.
inactive_license
The trial ended or the licence is suspended.
active_user_limit_reached
This month’s active user allowance is used up.
invalid_user_signature
Signing is required, or the signature does not match the user id.
ticket_invalid
The editor took too long to start; reload it.