EmailJS compatibility (@frontmail/emailjs-compat)
@frontmail/emailjs-compat exposes the same functions and signatures as @emailjs/browser, but
talks to Frontmail. Existing code keeps working after you change the import and the IDs.
npm uninstall @emailjs/browsernpm install @frontmail/emailjs-compatimport emailjs from '@emailjs/browser';import emailjs from '@frontmail/emailjs-compat';
emailjs.init({ publicKey: 'pk_4f2a…' });emailjs.send('svc_01J9…', 'tpl_01J9…', { name: 'Jana' });emailjs.sendForm('svc_01J9…', 'tpl_01J9…', '#contact-form');What’s compatible
Section titled “What’s compatible”init(publicKey)andinit({ publicKey, blockHeadless, blockList, limitRate, storageProvider }), with an optional second argument for the API origin (defaulthttps://api.frontmail.dev).send(serviceID, templateID, templateParams?, options?)andsendForm(serviceID, templateID, form, options?), withoptionsas a public key string or an options object.- The resolved value is an
EmailJSResponseStatuswithstatus(200) andtext('OK'), like EmailJS, plus Frontmail extras:messageId,deliveryStatus('queued'or'held') andstatusToken. - Errors are thrown as
EmailJSResponseStatusobjects withstatusandtext, so existingcatchhandlers work. The underlyingFrontmailError(withcodeanddocsUrl) is inerror.error. - The REST paths
/api/v1.0/email/sendand/api/v1.0/email/send-formexist onapi.frontmail.dev, with the EmailJS body fieldsservice_id,template_id,user_id,template_params,accessToken.
What’s different
Section titled “What’s different”- The IDs and keys are Frontmail’s:
svc_…,tpl_…,pk_…,sk_…. - Templates use Frontmail syntax (Handlebars) and typed params. Most
{{variable}}templates work unchanged; see the migration guide. - Frontmail may resolve with a held message when you are out of credits (still a success).
The compat layer reports it as
status: 200withdeliveryStatus: 'held';@frontmail/browserreturnsstatus: 'held'directly. - Frontmail retries network errors and 5xx automatically with an idempotency key.
accessToken(a private key) is refused in the browser:send/sendFormreject withstatus: 400anderror.code === 'private_key_in_browser'. Remove it from front-end code – see the migration guide. Server-side code (Node.js, nodocument) may still pass it.sendFormskips password inputs, anti-CSRF fields of common frameworks and reserved names such asaccessToken(see sendForm).blockHeadless,blockListandlimitRaterun in the browser and are a convenience, not a security control – enforce limits in Security in the dashboard.
When you’re ready, switching to @frontmail/browser or a framework SDK is
straightforward and gives you typed results, typed params and getStatus.