Embedding Forms

One of the core features of Flux is the ability to embed secure, dynamic forms into static sites (like Hugo, Jekyll, or plain HTML) without needing a backend.

Flux uses HTMX to inject the form directly into your page. This provides a seamless user experience—validation errors and success messages appear instantly without reloading the browser window.

Basic embed

To add a form to your website, you simply need a container <div> that tells HTMX where to fetch the form content.

Step 1: Include the HTMX Library
Add this script tag to your page <head> or just before the closing </body> tag. You only need to include this once per page.

<script src="[https://unpkg.com/htmx.org@1.9.10](https://unpkg.com/htmx.org@1.9.10)"></script>

Step 2: Add the Form Container Place this snippet where you want the form to appear. Replace the URL with your Flux instance address and form slug.

<div id="flux-form-wrapper"
     hx-get="https://{your-flux-server}/form/{form-slug}"
     hx-trigger="load"
     hx-swap="innerHTML">
</div>

How it works:

  1. hx-trigger="load": As soon as the page loads, HTMX contacts your Flux server.
  2. hx-swap="innerHTML": Flux generates the HTML for the form (CSRF tokens, Captcha scripts included) and injects it into this div.
  3. Submission: When a user submits, Flux handles validation on the server. If there are errors, it returns the form HTML with error messages. If successful, it returns the Success Message defined in your config.

Adding a loading state

Since the form is fetched asynchronously, there might be a slight delay before it appears. You can improve the user experience by including a loading spinner inside the container.

The content inside the div will be displayed immediately and then replaced once the form loads.

<div id="flux-form-wrapper"
     hx-get="https://{your-flux-server}/form/{form-slug}"
     hx-trigger="load"
     hx-swap="innerHTML">
     
    <div class="flux-loading" style="text-align: center; padding: 2rem; opacity: 0.6;">
        <svg width="24" height="24" viewBox="0 0 24 24" xmlns="[http://www.w3.org/2000/svg](http://www.w3.org/2000/svg)">
            <style>.spinner{transform-origin:center;animation:spinner_AtaB .75s infinite linear}@keyframes spinner_AtaB{100%{transform:rotate(360deg)}}</style>
            <path d="M12,1A11,11,0,1,0,23,12,11,11,0,0,0,12,1Zm0,19a8,8,0,1,1,8-8A8,8,0,0,1,12,20Z" opacity=".25"/>
            <path d="M10.14,1.16a11,11,0,0,0-9,8.92A1.59,1.59,0,0,0,2.46,12,1.52,1.52,0,0,0,4.11,10.7a8,8,0,0,1,6.66-6.61A1.42,1.42,0,0,0,12,2.69h0A1.57,1.57,0,0,0,10.14,1.16Z" class="spinner"/>
        </svg>
        <p style="margin-top: 10px; font-family: sans-serif; font-size: 0.9rem;">Loading Form...</p>
    </div>
</div>

Customizing Styles

Flux forms come with a default, clean theme inspired by shadcn/ui. It uses neutral colors and standard spacing that blends well with most designs.

Overriding defaults

The default theme uses standard CSS classes (.flux-input, .flux-label, .flux-button). You can simply add CSS to your website to override specific properties (e.g., changing the button color to match your brand).

Checkout more info about styles in the note Default style.

Naked mode

If you prefer complete control over the design, you can request the form without any CSS styles attached. This renders plain HTML elements that inherit your website's global styles.

To do this, simply append ?style=naked to the source URL:

<div hx-get="[https://flux.example.com/form/contact-us?style=naked](https://flux.example.com/form/contact-us?style=naked)" ... >

Find out more about this in the note Naked mode.

Troubleshooting

The form doesn't load.

  • Check your browser console (F12). If you see a CORS Error (Cross-Origin Resource Sharing), it means your website domain is not authorized.
  • Fix: SSH into your Flux instance, edit the form configuration, and add your website's URL (e.g., https://mysite.com) to the Allowed Origins list.