Description
When using Resend's REST API to send emails with template: { id, variables }, URL variables inside <a href> attributes are mangled, breaking the button/link rendering. The href attribute is replaced with <span data-type="variable"> wrappers that get HTML-entity-encoded, destroying the <a> tag structure.
Dashboard "Send test" works correctly — this only affects the REST API path.
Steps to Reproduce
- Create a React Email template with a link prop:
export default function ResetEmail({
customer_name = "there",
reset_link = "https://example.com/reset?token=preview",
}) {
return (
<BrandedLayout>
<Text>Hi {customer_name},</Text>
<Button href={reset_link}>Reset Password</Button>
</BrandedLayout>
);
}
-
Upload the template to Resend via the SDK
-
Send via REST API:
POST /emails
{
"from": "App <noreply@example.com>",
"to": ["user@example.com"],
"subject": "Reset Password",
"template": {
"id": "tmpl_xxx",
"variables": {
"customer_name": "Brandon",
"reset_link": "https://example.com/reset?token=abc123"
}
}
}
- The received email renders the link broken:
- The URL appears as visible text in its own styled block
- The button text is prefixed with
"> (e.g., ">Reset Password)
- The
href attribute is missing from the <a> tag
Debug Investigation
Fetching the stored template via GET /templates/{id} reveals the issue:
<!-- Expected -->
<a href="{{{reset_link}}}" style="..." target="_blank">Reset Password</a>
<!-- Actual (from GET /templates response) -->
<a href="<span data-type=" rel="noopener noreferrer nofollow" ...>
Resend's template storage converts the href URL into a <span data-type="variable"> wrapper, which gets HTML-entity-encoded (<span data-type="), breaking the <a> tag's attribute boundary.
Expected Behavior
The <a href> should preserve the {{{variable}}} placeholder cleanly:
<a href="{{{reset_link}}}" style="..." target="_blank">Reset Password</a>
Actual Behavior
The href attribute is replaced with a mangled <span> wrapper that breaks HTML structure. The URL renders as visible text, and the button shows ">Button Text.
Workaround
We bypass Resend's template variable system for link-based emails by building the HTML server-side and sending via the html field instead of template. Text-only variables (like customer_name) work correctly through the template system.
Environment
- React Email: latest
- Resend REST API (not SDK)
- Affects: Any template with
<Button href={prop}> or <a href={prop}>
- Text variables (e.g.,
{customer_name} in body text) work fine
- Dashboard "Send test email" with the same variables renders correctly
Related
Description
When using Resend's REST API to send emails with
template: { id, variables }, URL variables inside<a href>attributes are mangled, breaking the button/link rendering. Thehrefattribute is replaced with<span data-type="variable">wrappers that get HTML-entity-encoded, destroying the<a>tag structure.Dashboard "Send test" works correctly — this only affects the REST API path.
Steps to Reproduce
Upload the template to Resend via the SDK
Send via REST API:
">(e.g.,">Reset Password)hrefattribute is missing from the<a>tagDebug Investigation
Fetching the stored template via
GET /templates/{id}reveals the issue:Resend's template storage converts the
hrefURL into a<span data-type="variable">wrapper, which gets HTML-entity-encoded (<span data-type="), breaking the<a>tag's attribute boundary.Expected Behavior
The
<a href>should preserve the{{{variable}}}placeholder cleanly:Actual Behavior
The
hrefattribute is replaced with a mangled<span>wrapper that breaks HTML structure. The URL renders as visible text, and the button shows">Button Text.Workaround
We bypass Resend's template variable system for link-based emails by building the HTML server-side and sending via the
htmlfield instead oftemplate. Text-only variables (likecustomer_name) work correctly through the template system.Environment
<Button href={prop}>or<a href={prop}>{customer_name}in body text) work fineRelated