# AJAX without writing JavaScript

Part of the sendm8 docs: https://sendm8.com/docs#ajax-helper. Index for AI assistants: https://sendm8.com/llms.txt

Want the stay-on-the-page feel without writing the `fetch` yourself? Add our tiny helper script and a `data-sendm8` attribute to your form. It sends the form in the background (file uploads included), disables the button while it’s sending, and shows a message when it’s done.

`contact.html`

```html
<script src="https://sendm8.com/s/v1.js" defer></script>

<form action="https://sendm8.com/f/k3x9q2m7ab" method="POST"
      data-sendm8 data-sendm8-success="Thanks! We’ll be in touch.">
  <label>Your email <input name="email" type="email" required></label>
  <label>Message <textarea name="message" required></textarea></label>
  <button>Send</button>
</form>
```

- **No JavaScript? Still works.** The form posts the normal way and visitors land on your thank-you page, so nobody gets stuck.
- `data-sendm8-success`: the message to show, or a selector like `#thanks` for an element to reveal. The default is “Thanks! Message sent.” The form is cleared afterwards.
- `data-sendm8-error`: a selector for where errors go. Without it we add a `role="alert"` paragraph to the form. The text is the API’s own plain-English error, like “This form isn’t accepting submissions right now.”
- Listen for `sendm8:success` (`event.detail.id`) and `sendm8:error` (`event.detail.message`, `code`, `status`) on the form. Call `event.preventDefault()` to skip the built-in message and do your own thing.
- Opt a form out with `data-sendm8="off"`. For a manual send, `window.sendm8.submit(form)` returns a promise of `{ ok, id, error }`.

`optional.js`

```js
const form = document.querySelector("form[data-sendm8]");

form.addEventListener("sendm8:success", (event) => {
  console.log("Stored as", event.detail.id);
});

form.addEventListener("sendm8:error", (event) => {
  console.warn(event.detail.code, event.detail.message);
});
```

> **Small and dependency-free**
>
> About 6 KB, no libraries, works in every browser with `fetch`. It only touches forms with `data-sendm8` whose `action` is a sendm8 `/f/` endpoint, and adds nothing to the page apart from an optional `window.sendm8`.
