Sveltekit Form Post 404

For site flamboyant-einstein-0374a6
My svelte-kit form is recognized by Netlify on build, but the Post results in a 404, and no post record appears under the site “Forms” section. I think I’ve read all of the relevant posts on the topic here.

For reference, the form is declared at /src/routes/contact.svelte and appears to be properly prerendering.

<script context="module">
  export const prerender = true;
</script>

<div>
  <form name="contact" method="post"  netlify>
    <input type="hidden" name="contact" value="contact" />
    <p> <label>Your Name: <input type="text" name="name" /></label></p>
    <p><label>Your Email: <input type="email" name="email" /></label></p>
    <p><label>Message: <textarea name="message" /></label></p>
    <p><button type="submit">Send</button></p>
  </form>
</div>

svelte.config.js is:

import preprocess from 'svelte-preprocess';
import { mdsvexConfig } from "./mdsvex.config.js";
import adapter from '@sveltejs/adapter-netlify';

/** @type {import('@sveltejs/kit').Config} */
const config = {
	preprocess: [
		preprocess({
			postcss: true
		})
	],
	kit: {
		target: '#svelte',
		adapter: adapter(),
		prerender: {
			crawl: true,
			enabled: true,
			force: true,
			pages: ['*'],
		}
	},
};

Is there something I should check for in my svelte-kit configuration that might be intercepting the submit action?

This was helpful docs: explain form handling and redirects using Netlify Adapter (#1481) · sveltejs/kit@e144771 · GitHub

And this was helpful

but I’m still short of a successful form submission. Any clues appreciated.

I got the form posts to get processed by explicitly supplying a submit handler:

  function encode(data) {
    return Object.keys(data)
      .map(key => encodeURIComponent(key) + "=" + encodeURIComponent(data[key]))
      .join("&")
  }

  const submit = (event) => {
    event.preventDefault();
    fetch("/contact", {
      method: "POST",
      headers: { "Content-Type": "application/x-www-form-urlencoded" },
      body: encode({
        "form-name": event.target.getAttribute("name"),
        ...name
      })
    }).then(() => goto("/")).catch(error => alert(error))
  }
</script>

I’m getting a post record on the site’s Netlify Forms tab, but only the form’s labels, not the data. Any clues on what’s needed here? Presumably the body code is incorrect or incomplete:

   body: encode({
        "form-name": event.target.getAttribute("name"),
        ...name

Again, it is a svelte-kit site: flamboyant-einstein-0374a6

Thanks

Hiya, @mgodeck :wave:

Thanks for writing such detailed posts and including the resources you have already referenced!

In addition to the video and github link you shared, have you read this Support Guide? It is generally the first port of call to debug any forms issues.

We also recommend trying to search the forums or look at topics tagged Netlify forms if you haven’t already - it’s likely your question was already asked by someone else! Quickly looking, it seems like this thread Proper way to submit netlify forms with SSR frameworks like svelte / sapper or this thread Form 404 - Static Form in Svelte / Sapper may be related to what you are encountering

If you are still having problems, please provide the following information:

  1. The URL for your live form as you want visitors to use it
  2. The URL of your deployed html form. In case you have a javascript form, we need to literally be linked to the html version you’ve deployed, as mentioned above (look for “ pure javascript form”)
  3. The form name that you’ve set and that shows in our UI
  4. Any errors or logs from the Netlify build logs, dashboard or browser developer console
  5. Description of anything you have tried that did or didn’t help or make things better/worse

The devil in the details: here’s a working solution for a svelte-kit form on Netlify:

/src/routes/hello.svelte

<script context="module">
	export const prerender = true;
</script>

<script>
	const handleSubmit = (e) => {
		e.preventDefault()
		let myForm = document.getElementById('myform');
		let formData = new FormData(myForm);
		fetch('/', {
			method: 'POST',
			headers: { "Content-Type": "application/x-www-form-urlencoded" },
			body: new URLSearchParams(formData).toString()
		}).then(() => console.log('Form successfully submitted')).catch((error) =>
			alert(error))
	}
</script>

<form id="myform" on:submit{handleSubmit} name="hello" method="POST" data-netlify="true">
	<p><label>Your Name: <input type="text" name="name" /></label></p>
	<p><label>Your Email: <input type="email" name="email" /></label></p>
	<p><label>Message: <textarea name="message"></textarea></label></p>
	<p><button class="mx-2 bg-red-50 border-2 px-2 rounded-md  block mx-auto" type="submit">Send</button></p>
	<br>
	<input type="hidden" name="form-name" value="hello">
</form>

export const prerender = true; is required to insure that an HTML form is rendered a build time, so that Netlify can register it. That directive needs to be in context=module tagged script so that it is part of the build, not just runtime, like the submit hander is.

The body attribute of the my submit handler from the start of this thread was wrong, the working version is simply. body: new URLSearchParams(formData).toString()

The HTML form definition from the start of this thread, the name attribute in the hidden input element was wrong in

<input type="hidden" name="contact" value="contact" />
should be
<input type="hidden" name="form-name" value="contact" />

For the sake of clarity, configuring pre-render in sevelte.config.js that I mentioned in the thread above is not necessary for our purposes here of simply getting a form to pre-render.

In the end it’s not so complicated, but there are so many fragments of examples, that its easy to miss details. It’s nice to see form posts working now in Svelte-kit and Netlify!

Hey there, @mgodeck :wave:

I am so glad you got to the bottom of this! Thank you for coming back and sharing these thorough details with the Forums. Knowledge sharing is definitely beneficial for future members who encounter something similar. :netliconfetti:

There is a detail in the working svelte form example above that is worth noting: the on:submit binding omits the assignment operator ( = ). Svelte documentation specifies on:<event>={binding}, and that works for other bindings, such as on:keyup or on:click but not for on:submit. For a more complete discussion, I’ve opened this as an issue on the svelte project.

Note that this behavior is against svelte@next If the issue describes the problem correctly, and it is fixed in svelte, then any forms that are coded as indicated in the solution above will presumably no longer post. (your deployed code will of course continue to work until you push a new build after the issue is fixed in svelte, (when pinned to svelete@next). The remedy will then be simply to supply the binding assignment operator (the “equals” character) in the on:submit binding. Heads up.

1 Like

Thank you for that additional detail!