# `@formbrew/embed`

`@formbrew/embed` is Formbrew's framework-free hosted form renderer. It bundles the typed JavaScript client, managed DOM renderer, and `<formbrew-form>` custom element into one classic browser script.

Version `0.4.0` uses the same version as the JavaScript and React SDKs and supports the complete
public field set, multiline Text configuration, and Number sign and precision settings. See the
[release notes](https://github.com/solspace/formbrew/blob/main/docs/releases/frontend-0.4.0.md).

## Custom-element embed

Load the script once, then place a `<formbrew-form>` element wherever a form should appear. The script can be loaded before or after the elements, and one page can contain multiple forms.

```html
<script
  crossorigin="anonymous"
  defer
  integrity="sha384-G8oDligKJ0/Zuaer1dZfpMa35oQQEi1DNWYXjmSxmteeveZg6dhzTUuG8M8XnEK9"
  src="https://cdn.jsdelivr.net/npm/@formbrew/embed@0.4.0/dist/embed.js"
></script>

<formbrew-form token="YOUR_PUBLIC_TOKEN"></formbrew-form>
```

The loader registers the custom element and loads its version-matched stylesheet. The website origin must be configured in the form's Public Access settings.

Public tokens are publishable identifiers, not secrets.

### Element attributes and state

- `token`: required public form token.
- `base-url`: optional API base URL; defaults to production.
- `data-formbrew-state`: read-only lifecycle state set to `loading`, `ready`, or `error`.

Changing `token` or `base-url` reloads the element. Removing an element aborts its active request and destroys its form controller; reconnecting it renders again.

## Lifecycle events

```js
document.addEventListener("formbrew:ready", (event) => {
  console.log(event.detail.definition.name);
});

document.addEventListener("formbrew:success", (event) => {
  console.log(event.detail.result.id);
});

document.addEventListener("formbrew:error", (event) => {
  console.error(event.detail.phase, event.detail.error);
});
```

## Imperative rendering

Load the script as shown above, then call the global directly instead of using `<formbrew-form>`. Because the script tag uses `defer`, wait for `DOMContentLoaded` before calling `Formbrew.render`:

```html
<div id="contact-form"></div>
<script>
  document.addEventListener("DOMContentLoaded", () => {
    Formbrew.render("#contact-form", {
      token: "YOUR_PUBLIC_TOKEN",
      metadata: { source: window.location.pathname },
    });
  });
</script>
```

The returned promise resolves to a controller with `reset()` and `destroy()` methods.

TypeScript projects using the browser global can opt into its declarations with `import type {} from "@formbrew/embed/global"`.

## Loader attributes

- `data-formbrew-styles="false"`: disable automatic style loading.
- `data-formbrew-styles-url`: override the automatically derived stylesheet URL.

Strict Content Security Policies must allow the CDN under `script-src` and `style-src`, and the Formbrew API under `connect-src`. A script nonce is copied to the generated stylesheet link.
