- The site is here: https://www.guestcrafter.com
- The password to get into the content is: spin1234
- The route that has the ajax form is: https://www.guestcrafter.com/info-we-need
- The route that has the hidden form is: https://www.guestcrafter.com/form/
I have a SSR SvelteKit app that has a form on it to collect basic info + a single image. All the routes on the app are protected via cookie verification + 302 redirects if the cookie doesn’t exist (or isn’t correct).
I setup a dummy form on a public route (https://www.guestcrafter.com/form/) to get Netlify to recognize the form, this works fine and I see the inputs in my build as expected. Here is the dummy form code for reference:
<script context="module">
export const prerender = true
</script>
<form name="info" data-netlify="true" hidden>
<input type="hidden" name="form-name" value="info" />
<input type="text" required tabindex="0" name="Name" />
<input type="text" required tabindex="0" name="Location" />
<input type="file" tabindex="0" name="HeadShot" />
<input type="text" required tabindex="0" name="PrimaryURL" />
<input type="text" required tabindex="0" name="SecondaryURL" />
<textarea required tabindex="0" name="Biography" maxlength="1000" />
<textarea required tabindex="0" name="TechSetup" maxlength="500" />
<input type="email" required tabindex="0" name="Email" />
<input type="tel" required tabindex="0" name="Phone" />
<button type="submit">
Submit Form
</button>
</form>
The actual form is SSR but since it is behind a simple custom auth solution Netlify doesn’t see it. So my assumption is submitting the form should basically be the same as a JS rendered form.
Here is the form component with all the markup + the handle function:
<script>
let visible = true
let sending = false
import { slide } from "svelte/transition"
let formData = {
Name: '',
Location: '',
PrimaryURL: '',
SecondaryURL: '',
Biography: '',
TechSetup: '',
Email: '',
Phone: ''
}
let HeadShot
const handleSubmit = event => {
// button formatting
sending = true
// debug logging
console.log(formData)
event.preventDefault()
// build the form data
let processedForm = new FormData()
processedForm.append('form-name', `info`)
processedForm.append('Name', formData.Name)
processedForm.append('Location', formData.Location)
processedForm.append('HeadShot', HeadShot[0], HeadShot[0].name)
processedForm.append('PrimaryURL', formData.PrimaryURL)
processedForm.append('SecondaryURL', formData.SecondaryURL)
processedForm.append('Biography', formData.Biography)
processedForm.append('TechSetup', formData.TechSetup)
processedForm.append('Email', formData.Email)
processedForm.append('Phone', formData.Phone)
// debug logging of FormData
for (var pair of processedForm.entries()) {
console.log(pair[0]+ ', ' + pair[1]);
}
// send the form data
fetch("/", {
method: "POST",
headers: { 'Content-Type': 'multipart/form-data' },
body: new URLSearchParams(processedForm).toString()
}).then(() => (visible = false)).catch(error => alert(error))
}
</script>
{#if visible}
<form on:submit|preventDefault={handleSubmit}
out:slide={{duration: 300}}
method="POST" data-netlify="true"
name="info"
>
<label>
<header>Display Name</header>
<input type="text" required tabindex="0" name="Name" bind:value={formData.Name} />
<footer>Example: Mary Gunn or Mary G.</footer>
</label>
<label>
<header>Location</header>
<input type="text" required tabindex="0" name="Location" bind:value={formData.Location} />
<footer>Example: Texas or Kansas City (can be general)</footer>
</label>
<label>
<header>Head Shot</header>
<input type="file" tabindex="0" name="HeadShot" bind:value={HeadShot} />
<footer>Your favorite profile pic is great</footer>
</label>
<label>
<header>Primary Link URL</header>
<input type="text" required tabindex="0" name="PrimaryURL" bind:value={formData.PrimaryURL} />
<footer>Your top link (youtube channel, blog, instagram etc)</footer>
</label>
<label>
<header>Secondary Link URL</header>
<input type="text" required tabindex="0" name="SecondaryURL" bind:value={formData.SecondaryURL} />
<footer>Your secondary link (youtube channel, blog, instagram etc)</footer>
</label>
<label>
<header>Short Bio</header>
<textarea required tabindex="0" name="Biography" maxlength="1000" bind:value={formData.Biography} />
<footer>Used on our website. 1000 characters max.</footer>
</label>
<label>
<header>Tech Setup</header>
<textarea required tabindex="0" name="TechSetup" maxlength="500" bind:value={formData.TechSetup} />
<footer>Breifly describe your tech setup for making videos. Do you use your phone? Web cam? Etc.</footer>
</label>
<h2>Private Contact Info</h2>
<p>We won't share this information with anyone. We like to have this information just-in-case.</p>
<label>
<header>Your Email</header>
<input type="email" required tabindex="0" name="Email" bind:value={formData.Email} />
<footer>Best email for personal contact.</footer>
</label>
<label>
<header>Phone Number</header>
<input type="tel" required tabindex="0" name="PhoneNumber" bind:value={formData.Phone} />
<footer>Best phone to reach you. (We sometimes text to remind about the show.)</footer>
</label>
<button type="submit">
{#if sending}
Sending...
{:else}
Submit Form
{/if}
</button>
</form>
{:else}
<p in:slide={{delay: 300, duration: 300}}>Thank you for sending in your info. We will reach out if we have any questions.</p>
{/if}
If you go to the form and try submitting it, you’ll see that the debug data logs correctly and as expected.
I have tried many iterations of the form and the function and have never gotten anything to register in the Netlify admin, spam or otherwise. I have also tried the form with the file field excluded and the content type set to
application/x-www-form-urlencoded
I have also tried sending the post body in all the different methods in the docs… You can see I am using the “body: new URLSearchParams(processedForm).toString()” in the above example, but I have also just sent the raw FormData, and also tried the
function encode(data)
example from the docs. All with the same result: The post finishes with out any feedback or error. And nothing shows up in the admin.
I have no idea what else I could try to get this working. I am open to all suggestions.
Thanks.