Next.js App Router integration

Build a client-safe email editor in Next.js

Embed the MailLayers React SDK in a Next.js App Router client component while keeping authentication, embed-token issuance, and persistence in server-only code.

Published on npm

Version 0.2.2 · Install from npm or review the source on GitHub.

npm install @maillayers/react-email-editor
Next.js App Router client component
"use client";

import { MailLayersEmailEditor } from "@maillayers/react-email-editor";

export function EmailEditorClient({ embedToken }: { embedToken: string }) {
  return (
    <MailLayersEmailEditor
      apiKey={process.env.NEXT_PUBLIC_MAILLAYERS_API_KEY!}
      embedToken={embedToken}
      initialHtml="<h1>Welcome</h1>"
      onSave={(html) => saveTemplate(html)}
    />
  );
}

Production integration

Content, assets, security, and lifecycle

A useful embedded email editor is more than a mounted component. Plan the persistence and trust boundaries before connecting it to customer data.

Editor data methods

Use getHtml() for a sendable snapshot and getJson() for structured editor state. Call reload() only when staged content or configuration should start a new iframe handshake; use ready, load, change, save, and status callbacks for normal updates.

Assets

Implement upload, list, and delete handlers against storage owned by your application. Validate file type and size on the server, authorize each tenant-scoped object, return HTTPS URLs, and treat delete as an authenticated operation.

API keys and allowed domains

Use a browser SDK key only from an exact configured origin. Keep privileged secrets on your server, issue scoped embed tokens after authenticating the user, and do not treat iframe messages as trusted until origin and payload validation pass.

Multiple instances

Give each mounted editor stable state and separate callbacks. Avoid reusing one imperative ref across instances, and unmount inactive editors when tabs or routes no longer need them so listeners and iframe resources are released.

Performance

Reserve editor height to prevent layout shift, defer mounting until the authoring UI is needed, and show a stable loading fallback. Avoid remounting the iframe for ordinary form-state changes; prefer events and staged reloads.

Troubleshooting

If the editor does not become ready, verify the allowed origin, browser key, embed-token lifetime, editor URL, and Content Security Policy. For missing saves, inspect callback errors and confirm the host persistence request succeeds independently of the iframe.

Integration

Keep the browser boundary explicit in the App Router

  1. 01

    Place the editor wrapper in a file with the use client directive. The package import is SSR-safe, but the hosted iframe component must mount in a browser.

  2. 02

    Read privileged credentials only in a route handler, server action, or server component. Pass a scoped, short-lived embed token into the client component; never expose a server secret through NEXT_PUBLIC_*.

  3. 03

    Persist HTML and template JSON through authenticated server code. If the editor is loaded dynamically, provide a stable loading fallback with the same approximate height to avoid layout shift.

Relevant capabilities

What this integration actually supports

App Router boundary
A small client component keeps the rest of the route server-rendered and indexable.
SSR-safe package import
The package can be imported during server compilation; only the visual editor mounting is browser-only.
Server-owned persistence
Route handlers or server actions validate the signed-in user before saving HTML or JSON.

Product boundary: Next.js uses @maillayers/react-email-editor; there is no separate Next.js package. MailLayers supplies the hosted editing surface while your application owns authentication, data, assets, and delivery.

Related integration guides

Engineering articles

Read implementation notes about editor security, persistence, asset workflows, and framework-specific patterns.

Browse the MailLayers blog

FAQ

Questions specific to this integration

Do I need next/dynamic with ssr: false?

Not always. A client component is the primary boundary because the package import is SSR-safe. A dynamic client-only import is still useful when you want to defer the editor bundle.

Where should the API key live?

Only a browser SDK key may use a NEXT_PUBLIC variable. Privileged credentials and embed-token signing stay in server-only environment variables.

Does the editor page lose server rendering?

No. Keep the page and surrounding content as server components and isolate only the editor wrapper behind the client boundary.

Continue with the verified integration guide

Review licensing, allowed domains, events, assets, SSR boundaries, and troubleshooting before production use.