New from emailrHealthCheck Email iconHealthCheck Email
emailr_

Send email from Nuxt with emailr_

Send transactional email from Nuxt server routes with the emailr_ SDK, keep keys in runtimeConfig and verify delivery webhooks with raw bodies.

Nuxt iconNuxtFramework

Nuxt's Nitro server routes are a natural home for email sending: they run only on the server, read secrets from runtimeConfig, and deploy anywhere Nitro does.

This guide adds the emailr SDK, sends from a server route and verifies signed delivery webhooks.

Set up emailr_ with Nuxt

  1. 01

    Create an API key

    Create a key under API keys in the dashboard. Keys start with et_live_ and are scoped to one domain workspace. Store it as EMAILR_API_KEY in your secret manager or environment, never in client-side code.

  2. 02

    Add and verify your sending domain

    In the dashboard, open Domains and add the domain you send from. A subdomain such as mail.yourcompany.com keeps transactional reputation separate from your corporate mailbox.

    Emailr generates the DNS records: a DKIM TXT record on the emailr._domainkey selector, an SPF TXT record, and an MX + TXT pair on the send subdomain used as the MAIL FROM / Return-Path. A DMARC record is optional but recommended.

    Emailr's DKIM selector and send subdomain don't collide with other providers' records, so you can add them before cutting over and send from both providers during the migration. A domain can only have one SPF record: if one already exists, merge Emailr's include: into it instead of adding a second record.

  3. 03

    Install the SDK

    Install the package in your Nuxt project.

    Terminalbash
    npm install emailr
  4. 04

    Declare private runtime config

    Keys declared at the top level of runtimeConfig are server-only. Nuxt fills them from NUXT_-prefixed environment variables, so set NUXT_EMAILR_API_KEY and NUXT_EMAILR_WEBHOOK_SECRET in production.

    nuxt.config.tsts
    export default defineNuxtConfig({
      runtimeConfig: {
        emailrApiKey: '',
        emailrWebhookSecret: '',
      },
    })
  5. 05

    Send from a server route

    Files in server/api become endpoints. A .post.ts suffix restricts the route to POST requests.

    server/api/welcome.post.tsts
    import { Emailr } from 'emailr'
    
    export default defineEventHandler(async (event) => {
      const { email } = await readBody<{ email: string }>(event)
      const { emailrApiKey } = useRuntimeConfig(event)
      const emailr = new Emailr({ apiKey: emailrApiKey })
    
      const result = await emailr.emails.send({
        from: 'Acme <hello@mail.acme.com>',
        to: email,
        subject: 'Welcome to Acme',
        html: '<p>Thanks for signing up.</p>',
      })
    
      return { id: result.message_id }
    })
  6. 06

    Verify delivery webhooks

    Use readRawBody so the HMAC is computed over the exact bytes emailr_ sent, then parse the JSON yourself.

    server/api/webhooks/emailr.post.tsts
    import { createHmac, timingSafeEqual } from 'node:crypto'
    
    export default defineEventHandler(async (event) => {
      const body = (await readRawBody(event)) ?? ''
      const signature = getHeader(event, 'x-emailr-signature') ?? ''
      const { emailrWebhookSecret } = useRuntimeConfig(event)
      const expected = createHmac('sha256', emailrWebhookSecret).update(body).digest('hex')
    
      if (signature.length !== expected.length ||
          !timingSafeEqual(Buffer.from(signature), Buffer.from(expected))) {
        throw createError({ statusCode: 401, statusMessage: 'Invalid signature' })
      }
    
      const { event: type, data } = JSON.parse(body)
      // handle email.delivered, email.bounced, email.complained ...
      return { ok: true }
    })

Tips

  • Call the route from a page with $fetch('/api/welcome', { method: 'POST', body: { email } }).
  • On edge presets such as Cloudflare, swap node:crypto for the Web Crypto verification shown in the Cloudflare guide.
  • Vue Email or any other renderer works: render to an HTML string and pass it as html.

Frequently asked questions

Where should I put my emailr_ API key in Nuxt?

In a top-level runtimeConfig key, filled from the NUXT_EMAILR_API_KEY environment variable. Top-level keys are only available on the server.

Can I send email from a Nuxt page or component?

Not directly. Pages run in the browser too, so call a server route with $fetch and send from there.

Does the SDK run on Nitro edge presets?

The SDK uses fetch and works on edge runtimes. For webhook verification on the edge, use Web Crypto instead of node:crypto.

How do I verify emailr_ webhooks in Nuxt?

Read the body with readRawBody, compute an HMAC-SHA256 with your webhook secret and compare it to the X-Emailr-Signature header.

Start sending in minutes

Create a free account, verify your domain and send your first email. No credit card required.