Skip to content
SproutCart
In developmentShopper input

Formwell

Forms that live on your storefront and land in your inbox.

Contact and enquiry forms served as pages inside your theme, validated on the server, rate-limited per form, stored against the store, and emailed to whoever you choose the moment they arrive.

Formwell — key art
Status
In development
Built with
App proxy · Webhooks · GraphQL Admin

What it does

  • Text, email, long text, dropdown and checkbox fields — up to 30 per form
  • Each form is a page on the store's own domain, rendered inside the active theme through the app proxy
  • Server-side validation: required fields, valid email addresses, dropdown values that exist, a length cap on every answer
  • At most 30 submissions a minute per form, and only requests that carry Shopify's proxy signature
  • Every submission stored, listed in the admin, and emailed to the form's notification address
On this page

Formwell gives a store forms that belong to it: a contact form, a wholesale enquiry, a returns question. Each form is a page at the store's own address, rendered inside its theme; every submission is checked on the server, kept in the app, and emailed to the address the merchant chose. It is in development and not yet on the App Store.

Every store needs a form that is not a checkout. A contact form, a wholesale enquiry, a returns question, a request for a custom order. The theme usually ships one contact form, it sends everything to one address, and the moment a store needs a second form with different fields the options get worse.

The problem this solves

There are two common workarounds, and both leak.

The first is an embedded form from a general-purpose form service. It works, but it sits in an iframe that does not look like the store, the submissions live in somebody else’s account, and the shopper’s message has left Shopify before anyone at the store has read it.

The second is to bend the theme’s built-in contact form into something it was not designed to be. It can carry a few extra fields, but every submission arrives as an email and nowhere else. If that email is filtered, deleted or sent while the one person who reads it is on holiday, the enquiry is simply gone.

Formwell takes the plain route. The form is a page on the store’s own domain, drawn by the store’s own theme. The submission is stored in the app before anything else happens, and only then emailed.

What the first release does

A merchant creates a form in the app with a title, a success message, a list of fields, an optional notification address and an on/off switch. A new form starts with three required fields: name, email and message.

Five field types are available: single-line text, email, long text, a dropdown with up to fifty options, and a checkbox. A form can have up to thirty fields. Field names must be unique and each label has a sensible length limit, and a field list that breaks any of those rules is refused when the merchant saves it, not discovered later by a shopper.

Each form gets a storefront address on the store’s own domain, served through Shopify’s app proxy. The app returns the form as Liquid, so Shopify renders it inside the active theme with the store’s header, footer, fonts and colours. Everything the merchant typed — titles, labels, options — is escaped before it reaches the page, so a label cannot inject markup into the store. A form that is switched off, or an address that names no form, returns a plain “This form is not available”.

Checked on the server, not only in the browser

The browser’s own validation is a convenience for the shopper. It is not a defence: anything a browser sends can be sent without the browser.

So every submission is checked again by the app. Values are trimmed and capped at 5,000 characters. An email field must hold a valid address and is stored lowercased. A dropdown value must be one of the options the merchant defined. Fields the form does not have are dropped rather than stored. When something fails, nothing is stored and the shopper is asked to check the form and try again, rather than being shown a success message for a message nobody will receive.

Every request, to show the form or to submit it, must carry Shopify’s proxy signature, which proves it came through the store. Each form accepts at most thirty submissions a minute; past that, the app answers “too many requests” until the minute is up. That is not a CAPTCHA, and it does not claim to stop a patient spammer, but it puts a ceiling on how fast a script can fill a form.

Stored first, then emailed

When a submission passes validation, it is written to the app’s database before anything else. Only then does a background job send it to the form’s notification address, as a table of every field and its value. The job is throttled per store, so a burst of submissions cannot turn into a burst of mail that a provider might treat as abuse.

The order matters. If the email is delayed, filtered or lost, the submission is still in the app’s Submissions list, with the form it came from and the address the shopper gave. The inbox is a notification, not the record.

When the shopper is logged in to a customer account, Shopify’s signed proxy request includes their customer ID, and the app keeps it with the submission. The first email field’s value is also stored on its own. Both exist for the same reason: when a customer asks a store to delete their data, the app has something specific to search for.

What it does not do yet

  • Fields are edited as a short JSON list in the admin. It is precise and it is validated, but it is not a drag-and-drop builder.
  • A form is a page of its own. There is no theme block that drops a form into the middle of another page.
  • No file uploads, no CAPTCHA, no CSV export, and no redirect to another page after a successful submission.
  • The storefront form and the notification email are in English only, even though the admin is available in English and French.
  • A required checkbox is enforced by the shopper’s browser but not checked again on the server.
  • Submissions can be read in the admin but not yet deleted from it.
  • It has been built and tested against a simulated Shopify, not yet against a live store, and it is not listed on the App Store.

How to judge a form app

Five questions are worth asking before choosing one:

  1. Where is a submission stored before it is emailed? If the answer is “it is not”, the inbox is the only copy.
  2. Is the form validated by the server, or only by the browser?
  3. Does the form render inside your theme, or in a frame that does not look like your store?
  4. What stops a script from submitting a thousand times? Ask for the mechanism, not the adjective.
  5. When a customer asks to be forgotten, how does the app find their submissions? It needs something to match on, and it should say what.

Support and privacy

How to get help with Formwell, and what it stores about your store and your customers.

Keep exploring

The catalogue in order — one step back, one step forward.

What happens next

Formwell isn't installable yet. Its progress lands in the changelog.