Skip to content
Migration guide

Switching from EmailJS?

Keep your form. Change where submissions go. Your form HTML stays the same, your field names stay the same — you change one function call and submissions become Latch cases instead of emails.

One function call.

Everything else stays the same.

Before · EmailJS
import emailjs from '@emailjs/browser'

emailjs.send(
  'service_id',
  'template_id',
  {
    from_name: name,
    reply_to: email,
    message: message,
  }
)

Result: an email in your inbox.

After · Latch
import { submitIntake } from '@latch/intake-sdk'

submitIntake(
  'your_form_id',
  {
    name: name,
    email: email,
    message: message,
  }
)

Result: a case in your Latch queue for your team to review.

What changes on the other side.

The frontend looks identical. What happens after submit is completely different.

Submission arrives
With EmailJS

Goes to an email inbox. Someone reads it when they next check email.

With Latch

Goes into your Latch queue immediately. Your team is notified.

Context
With EmailJS

A raw email or form notification. Your team has to look things up separately.

With Latch

Latch prepares a summary — what kind of request it is, what is needed, what to do next.

Review
With EmailJS

Happens informally. Someone forwards it or pastes it into Slack.

With Latch

Your team reviews the case in Latch. Everything is in one place.

Action
With EmailJS

Manual. Someone logs into a CRM, sends an email, or messages a colleague.

With Latch

Your team approves an action and Latch runs it — CRM entry, Slack notification, support ticket, or whatever is needed.

Record
With EmailJS

Scattered. The email is in one tool, the CRM entry in another, the Slack thread somewhere else.

With Latch

Everything stays on the case: the original submission, who reviewed it, what was approved, and what happened.

How to migrate

Six steps to switch.

1

Install the Latch SDK

pnpm add @latch/intake-sdk
2

Create a form in your Latch workspace

You will get a form ID. This tells Latch which case type to use and which field mapping to apply.

3

Map your fields

Match your form fields to Latch case fields — name, email, message, attachments. Unmapped fields are still stored on the case.

4

Replace the EmailJS call

Remove
emailjs.send(
  serviceId, templateId, fields
)
Add
submitIntake(
  'your_form_id', fields
)
5

Test with a real submission

Submit your form and confirm the case appears in your Latch queue. Check the fields mapped correctly and Latch's summary looks right.

6

Remove the old dependency

pnpm remove @emailjs/browser
Also works for Formspree

Using Formspree or a form endpoint?

Same idea. Replace the fetch call to your Formspree endpoint with submitIntake(). Your form HTML stays unchanged.

Before · Formspree
fetch('https://formspree.io/f/your_id', {
  method: 'POST',
  body: new FormData(form),
})
After · Latch
submitIntake(
  'your_form_id',
  Object.fromEntries(new FormData(form))
)
Ready to switch

Migrate in an afternoon.

Your form stays the same. Your team gets a review queue instead of an inbox.