When I submit, I get a 404 error from Netlify with the back button.
In svelte, I can override the default behavior of the button pretty easily, but wouldnt I still have to post the request? I googled and searched the forums and I couldn’t find an answer specific to posting directly to Netlify forms via javascript or some other solution other than the default HTML behavior.
So two questions:
Am I even doing it right? (lol)
Will I need to implement a javascript solution to post data to the Netlify form API using svelte? If so, how?
Thank you for your time, I am really enjoying the platform and am currently trying to build a business model around it.
Depends on you. JavaScript form submission via AJAX will allow you to submit the form data without the page getting refreshed. You then have to manipulate your DOM to show/hide success/error messages. If you are fine with the page reloading, you don’t need to.
Regarding the how part, the form docs already have a jQuery example.
Here’s a rough vanilla JS example:
/* assumed that your form will have a class named 'contact-form' */
var form = document.querySelector('.contact-form');
/* form submission handler */
form.addEventListener('submit', function(e)
{
e.preventDefault(); // disables the default form submit action
/* gathers form data to submit */
var XHR = new XMLHttpRequest();
var FD = new FormData(form);
/* submission successful */
XHR.addEventListener('load', function(event)
{
/* show your success message */
}
/* submission failed */
XHR.addEventListener('error', function(event)
{
/* show your error message */
}
/* actually submits the form */
XHR.open('POST', '#');
XHR.send(FD);
}
Hello! Thank you for the reply. I tried the above via svelte coding and I get a 404 error on the post #. The data is loaded, but because of the SSR it doesn’t recognize the #. Here is the code:
<form class="content">
<p>
<label>Name<input type="text" bind:value={$user.name} /></label>
</p>
<p>
<label>E-mail<input type="text" bind:value={$user.email} /></label>
</p>
<p>
<label>Telephone<input type="text" bind:value={$user.phone} /></label>
</p>
<button on:click|preventDefault={submitForm}>Reach out</button>
</form>
<script>
import { user } from "../store.js";
let submitForm =(event)=>{
event.preventDefault();
var oReq = new XMLHttpRequest();
oReq.open('POST','#');
oReq.send($user);
};
</script>
Im thinking because its SSR I will have to play around with component mounting or something to get the post to properly go through. Any other suggestions very much appreciated!
The JavaScript one also won’t work unless the pure HTML one is working. Did the 404 error in your original form get resolved?
Also, I’m not familiar with Svelete’s way of working, but, as long as the HTML form is working normally and the script is loaded in the browser, it should work.
What I am realizing now is that I am using sapper, which is a framework that acts as a server of sorts, which is rendering my views. After googling, “post request from sapper” I am realizing this has nothing to do with netlify probably! Still, I will return when i figure it out and post my solution. Thank you!
I havent figured it out, but so far I have figured out that just doing the standard form post with hidden field submits a form, however the body is empty. I found online that you can disable the service worker and it will work, but it didn’t. I also installed body-parser and made a JS file on my contact.svelte route that goes like this
export async function post(req, res, next) {
/* Initializes */
res.setHeader('Content-Type', 'application/json')
/* Retrieves the data */
var data = req.body
/* Returns the result */
return res.end(JSON.stringify(data))
}
Although I don’t think this ever runs because when.I run a fetch request from the submit button it just gives me a 404 error every time instantly. I’ve tried all sorts of stuff in the fetch url and nothing changes the 404.
I am at a complete loss really. I might try this with just svelte and see how well it works…
Is your code base / repository for your site open source / publicly viewable? Happy to take a look for you; Forms can be finicky with some of these more progressive / dynamic-front-end SSGs
You’re going to have problems submitting the form like this. You’ve set the Content-Type header correctly (form encoded) but the body isn’t actually form encoded content… and for that matter, I think it’s structurally invalid
You’ll have to forgive me - I’m actually writing the part 2 right now which more directly pertains to this situation, but I just wrote this last night as a primer for how Netlify Forms works. I’d recommend giving it a read then making sure that your custom submit handler (above) is adhering to the spec of a Forms Listener - the content type, the body formatted correctly, and the form name being submitted within that url-encoded payload.
Ive verified locally that the new form data is good. Everything seems like it should work. The form is submitted but I get a 404 still in the console. Im not sure what else to try to be honest. Thinking of redoing an app down the road with just svelte see if its a sapper deal or something.
So i am at like zero hour for a big trip this weekend and am trying to finish work for the client while I am gone so I have very little hope of testing this, but I wanted to reach out and thank you for taking the time to review this as it has been a huge bummer to me that it doesn’t work. I will update what happens when I get back from my trip worst case scenario. Have a great weekend.
The solution here was indeed that the values were wrong! Huge ultra massive props to @jen for the solution!
I simply used an ES6 variable casting dealio.
<script>
let form;
let submitForm =(event)=>{
let formdata = new FormData();
formdata.append('name',`${user.name}`); //notice we cast the store values as strings with the `${var}` syntax
formdata.append('email',`${user.email}`);
formdata.append('telephone',`${user.telephone}`);
fetch("/contact/", {
method: "POST",
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body: formdata,
})
.then(() => alert("Success!"))
.catch(error => alert(error));
event.preventDefault();
}
import { user } from "../store.js";
</script>