Email Fast Get a sandbox key
Guides

Send email with Vue

A form component that sends from the browser with a shippable public key — or a Nuxt server route when you have a backend.

Facts verified 2026-07-17 — corrections: hello@emailfast.dev

A Vue component can send email with no backend at all. Email Fast ships a browser SDK with EmailJS-compatible endpoints — the recipient always comes from the server-stored template, never from the request, so a public key in your frontend can't be abused to spam arbitrary addresses. Initialize with your public key, name a server-stored template, and hand sendForm the form element. If you run Nuxt or any backend, the second pattern keeps a secret key server-side instead.

npm install @email-fast/browser
<!-- ContactForm.vue -->
<script setup>
import { ref } from "vue";
import emailfast from "@email-fast/browser";

emailfast.init({ publicKey: "ef_pub_..." }); // public by design — safe to ship

const state = ref("idle");

async function submit(e) {
  state.value = "sending";
  try {
    await emailfast.sendForm("default", "contact_form", e.target);
    state.value = "sent";
  } catch {
    state.value = "error";
  }
}
</script>

<template>
  <form @submit.prevent="submit">
    <input name="name" required />
    <input name="email" type="email" required />
    <textarea name="message" required />
    <button :disabled="state === 'sending'">Send</button>
    <p v-if="state === 'sent'">Thanks — we got it.</p>
    <p v-if="state === 'error'">That didn't go through. Try again.</p>
  </form>
</template>

Or: send through your own backend

With Nuxt, one server route keeps the secret key out of the bundle entirely:

// server/api/contact.post.ts — Nuxt; the key stays on the server
import { EmailFast } from "@email-fast/nodejs";

const ef = new EmailFast({ apiKey: process.env.EMAILFAST_API_KEY!, baseUrl: "https://api.emailfast.dev" }); // ef_sandbox_… while testing

export default defineEventHandler(async (event) => {
  const { message, formId } = await readBody(event);
  const { id } = await ef.send({
    to: "team@yourdomain.dev",
    subject: "New contact message",
    html: "<p>{{message}}</p>",
    data: { message },
    idempotency_key: `contact-${formId}`, // generated once per render — a double-submit replays
  });
  return { id };
});

Gotchas

Next

See it for yourself

Sandbox keys run the real pipeline dry — real validation, real events, a hosted inbox, no email sent. Early access is onboarding now.