HTML form submission6 min read
Redirect to a thank-you page after form submit
Send visitors to your own thank-you page after a form posts: the 303 redirect, the _redirect field, which domains are allowed and what refresh does.
A form can't redirect itself; the server that receives the post answers 303 See Other with a Location header, and the browser loads that page. With Ikiform, set Redirect after submit in the form's settings, or add a hidden _redirect input with an https: URL on one of the form's Allowed domains. With neither, visitors land on Ikiform's hosted thank-you page.
The example is a demo request form whose thank-you page is really a next step: it asks the visitor to pick a time. That makes the redirect target matter more than usual, and it raises the question this page is mostly about: who is allowed to decide where a form sends people.
What's different here
HTML has no attribute for "go here after submit". The action is where the data goes, and the page after that is whatever the server answers. So the redirect is always the receiving server's decision. When that server is Ikiform, there are exactly two ways to influence it, and they don't carry the same trust.
| Item | Redirect after submit setting | _redirect hidden input |
|---|---|---|
| Who sets it | Members of your workspace, in the dashboard | Anyone who can edit the page's HTML, or the visitor's browser |
| Allowed targets | Any http: or https: URL | https: only, on an allowed domain or a subdomain of one |
| Scope | One target for the whole form | One per page, so per language or per campaign |
| When both are set | Wins | Ignored |
The strict rules on _redirect exist because its value arrives with the post. Without them, anyone could put your form's URL in a link that posts and then bounces visitors to a phishing page, which is what an open redirect is.
- If the form has a Redirect after submit URL in its settings, Ikiform answers with a 303 to it and looks no further.
- Otherwise, if the post has a _redirect field, or _next, that is an https URL on an allowed domain with no port or credentials, Ikiform redirects there.
- Otherwise Ikiform redirects to its hosted thank-you page, which links back to your page when the post came from an https page on an allowed domain.
The form
<form action="https://ikiform.com/f/frm_xxxxxxxxxxxxxxxx" method="post">
<label for="email">Work email</label>
<input id="email" name="email" type="email" autocomplete="email" required />
<label for="company">Company</label>
<input id="company" name="company" autocomplete="organization" required />
<label for="team_size">Team size</label>
<select id="team_size" name="team_size">
<option value="1-10">1 to 10</option>
<option value="11-50">11 to 50</option>
<option value="51+">51 or more</option>
</select>
<input type="hidden" name="_redirect" value="https://example.com/demo/next-step" />
<input name="_gotcha" type="text" tabindex="-1" autocomplete="off" hidden />
<button>Request a demo</button>
</form>Add example.com under the form's Allowed domains and this posts, gets a 303 and lands on /demo/next-step. The thank-you page is ordinary HTML on your site:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="robots" content="noindex" />
<title>Thanks, pick a time</title>
</head>
<body>
<h1>Thanks. One more step.</h1>
<p>Pick a time for your demo. You'll get a calendar invite right away.</p>
<p><a href="https://cal.example.com/acme/demo">Choose a time</a></p>
</body>
</html>noindexkeeps it out of search results. Nobody should land there from Google, and a thank-you page in your analytics as an entrance is a sign something links to it.- Refresh is safe. Because Ikiform answered with
303, the browser loaded this page with GET, and reloading it sends nothing again. - If you count conversions on this page, count once per session. A refresh or a bookmark reloads it, and Ikiform's dashboard is the real count.
Redirecting to another site
Suppose you want to skip your own page and send people straight to a booking tool on another domain, such as cal.example.com or a scheduling service's domain. With _redirect, that domain would have to be in Allowed domains, and that list has a second job: it decides which sites may post to the form. Adding a scheduling service's domain means pages on that domain could post to your form too.
Use Redirect after submit in the form's settings instead. It accepts any URL, because only your workspace can set it, and it leaves Allowed domains listing only your own sites.
Different pages for different forms
The dashboard setting is one URL per form. When one form appears on several pages that need different thank-you pages, leave the setting empty and give each page its own _redirect. A German page sends visitors to the German thank-you page:
<input type="hidden" name="_redirect" value="https://example.com/de/demo/danke" />Adding a value to the redirect
Query strings on _redirect are kept, so you can pass what the visitor chose to the thank-you page. Set the value in a submit listener, which runs after the browser's validation and before the form is encoded:
const form = document.querySelector("form");
const redirect = form.elements.namedItem("_redirect");
form.addEventListener("submit", () => {
const size = form.elements.namedItem("team_size").value;
const next = new URL("https://example.com/demo/next-step");
next.searchParams.set("size", size);
redirect.value = next.href;
});The visitor arrives at /demo/next-step?size=11-50, and the page can show the right booking link for that team size. Keep it to non-personal values: query strings end up in browser history, server logs and analytics.
Redirecting after a fetch submit
A fetch call gets JSON, not a redirect, so Ikiform's redirect rules don't apply. Navigate yourself when the answer is ok:
const response = await fetch(form.action, {
method: "POST",
headers: { Accept: "application/json" },
body: new FormData(form),
});
const result = await response.json();
if (result.ok) location.assign("/demo/next-step");Use location.assign rather than location.replace if the back button should return to the form. The no-reload guide has the full handler with errors and loading state.
Check it works
- Under the form's Allowed domains, add your site's domain, plus
localhostwhile you develop. Leave it empty to accept posts from anywhere. - Submit the form from your live page. The address bar shows your thank-you page, and the Network panel shows the post answered with
303. - Press refresh on the thank-you page. The browser doesn't ask to resubmit, and the dashboard still shows one submission.
- Change
_redirectto an address on a domain that isn't allowed and submit. You land on Ikiform's hosted thank-you page instead, with no error. - Open Submissions in the dashboard. The new submission is there with every field you sent.
Gotchas
| Problem | Cause and fix |
|---|---|
_redirect is ignored even though the domain is allowed | Redirect after submit is set in the form's settings, and it always wins. Clear it to use per-page redirects |
Works in production, not on localhost | _redirect must be https: with no port, so http://localhost:3000/thanks never passes. Test on a preview deploy, or accept the hosted page locally |
| The hosted thank-you page has no link back to your site | It links back only when the post came from an https: page on one of the form's allowed domains. Add the domain, or redirect to your own page |
| The browser lands on Ikiform's thank-you page instead of yours | _redirect is ignored unless its domain is in Allowed domains and it is an https: URL. Add the domain, or set Redirect after submit in the form's settings instead. |
| The thank-you page shows in search results | Add <meta name="robots" content="noindex"> to it, and don't link to it from your navigation |
The exact rules, with examples of URLs that pass and fail, are in HTML forms. The overview explains why the answer is a 303 and not a 302 or 200.
Questions
The server that receives the form answers with a 303 redirect to the page. With Ikiform, set Redirect after submit in the form's settings, or add a hidden _redirect input with an https URL on one of the form's allowed domains.
Either the form's Redirect after submit setting is set, which always wins, or the URL fails the rules: it must be https, on an allowed domain or a subdomain of one, with no port, username or password. Forms with no allowed domains ignore _redirect.
Yes. Put the URL in the form's Redirect after submit setting, which accepts any http or https URL. Using _redirect instead would mean adding that site to your allowed domains, which also lets it post to your form.
Not from Ikiform's redirect, which uses the URL exactly as given. You can add non-personal values to the _redirect URL in a submit listener, or show a message from your own script after a fetch submit.
Stuck on a step, or want a guide for your situation? Email hello@ikiform.com.