---
title: "Setting up Resend in a Lovable app | Lovable Field Guide"
url: https://prerenderlovable.com/blog/lovable-resend-email-setup
description: "The Lovable Resend setup that actually ships: what the shared connector can't do, the DNS you verify first, and the deliverability work nobody documents."
lang: en
---

Skip to content

# Setting up Resend in a Lovable app

The Lovable Resend setup that actually ships: what the shared connector can't do, the DNS you verify first, and the deliverability work nobody documents.

Published September 11, 2026 11 min read

Resend in Lovable is a connector you paste an API key into, and it will send email from your app almost immediately. The part that takes real work (and the part that decides whether anyone outside your own inbox ever receives anything) is the DNS work you have to finish in Resend first, because the connector cannot do it for you.

The short version:

- Resend is an **app + chat connector**: one shared connection, usable in Lovable chat during development and in your published app.
- **One Resend account is shared across every linked project.** There is no per-project key.
- You supply an API key prefixed `re_`, either **sending access** (dispatch only, optionally scoped to a single domain) or **full access**.
- The connector **cannot verify domains** and **cannot receive webhooks**. Both of those happen outside Lovable.
- Until you verify a domain, you are sending from `onboarding@resend.dev`, which only delivers to the Resend account owner. That is the single most common “it works for me but nobody else got it” bug.

## What the connector actually is

Lovable organizes integrations by connection type rather than by category, and Resend sits in the first type: an app + chat connector with shared credentials. That means the same connection is available to the agent while you build and to your app at runtime. You can ask Lovable in chat to send a test email, and the deployed app can call the Resend API using the same stored key.

Per Lovable’s Resend documentation (https://docs.lovable.dev/integrations/resend), generated apps can send HTML and plain-text transactional email with multiple recipients, cc, bcc and reply-to, attachments and tracking tags, and can query sending domains and email status. The limits are as important as the features:

| | Handled by the connector | Not handled: you do this yourself |
| --- | --- | --- |
| Sending | Transactional sends, cc/bcc/reply-to, attachments, tags | n/a |
| Domains | Query your sending domains | **Adding and verifying a domain** (Resend dashboard + DNS) |
| Events | Query an email’s status | **Receiving webhooks** (your own endpoint) |
| Accounts | One shared connection | **Per-project keys, per-user Resend auth** |

That last row deserves a moment. The connection is shared across every project you link it to, so your staging project and your production project send through the same Resend account, with the same key, against the same domain reputation. There is no environment boundary built in.

The wider picture of how Lovable wires third-party services (six connection types, what each one can reach) is in the Lovable integrations guide (https://prerenderlovable.com/blog/lovable-integrations).

## Step 1: verify your sending domain in Resend, before you touch Lovable

Lovable’s docs put it plainly: email reaches your app’s users only from a domain you have verified in Resend. The connector cannot do DNS and cannot run verification. So do this first, in the Resend dashboard, at your DNS provider.

Three record types matter, and they do different jobs.

**SPF** is a TXT record listing which servers may send for your domain. A receiving server checks the envelope sender’s domain against it. SPF alone authorizes the sending infrastructure; it says nothing about the `From:` header a human sees.

**DKIM** is a public key published in DNS. Resend signs each outgoing message with the matching private key, and the receiver verifies the signature. This is the one that survives forwarding, and it is the stronger of the two signals.

**DMARC** is the policy that ties SPF or DKIM back to the visible `From:` domain, “alignment”, and tells receivers what to do when neither aligns. Without DMARC, a receiver has two passing checks and no instruction. With it, you get a policy and, more usefully at first, aggregate failure reports.

Resend generates the exact SPF and DKIM records for you when you add a domain; publish them verbatim and wait for propagation. DMARC you add yourself:

```
; TXT record at _dmarc.yourdomain.com
v=DMARC1; p=none; rua=mailto:dmarc-reports@yourdomain.com; pct=100
```

Start at `p=none`. It changes nothing about delivery, but it starts the reports flowing so you can see every source sending as your domain. Move to `p=quarantine` once the reports are clean, and to `p=reject` when you are confident. Going straight to `p=reject` on a domain you also use for a CRM, a help desk and a newsletter tool is how people take down their own invoices.

## Step 2: create a key with the right scope

Resend keys come in two access levels, and Lovable accepts either. Choose deliberately:

- **Sending access**: dispatch only, and optionally restricted to one domain. This is what a Lovable app needs. If the key leaks, the blast radius is “someone can send mail from one domain”, not “someone can delete my domains and read my logs”.
- **Full access**: everything, including domain and key management. Only pick this if you have a concrete reason.

The value is prefixed `re_`. Copy it once; Resend will not show it again.

## Step 3: connect it, then send

Add the Resend connector from Lovable’s connectors catalog and paste the key. After that, sending is a chat instruction. Be specific about the from address, because this is where the classic failure lives:

> Send a transactional email when a new row is inserted into `contact_submissions`. Send it from `notifications@send.mydomain.com`, with both an HTML body and a plain-text alternative, and set reply-to to the submitter’s address.

Two things go wrong at this step, reliably.

First, the test address. Until you specify otherwise, sends go from the shared `onboarding@resend.dev` address, which only delivers to the Resend account owner. Your test works. Every real recipient gets nothing, with no error you will notice. Resend’s Lovable integration docs (https://resend.com/docs/lovable-integration) call this out directly, along with the fix.

Second, the redeploy. Changing the from address in chat updates your code; it does not update your live site. Lovable’s hosting publishes a snapshot, and changes after a publish do not affect the live site until you republish. Verifying a domain, changing the from address, and then testing the _published_ app without republishing produces a confusing “I fixed it and nothing changed” loop.

## Transactional or marketing: the line matters legally

Transactional email is triggered by, and about, something the recipient did: a receipt, a password reset, a booking confirmation, a shipping notice. Marketing email promotes something, regardless of how it is dressed up.

The distinction is not cosmetic. Under CAN-SPAM, commercial messages must carry a working opt-out and a valid physical postal address; transactional or relationship messages are exempt from most of those requirements but still may not use deceptive headers or subject lines. Under GDPR you need a lawful basis for marketing (in practice, consent) while a transactional message to fulfill a contract stands on different ground. Canada’s CASL is stricter still on consent.

Here is the trap: adding a promotional block to a transactional email can reclassify the whole message. A receipt with “while you’re here, check out our Pro plan” stops being purely transactional. If you want to upsell, send a separate message on a separate footing, ideally from a separate subdomain.

Mixing the streams also costs you technically. Marketing mail attracts complaints and unsubscribes; transactional mail must arrive. Share a domain between them and one bad campaign can send your password resets to spam.

## Deliverability: five things that decide whether it lands

Authentication gets you admitted. These get you delivered.

1. **A real From address on a domain you control.** Never send as `@gmail.com` or `@outlook.com` from Resend: you cannot sign or authorize mail for a domain you don’t control, so DKIM and SPF can never align with the visible `From:` address, and the major providers treat spoofed consumer domains harshly regardless of what policy those domains publish. `notifications@send.yourdomain.com` is fine; a monitored `reply-to` is better than a `no-reply` that silently eats replies.
2. **A plain-text alternative.** Send `text` alongside `html`. HTML-only mail is a mild spam signal, it breaks in text-only clients and accessibility tooling, and writing the text version usually reveals that your HTML says less than you thought.
3. **Unsubscribe handling, wired properly.** For anything even adjacent to marketing, set `List-Unsubscribe` and `List-Unsubscribe-Post` so mailbox providers can render a native one-click unsubscribe:

   ```
   List-Unsubscribe: <https://yourdomain.com/u/abc123>, <mailto:unsubscribe@yourdomain.com>
   List-Unsubscribe-Post: List-Unsubscribe=One-Click
   ```

The endpoint must actually suppress the address, and it must work on a single POST with no login and no confirmation page. Note that Lovable’s connector documents recipients, cc/bcc, reply-to, attachments and tags: it does not document arbitrary custom headers. If you need these, send through your own server code against the Resend API rather than through the connector.
4. **Warming, if you are sending volume.** A brand-new sending domain has no reputation. Ramp over days rather than blasting your whole list on day one, and send to engaged recipients first. For a low-volume transactional app this mostly takes care of itself; for anything list-shaped it does not.
5. **Bounce and complaint hygiene.** Hard bounces must never be retried, and complaints must suppress the address permanently. Which brings us to the connector’s second limitation.

## Webhooks, given the connector can’t receive them

Resend reports delivery, bounce, complaint and open/click events by webhook. Lovable’s connector cannot receive them. You have two honest options.

**Poll for status.** The connector can query an email’s status. For a low-volume app where you mainly want to know whether a specific receipt was delivered, a status lookup on demand is enough, and it costs you nothing to build. Do not turn this into a background job that polls every few seconds: deployed-app database and compute usage is billed out of the same credit pool as your AI coding, and a short-interval job keeps compute awake around the clock for no benefit. Credit discipline (https://prerenderlovable.com/blog/save-lovable-credits) applies to runtime as well as to prompting.

**Receive them yourself.** Have the app expose a real HTTP endpoint and register that URL in Resend’s dashboard. On the TanStack Start stack (the default for projects created from 13 May 2026 onward) you need a real HTTP endpoint rather than a `createServerFn` server function, which is meant to be called from your own app. As of September 2026 Lovable’s docs don’t spell out how to ask for one, so describe the requirement in chat (a public POST URL a third party can hit) and verify what it actually generates. On an older React + Vite project, it is a Supabase edge function, the same shape as any other backend handler. Then:

```
// Sketch: check Resend's current webhook docs for the exact signing scheme
// and use their documented verification helper rather than hand-rolling HMAC.
// The secret is passed in, because where it comes from differs by stack:
//   edge function (React + Vite projects): Deno.env.get('RESEND_WEBHOOK_SECRET')
//   TanStack Start on Workers: the request-time env/bindings object handed to
//   your handler, not a global, and never `process.env` on either stack.
export async function handleResendWebhook(req: Request, secret: string) {
  const raw = await req.text()               // verify against the RAW body
  const ok = verifySignature(raw, req.headers, secret)
  if (!ok) return new Response('invalid signature', { status: 401 })

  const event = JSON.parse(raw)
  switch (event.type) {
    case 'email.bounced':
      // `data.to` is an ARRAY of recipients, not a single address.
      for (const addr of event.data.to) await suppress(addr, 'bounce')
      break
    case 'email.complained':
      for (const addr of event.data.to) await suppress(addr, 'complaint')
      break
  }
  return new Response('ok', { status: 200 })   // always 200, or it retries
}
```

Two payload details catch people out: the secret never lives on `process.env` in either runtime, and `data.to` is an array even when you only sent to one person. Past that, three rules regardless of provider: verify the signature against the raw request body before parsing, treat delivery as at-least-once and make the handler idempotent, and return 2xx quickly, doing real work asynchronously.

## The other email pipeline nobody mentions

A Lovable app with authentication has **two** email systems, and the Resend connector is only one of them.

Signup confirmations, magic links and password resets are sent by the authentication service (Supabase Auth, whether that is Lovable Cloud or your own Supabase project (https://prerenderlovable.com/blog/lovable-cloud-vs-supabase)) using its own SMTP settings and its own templates. Connecting Resend to Lovable does nothing for those. People verify a domain, fix their contact-form email, then spend an afternoon wondering why the signup confirmation still arrives from a generic address and lands in Promotions.

On your own Supabase, the fix is to configure custom SMTP in the Auth settings with Resend’s SMTP credentials and edit the templates there. On Lovable Cloud, auth is managed inside the editor rather than in a Supabase dashboard, and as of September 2026 Lovable’s docs don’t spell out a custom-SMTP setting for it, so ask in chat and verify what it actually wires up before you assume the auth stream is authenticated.

Either way: test both pipelines. A sent transactional email proves nothing about a signup confirmation.

## When you don’t need an email provider at all

Everything above is the right amount of work if your app sends product email: receipts, resets, notifications to users who are not you. It is a lot of work if what you actually wanted was “somebody filled in the contact form, tell me about it”.

For that case the whole stack collapses. A hosted form backend takes the POST, stores the submission and emails you, with no API key in your app, no domain to verify and no function to redeploy. Formspree and Basin are the established names; a Tally or Typeform embed does it too, at the cost of not owning the markup. The build-it-yourself version (a table plus a handler plus Resend) is covered in the Lovable contact form guide (https://prerenderlovable.com/blog/lovable-contact-form), and it is genuinely worth doing when the form is part of a product rather than an inbox.

LinkyCal (https://linkycal.com/features/forms) is the one we’d use here. Most people who land on this page want one thing: a contact form that tells them when someone fills it in. LinkyCal does that without an email provider at all. It filters spam, needs no DNS setup, and sends notifications by email, Slack, Telegram or WhatsApp, into Excel or Google Sheets, or to a webhook. Its workflows (https://linkycal.com/features/workflows) can also enrich each lead and send an auto-responder or a lead magnet the moment the form is submitted. The transactional email your product sends to users, such as receipts and password resets, still goes through Resend.

## What to do next

1. Check where your app is sending from right now. If the from address contains `resend.dev`, nobody outside your Resend account has received anything.
2. Verify a dedicated sending subdomain in Resend and publish a DMARC record at `p=none` today, so reports accumulate while you build.
3. Rotate to a sending-access key scoped to that one domain if you connected a full-access key to get started.
4. Change the from address, then **republish**, then test against the published URL.
5. Send yourself one real message and read the raw headers. If SPF and DKIM both pass and DMARC aligns, the technical half is done and everything left is content and reputation.
6. Send a test signup through your auth flow separately. That email comes from somewhere else entirely.

Found something wrong or out of date? Lovable changes fast and we'd rather fix a guide than let it rot.

Disclosure: the team behind this guide also builds LinkyCal, mentioned above.

## Frequently asked questions

Can the Lovable Resend connector verify my sending domain?

No. Lovable's Resend documentation states the connector cannot verify domains, and that email reaches your app's users only from a domain you have already verified inside Resend. Domain verification is a DNS task you complete in the Resend dashboard before you connect anything to Lovable.

Why does my Lovable app only send email to my own address?

Because it is still sending from the shared onboarding@resend.dev test address, which only delivers to the Resend account owner. Verify your own domain in Resend, then change the from address in your app and redeploy. Resend's Lovable integration docs note that changing the from address does not apply automatically.

Does each Lovable project get its own Resend account?

No. Resend is an app plus chat connector with a single shared connection across every linked project, so staging and production send through the same Resend account and the same API key. If you need per-project isolation, skip the connector and store your own key as a backend secret instead.

Can I receive Resend webhooks through Lovable?

Not through the connector. Lovable's docs list receiving webhooks as a limitation. You can still receive them by having your app expose its own HTTP endpoint, registering that URL in Resend's dashboard, and verifying the signature on every request.

Do I need DMARC to send transactional email?

SPF and DKIM are the hard requirement at the major mailbox providers, and DMARC is what tells them what to do when alignment fails. Publishing a DMARC record even at p=none gives you failure reports and a path to enforcement later, and bulk senders to Gmail and Yahoo have been required to publish one since February 2024.

Will the Resend connector send my Supabase auth emails?

No. Signup confirmations and password resets are sent by the authentication service using its own SMTP configuration and templates. That is a separate pipeline from your app's transactional sends, and configuring the Resend connector changes nothing about it.

Read next

## Keep going

- ### Adding a contact form to a Lovable app: https://prerenderlovable.com/blog/lovable-contact-form
  A Lovable contact form needs an endpoint to POST to. Compare an edge function plus Resend, a hosted form backend, and a keyless HTML endpoint.
- ### Lovable integrations: the complete map: https://prerenderlovable.com/blog/lovable-integrations
  Lovable integrations come in six connection types, and picking the wrong one is why wiring fails. What each type does, what exists, and how secrets flow.
- ### Lovable Cloud vs your own Supabase: how to choose: https://prerenderlovable.com/blog/lovable-cloud-vs-supabase
  Lovable Cloud vs Supabase is close to a one-way door. The documented tradeoffs, the credit pool that bills your hosting, and what switching later really costs.

## Structured data

```json
{
  "@context": "https://schema.org",
  "@graph": [
    {
      "@type": "WebSite",
      "@id": "https://prerenderlovable.com/#website",
      "url": "https://prerenderlovable.com",
      "name": "The Lovable Field Guide",
      "description": "A working journal on Lovable SEO: getting apps built with Lovable indexed, ranked and cited, plus the migration and integration work that comes with it.",
      "publisher": {
        "@id": "https://prerenderlovable.com/#organization"
      },
      "inLanguage": "en"
    },
    {
      "@type": "Organization",
      "@id": "https://prerenderlovable.com/#organization",
      "name": "The Lovable Field Guide",
      "url": "https://prerenderlovable.com"
    },
    {
      "@type": "BlogPosting",
      "@id": "https://prerenderlovable.com/blog/lovable-resend-email-setup#article",
      "headline": "Setting up Resend in a Lovable app",
      "description": "The Lovable Resend setup that actually ships: what the shared connector can't do, the DNS you verify first, and the deliverability work nobody documents.",
      "datePublished": "2026-09-11T00:00:00.000Z",
      "dateModified": "2026-09-11T00:00:00.000Z",
      "inLanguage": "en",
      "mainEntityOfPage": {
        "@type": "WebPage",
        "@id": "https://prerenderlovable.com/blog/lovable-resend-email-setup"
      },
      "author": {
        "@type": "Organization",
        "name": "The Lovable Field Guide",
        "url": "https://prerenderlovable.com"
      },
      "publisher": {
        "@id": "https://prerenderlovable.com/#organization"
      },
      "keywords": "lovable resend setup, lovable resend integration, resend only sends to my own email, lovable resend domain verification, lovable transactional email",
      "articleSection": "Integrations"
    },
    {
      "@type": "BreadcrumbList",
      "@id": "https://prerenderlovable.com/blog/lovable-resend-email-setup#breadcrumbs",
      "itemListElement": [
        {
          "@type": "ListItem",
          "position": 1,
          "name": "Home",
          "item": "https://prerenderlovable.com/"
        },
        {
          "@type": "ListItem",
          "position": 2,
          "name": "Integrations",
          "item": "https://prerenderlovable.com/integrations"
        },
        {
          "@type": "ListItem",
          "position": 3,
          "name": "Setting up Resend in a Lovable app",
          "item": "https://prerenderlovable.com/blog/lovable-resend-email-setup"
        }
      ]
    },
    {
      "@type": "FAQPage",
      "@id": "https://prerenderlovable.com/blog/lovable-resend-email-setup#faq",
      "mainEntity": [
        {
          "@type": "Question",
          "name": "Can the Lovable Resend connector verify my sending domain?",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "No. Lovable's Resend documentation states the connector cannot verify domains, and that email reaches your app's users only from a domain you have already verified inside Resend. Domain verification is a DNS task you complete in the Resend dashboard before you connect anything to Lovable."
          }
        },
        {
          "@type": "Question",
          "name": "Why does my Lovable app only send email to my own address?",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "Because it is still sending from the shared onboarding@resend.dev test address, which only delivers to the Resend account owner. Verify your own domain in Resend, then change the from address in your app and redeploy. Resend's Lovable integration docs note that changing the from address does not apply automatically."
          }
        },
        {
          "@type": "Question",
          "name": "Does each Lovable project get its own Resend account?",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "No. Resend is an app plus chat connector with a single shared connection across every linked project, so staging and production send through the same Resend account and the same API key. If you need per-project isolation, skip the connector and store your own key as a backend secret instead."
          }
        },
        {
          "@type": "Question",
          "name": "Can I receive Resend webhooks through Lovable?",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "Not through the connector. Lovable's docs list receiving webhooks as a limitation. You can still receive them by having your app expose its own HTTP endpoint, registering that URL in Resend's dashboard, and verifying the signature on every request."
          }
        },
        {
          "@type": "Question",
          "name": "Do I need DMARC to send transactional email?",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "SPF and DKIM are the hard requirement at the major mailbox providers, and DMARC is what tells them what to do when alignment fails. Publishing a DMARC record even at p=none gives you failure reports and a path to enforcement later, and bulk senders to Gmail and Yahoo have been required to publish one since February 2024."
          }
        },
        {
          "@type": "Question",
          "name": "Will the Resend connector send my Supabase auth emails?",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "No. Signup confirmations and password resets are sent by the authentication service using its own SMTP configuration and templates. That is a separate pipeline from your app's transactional sends, and configuring the Resend connector changes nothing about it."
          }
        }
      ]
    },
    {
      "@type": "HowTo",
      "@id": "https://prerenderlovable.com/blog/lovable-resend-email-setup#howto",
      "name": "Set up Resend email in a Lovable app",
      "step": [
        {
          "@type": "HowToStep",
          "position": 1,
          "name": "Verify your sending domain in Resend",
          "text": "Add the domain (or a dedicated sending subdomain) in the Resend dashboard and publish the DKIM and SPF records it gives you at your DNS provider. Lovable cannot do this step for you."
        },
        {
          "@type": "HowToStep",
          "position": 2,
          "name": "Publish a DMARC record",
          "text": "Add a TXT record at _dmarc.yourdomain.com starting at v=DMARC1; p=none with an rua address so you get failure reports before you tighten the policy."
        },
        {
          "@type": "HowToStep",
          "position": 3,
          "name": "Create a scoped API key",
          "text": "In Resend, create a key with sending access only and restrict it to the domain you just verified. Copy the re_ prefixed value once."
        },
        {
          "@type": "HowToStep",
          "position": 4,
          "name": "Connect Resend in Lovable",
          "text": "Add the Resend connector from the Lovable connectors catalog and paste the re_ key. The connection is shared across every project linked to it."
        },
        {
          "@type": "HowToStep",
          "position": 5,
          "name": "Send from your verified domain and redeploy",
          "text": "Ask Lovable in chat to send using an address on your verified domain rather than onboarding@resend.dev, then republish. Changing the from address does not take effect until you redeploy."
        }
      ]
    }
  ]
}
```