Ghost
Ghost contact form without a backend
Ghost has no built-in contact form; its signup forms create members and newsletter subscriptions, not messages. The simplest way to take messages is an HTML card on a Contact page whose form posts to Formward. Formward stores each submission in Sweden, filters spam and emails it to you, and Ghost needs no theme changes or integrations.
01Create your form in Formward
Sign up at formward.eu, create a form and copy its endpoint URL (https://forms.formward.eu/f/your-form-id). If only your blog should be able to post to it, add your site's origin, for example https://yourblog.com, to the form's allowed origins.
02Add an HTML card to a Contact page
In Ghost Admin, create a page called Contact. On an empty line in the editor, type /html (or click the + button and choose HTML) and paste the form below. Ghost's own help names forms as one of the things HTML cards are for, and the markup is output on the published page.
The hidden _redirect field sends visitors to /thanks/ on your own site after a normal submit, so create a short Thanks page with that URL, or delete the field to use Formward's thank-you page.
<form class="formward-form" action="https://forms.formward.eu/f/your-form-id" method="POST"> <label>Name <input type="text" name="name" required /></label> <label>Email <input type="email" name="email" required /></label> <label>Message <textarea name="message" rows="5" required></textarea></label> <!-- Where Formward sends the visitor after a normal submit. --> <input type="hidden" name="_redirect" value="/thanks/" /> <!-- Honeypot: keep hidden and empty. --> <input type="text" name="_gotcha" style="display:none" tabindex="-1" autocomplete="off" /> <button type="submit">Send</button> <p class="formward-status" role="status"></p> </form>03Optional: submit without leaving the page
Open the page's settings menu in the editor, go to Code injection and paste this script into the page footer field, so it loads on this page only. It posts the form with fetch and an Accept: application/json header, so Formward replies with JSON ({ ok: true, id }) instead of a redirect, and the script writes the result under the form. If the script does not load, the form still submits normally.
<script> document.querySelectorAll("form.formward-form").forEach(function (form) { var out = form.querySelector(".formward-status"); form.addEventListener("submit", async function (e) { e.preventDefault(); out.textContent = "Sending..."; try { var res = await fetch(form.action, { method: "POST", headers: { Accept: "application/json" }, body: new FormData(form), }); var data = await res.json(); if (!res.ok || !data.ok) throw new Error(data.error); form.reset(); out.textContent = "Thanks, your message was sent."; } catch (err) { out.textContent = res && res.status === 429 ? "Too many attempts. Wait a minute and try again." : "Could not send. Please try again."; } }); }); </script>04Or: a contact button on every page
If you would rather not have a Contact page, Formbutton adds a floating button that opens a small contact form. Paste the script tag into the Site footer field under Settings, Advanced, Code injection in Ghost Admin. Ghost adds it before the closing body tag on every page. It posts to the same endpoint.
<script src="https://formward.eu/formbutton.js" data-form-id="your-form-id" data-button-text="Contact us"></script>05Test a submission
Publish the page and open it in a private window, so you are not signed in to Ghost Admin. Send a message and check that it appears in your Formward dashboard and your inbox. A submission that fills the hidden _gotcha field is filed as spam and never emailed.