The SDK exposes two rendering surfaces: a full-control render() method and three convenience shorthand methods.

Convenience methods

The fastest way to render. Each returns the output string directly.

// Render as HTML
$html = $client->renderHtml('template-id');

// Render as React Email (TSX)
$tsx = $client->renderReact('template-id');

// Render as MJML
$mjml = $client->renderMjml('template-id');

All three accept an optional second $dynamicData array argument:

$html = $client->renderHtml('template-id', [
    'merge_tags' => ['text' => ['name' => 'Noruwa']],
    'context'    => ['plan' => 'pro'],
]);

render() — full control

Use render() when you need the full result object or want to specify the target dynamically.

$result = $client->render([
    'templateId'  => '550e8400-e29b-41d4-a716-446655440000',
    'target'      => 'html',   // 'html' | 'react-email' | 'mjml'
    'dynamicData' => [
        'merge_tags' => ['text' => ['name' => 'Noruwa']],
        'context'    => ['plan' => 'pro'],
    ],
]);

echo $result->output;    // rendered string
echo $result->target;    // 'html'
$result->fromStaleCache; // true if rendered from a stale cached copy

render() options array

Key Type Required Description

templateId

string (UUID)

The template to render.

target

string

'html' (default), 'react-email', or 'mjml'.

dynamicData

array

Merge tags and context values. See Dynamic Data.

RenderResult

Property Type Description

output

string

The rendered template string.

target

string

The target format used ('html', 'react-email', or 'mjml').

fromStaleCache

bool

true when the template was rendered from a stale cached copy because the Maildeno server was unreachable. false on a normal render.

fromStaleCache is only available on the object returned by render() — the convenience methods resolve to the output string directly. See Caching for how the cache and stale-on-error fallback work.

Choosing a target dynamically

function renderFor(MaildenoClient $client, string $templateId, string $target, string $name)
{
    return $client->render([
        'templateId'  => $templateId,
        'target'      => $target,
        'dynamicData' => ['merge_tags' => ['text' => ['name' => $name]]],
    ]);
}

$html  = renderFor($client, 'template-id', 'html', 'Noruwa');
$react = renderFor($client, 'template-id', 'react-email', 'Noruwa');
$mjml  = renderFor($client, 'template-id', 'mjml', 'Noruwa');

Without dynamic data

If your template has no merge tags or visibility rules, omit dynamicData/the second argument entirely:

$html = $client->renderHtml('template-id');
// or
$result = $client->render(['templateId' => 'template-id']);

Low-level: the engine directly

Skip the API/cache entirely and render an already-fetched template array with the bundled engine:

use Maildeno\NativeEngine;

$engine = new NativeEngine(NativeEngine::locate());
$html   = $engine->renderTemplate($templateArray, 'html', $dynamicData);

Useful for testing, or if you’re fetching/caching template JSON yourself. NativeEngine takes an optional timeoutSeconds (default 30) for the subprocess call:

$engine = new NativeEngine('/path/to/maildeno-engine', timeoutSeconds: 10.0);