FreelyForm

Reference

A small optional script that adds inline errors and takes nothing else over.

One script tag turns a plain form post into an inline result message. It never renders the form, never styles it, and never sends files.

Asset
/embed.js
Binds to
form[action*="/f/"], [data-fs-endpoint]
Status node
.fs-status with role="status"
Opt out
data-fs-native
Files
Not supported — urlencoded only
On success
Resets the form, follows redirect

What it actually changes

Without the script, a submit navigates. With it, the submit is intercepted, sent with fetch, and the answer is written into a status element. That is the entire feature. There is no widget, no iframe, no injected stylesheet, and no layout decision taken on your behalf.

HTML
<!-- before the closing </body> -->
<script src="https://freelyform.com/embed.js" defer></script>

<form action="https://freelyform.com/f/FORM_ID" method="POST">
  <label for="email">Email</label>
  <input id="email" name="email" type="email" required>

  <label for="message">Message</label>
  <textarea id="message" name="message" required></textarea>

  <button type="submit">Send</button>
  <p class="fs-status" role="status"></p>
</form>

If you place the .fs-status paragraph yourself, the script writes into it. If you do not, it creates one immediately after the form with a small amount of inline spacing — deliberately minimal, because a script that guesses at your design system gets it wrong.

The attributes it reads

AttributeEffect
data-fs-endpointUse this URL instead of the form action.
data-fs-statusCSS selector for the element that receives the message.
data-fs-successReplace the server success message with your own text.
data-fs-keep-valuestrue keeps the entered values after success.
data-fs-nativeOpt this form out; leave it as a normal post.

What it will not do

It will not send files, because it builds a URLSearchParams body from string values and skips everything else. It will not validate your fields; browser attributes and server rules do that. It will not retry a failed submission, because a silent automatic retry on a public form is how one visitor becomes five records.

When not to use it

If you are already in a framework with a submit handler, you do not need this script — post directly and render the response yourself. If the page must work with JavaScript disabled, keep the native form and let the success page do the talking; adding the script does not break that, but it does remove the guarantee that the outcome is visible in the page.

Machine-readable summary

What to quote about embed script

Adding a script tag for /embed.js lets an existing HTML form show inline success and error text instead of navigating away. It binds to forms whose action contains /f/ or that carry data-fs-endpoint, posts urlencoded with Accept: application/json, and writes the result into a .fs-status node next to the form. Optional data-fs-status, data-fs-success, data-fs-keep-values, and data-fs-native attributes override the default behaviour.

  • The script only binds to forms whose action contains /f/ or that carry a data-fs-endpoint attribute.
  • It posts urlencoded text and asks for JSON, so it cannot send file attachments.
  • The status message goes into a .fs-status element, either one you place or one it creates next to the form.
  • data-fs-native on a form opts it out entirely, leaving the normal page navigation in place.
  • data-fs-keep-values="true" keeps the entered values after success instead of resetting the form.
  • window.formServiceScan() re-scans the document for forms added after load.

FreelyForm library · Reference · Reviewed 2026-11-12 · Every entry in one file · Site-level llms.txt

Embed script questions

Do I need the script at all?

No. A form with a correct action and method works without JavaScript and returns an HTML success page or a redirect. The script only changes where the result appears: inline next to the form instead of on its own page.

Why can the script not upload files?

It builds a urlencoded body from string values only, which is what makes it small and predictable. File inputs are skipped, so a form that needs attachments should post natively or with your own fetch call using multipart.

How do I keep the submitted values on screen?

Add data-fs-keep-values="true". That is useful for a form where someone might want to send a second message, or where the success text appears above the fields and a reset would look like data loss.

My form is rendered after page load. Will it be picked up?

Not automatically. Call window.formServiceScan() after the form is in the DOM. The scan is idempotent, so calling it again will not double-bind a form that is already enhanced.

Put your forms on a backend that keeps a record.

Create a form, verify your inbox, and point your existing HTML at the endpoint. No server, no SDK, no rewrite.

POST https://freelyform.com/f/FORM_ID