Skip to content
WebShield Docs

Forms on a static site

How to collect form messages on a static site without a server of your own, by email and in the control panel.

Point the form at /webshieldpro/forms/<name> on your site. For example:

<form action="/webshieldpro/forms/contact" method="post">
<p><label>Name<br><input name="name" required></label></p>
<p><label>Email<br><input name="email" type="email" required></label></p>
<p><label>Message<br><textarea name="message" rows="5" required></textarea></label></p>
<p><button type="submit">Send</button></p>
</form>
<script src="/webshieldpro/forms.js" defer></script>

That’s enough: the form takes your site’s styling, and <script> handles spam protection and the reply in place of the form. Change the fields and labels however you like; only action and method="post" matter.

On publishing we find such forms in the HTML ourselves and list them on the site card, in the Forms block. Fields from the markup become the list of allowed fields.

Naming rules: lowercase Latin letters, digits, - and _, up to 64 characters, case-sensitive.

Messages aren’t accepted without the forms.js script. It guards the form against spam and shows the reply right on the page: the form turns into a message styled by your site’s CSS (classes ws-form-success and ws-form-error). How to change the text, use your own block or your own page: see What the visitor sees.

Add the script to every page that has a form. A visitor with JavaScript turned off will be asked to turn it on and send the message again.

You change the list on the form card, in Email recipients. Your account’s address is added automatically. You can remove it or add any other mailbox if you like.

Messages are kept in the control panel either way, so you can always read them there.

We can’t see a form that you create with JavaScript in the HTML. There are two ways:

  • add the form on the site card by hand: Add form, with the same name as in the address;
  • or just send the first message. The form shows up as an unknown form, messages are kept but not emailed until you press Accept form.

Sending with fetch works too. Ask for JSON, and instead of the thank-you page you get {"ok": true}. Be sure to add the forms.js service fields to the body, the message isn’t accepted without them:

const body = new URLSearchParams(new FormData(form));
// Service fields from forms.js: the message isn't accepted without them.
for (const [key, value] of Object.entries(window.wsForms?.fields() ?? {})) body.set(key, value);
await fetch("/webshieldpro/forms/contact", {
method: "POST",
headers: { Accept: "application/json" },
body,
});

By default the form on the page turns into “Thank you! Your message has been sent.”, and on an error a hint appears above the button.

If the protection takes a message for spam, the visitor sees that it wasn’t sent and is asked to reach you another way. The message itself still lands in the Spam folder of your panel, so look there if you expected something that never arrived.

All of this can be changed:

What you want Where to set it
Send visitors to your own page the Page after sending field in the control panel
Change the message text data-success and data-error attributes on the form
Show your own block instead of the form an element with the data-ws-success attribute
A regular page load, no message the data-ws-submit="page" attribute on the form

The simplest way to keep your site’s look is a thank-you page on the site itself, with visitors sent there.

  1. Publish a page on the site, for example /thanks/.
  2. Open Sites → Manage for that site and expand the form in the Forms block.
  3. Type the path into Page after sending and press Save.

Only a path on the same site works: /thanks/ is fine, https://example.com/thanks/ isn’t. An empty field brings back the default behaviour. When the page is set, the data-success text isn’t shown: the visitor goes to the page instead.

The attributes go right on <form>:

<form action="/webshieldpro/forms/contact" method="post"
data-success="Got it, we'll reply within a day."
data-error="Something went wrong, write to us at hello@example.com.">
  • data-success is the text after a successful send. The form hides, and <p class="ws-form-success"> with this text takes its place.
  • data-error is the text when the message isn’t accepted. It shows above the button in <p class="ws-form-error">, and the form stays put. The spam-check refusal and file errors have their own wording, which the attribute doesn’t change.

The text is inserted as is, without HTML: tags show up as plain characters. Style it in your site’s CSS with the ws-form-success and ws-form-error classes.

Your own block instead of the form: data-ws-success

Section titled “Your own block instead of the form: data-ws-success”

Need more than a line of text, like a heading, a picture, links? Build the block yourself, hide it with hidden and mark it with data-ws-success:

<form action="/webshieldpro/forms/contact" method="post">
<!-- form fields -->
<div data-ws-success hidden>
<h3>Thank you!</h3>
<p>While you wait, <a href="/blog/">have a look at the blog</a>.</p>
</div>
<button type="submit">Send</button>
</form>

After sending, the script hides the fields and the button and shows this block. The block can also live outside the form: then put the form’s name in the attribute, <div data-ws-success="contact" hidden>, and the script hides the whole form.

A regular page load: data-ws-submit=“page”

Section titled “A regular page load: data-ws-submit=“page””

Don’t need a message in place? Add data-ws-submit="page" to the form. Sending becomes a regular page load: to Page after sending or to our thank-you page.

A CV, a screenshot of an error, a photo: add a regular file field to the form:

<form action="/webshieldpro/forms/contact" method="post" enctype="multipart/form-data">
<p><label>Name<br><input name="name" required></label></p>
<p><label>File<br><input name="attachment" type="file" multiple></label></p>
<p><button type="submit">Send</button></p>
</form>
<script src="/webshieldpro/forms.js" defer></script>

Without enctype="multipart/form-data" the browser would send only the file name. forms.js sends the file itself, but better not to forget the attribute.

Good to know:

  • Limits: up to 10 MB per file, up to 5 files and up to 25 MB per message.
  • Executables aren’t accepted: .exe, .msi, .apk, .bat, .jar, Office documents with macros and the like.
  • The form body including files is up to 27 MB.
  • The number of messages per month depends on the plan.
  • Messages are kept for 90 days, spam and messages to unaccepted forms for 14.