Przejdź do głównej zawartości

Czysty JavaScript (@frontmail/browser)

@frontmail/browser to malutkie (< 3,5 kB po gzipie) SDK bez zależności dla dowolnej strony. Jego API odpowiada @emailjs/browser, więc istniejący kod wymaga niewielu zmian.

Okno terminala
npm install @frontmail/browser
import { init, send, sendForm, getStatus } from '@frontmail/browser';

Wywołaj raz, przed wysyłką:

init({
publicKey: 'pk_4f2a…',
blockHeadless: true, // opcjonalne, zobacz Ochrona przed botami
blockList: { list: ['spam@example.net'], watchVariable: 'email' },
limitRate: { id: 'contact', throttle: 10_000 }, // najwyżej jedna wysyłka na 10 s
retry: { retries: 3, baseDelayMs: 300 }, // domyślne; `false` wyłącza ponawianie
timeoutMs: 15_000, // na jedną próbę
apiUrl: 'https://api.frontmail.dev', // domyślne
});

Działa też init('pk_4f2a…') z samym kluczem jako ciągiem znaków.

const result = await send('svc_01J9…', 'tpl_order', {
name: 'Jana',
items: [{ title: 'Pokój', qty: 2, price: 89 }],
});
// { messageId: 'msg_…', status: 'queued' | 'held', statusToken: '…', status_code: 202, text: 'OK' }
  • serviceId może być null – wtedy zostanie użyta domyślna usługa organizacji.
  • params są walidowane na serwerze według schematu szablonu.
  • options przyjmuje turnstileToken, attachments, idempotencyKey, locale, signal (AbortSignal), publicKey dla pojedynczego wywołania i zabezpieczenia dla pojedynczego wywołania (blockHeadless, blockList, limitRate). Zwykły ciąg znaków jest traktowany jako klucz publiczny, tak jak w EmailJS.
  • locale (np. 'de') wybiera język szablonu; nieznany język przechodzi na ten sam język bazowy, a potem na język domyślny. result.locale to język, w którym e-mail został wysłany.

Promise rozwiązuje się zarówno dla queued, jak i held – wstrzymana wiadomość jest przyjęta i zostanie wysłana, gdy pojawią się kredyty (zobacz Kolejka wstrzymanych wiadomości). W pozostałych przypadkach jest odrzucany z typowanym błędem (zobacz Obsługa błędów).

<form id="contact">
<input name="name" required>
<input name="email" type="email" required>
<textarea name="message"></textarea>
<input type="file" name="attachment">
<div class="cf-turnstile" data-sitekey="YOUR_TURNSTILE_SITE_KEY"></div>
<button>Wyślij</button>
</form>
<script type="module">
import { init, sendForm } from '@frontmail/browser';
init({ publicKey: 'pk_4f2a…' });
document.getElementById('contact').addEventListener('submit', async (event) => {
event.preventDefault();
const { status } = await sendForm('svc_01J9…', 'tpl_contact', event.target);
// albo: sendForm('svc_01J9…', 'tpl_contact', '#contact')
});
</script>

Formularz jest wysyłany jako multipart/form-data. Pola tekstowe stają się parametrami (konwertowanymi na zadeklarowane typy), pola plików stają się załącznikami, a token Turnstile z cf-turnstile-response jest pobierany automatycznie. Użyj site key swojego własnego widgetu Turnstile – zobacz Cloudflare Turnstile.

Pola, które nie mogą opuścić twojej strony, są pomijane: pola haseł (type="password"), pola anty-CSRF popularnych frameworków (csrfmiddlewaretoken, _token, authenticity_token, __RequestVerificationToken, _csrf, csrf_token) i zarezerwowane nazwy API (accessToken, privateKey, turnstile_key, …). Pola możesz wybrać samodzielnie opcją formFields:

await sendForm('svc_01J9…', 'tpl_contact', '#contact', {
formFields: { include: ['name', 'email', 'message'] }, // tylko te (+ token Turnstile)
// albo: formFields: { exclude: ['internal_note'] }
});

Żeby wysłać formularz w jednym z języków szablonu, przekaż { locale: 'de' } – zostanie wysłane jako zarezerwowane pole fm_locale – albo sam dodaj do formularza pole fm_locale (np. wybór języka <select name="fm_locale">); pole formularza ma pierwszeństwo. Pole o nazwie locale pozostaje zwykłym parametrem szablonu.

const status = await getStatus(result.messageId, { token: result.statusToken });
// { messageId, status: 'sent', createdAt, sentAt, templateId, serviceId, events: [...] }

Z kluczem publicznym możesz odczytywać tylko wiadomości wysłane przez siebie, za pomocą statusToken z wyniku wysyłki. SDK wysyła go w nagłówku X-Frontmail-Status-Token (a nie w URL-u, więc nie trafia do logów). Zobacz Statusy wiadomości.

Tag <script> działa z pełnym dostępem do twojej strony. Ładuj konkretną wersję i pozwól przeglądarce sprawdzić jej hash – zmieniony plik (np. po włamaniu na CDN albo do wydania) zostanie wtedy odrzucony, zamiast się wykonać:

<script
src="https://cdn.jsdelivr.net/npm/@frontmail/browser@0.1.0/dist/frontmail.umd.js"
integrity="sha384-g2Rxznkz2yb/YYSdVTkXLxZFZ2Nh2+XdhPStxh0stydXFF3gYjDuyHimWIZLJDCc"
crossorigin="anonymous"></script>
  • jsDelivr (npm): hash każdego wydania jest w informacjach o wydaniu na GitHubie (i pod przyciskiem „Copy HTML + SRI” na jsDelivr).
  • CDN Frontmail: https://cdn.frontmail.dev/v<wersja>/frontmail.umd.js; wartość integrity znajdziesz w https://cdn.frontmail.dev/v<wersja>/sri.json.
  • Aktualizuj, zmieniając wersję i hash jednocześnie (zobacz listę zmian).

Jeśli twoja strona korzysta z CSP, zezwól na:

connect-src https://api.frontmail.dev;
script-src https://cdn.jsdelivr.net https://challenges.cloudflare.com; # build z CDN (albo cdn.frontmail.dev), Turnstile
frame-src https://challenges.cloudflare.com; # Turnstile