Webforms with Svelte

Webforms are an essential component of a website which intends to stay connected with website visitors. We started to use Svelte for this type of interactive UI elements. It was surprisingly simple to apply it for our sites hosted on Firebase/Firestore.

We implemented and different approach previously, using an inline script submit handler. More detailed information about our previous approach can be found here: Webforms

Svelte Setup

We build a small Svelte app, one or two components if the form is shown on the page, or two components if the form is shown as modal. The form can be tested and debugged using a local dev build. Once finalized, the app is built. In a page where the form is published, a anchor div is added and the compiled js is loaded.


No difference to a regular form. Input, select, textarea tags embedded within a form tag. Regular submit is disabled using Svelte's approach:

<form name="contact" on:submit|preventDefault={handleSubmit}></form>

The following samples use a specific app for each form.

Having built these three forms, we noticed similarities between the different implementations and created a new, generic webform handler, similar to what we have used previously, built in javascript.

The improved svelte app webform handler can serve any webform: Muuuh Contact Form is an application of the generic version. The generic version depends on a static json file for form and field settings.

  • Generic Webform Handler (in page)

The first published webform using this generic webform handler is published here: Request SEO Audit.

  • Search Boxes
  • Surveys


Automated Submissions: Submit handler validates data and if found valid, the data is submitted as json object to Firestore. Our validation, besides making sure that all required fields are completed, checks if the agent submitting the form has cookies enabled.

Spamming: A firebase function can be built to act server side to a submission with a client independent validation and triggering an email to the site admin for notification. If a response to the person submitting a form is required, don't include the submitted content which removes the incentive to use the form for spamming.

SQL Injection: Prevented by proper setup of Firestore CRUD rules (CRUD: create, read, update, delete). Only create documents within a specific collection is allowed. Read/update/delete of documents in the same collection and create/read/update/delete of documents in other collections aren't allowed.


Using css in the svelte app generates inline style statements. Although, this use style can be prevented, some features require it. For example transition effects for modal containers. We haven't yet figured out how to configure Svelte so that CSP doesn't have to include "inline-safe" statement.

Unfortunately, Firebase/Firestore doesn't provide a library optimized for Svelte. There are community built libraries available but we prefer using the libraries provided by Google itself. The current SDK works so we stick to it.