I don’t know if this will apply, but I came across this post while working on adding my own forms to a site. I had previously set up a netlify form, but wanted to follow the svelteKit way of form handling. The netlify way forced validation on the page, which breaks without javascript enabled and didn’t allow any server side validation of the form.
I found that the easiest way was to build a route with a +page.server.js and +page.svelte with just form mockups that had the name input and all other inputs unstyled without submit buttons.
The +page.server.js has:
export const prerender = true;
The +page.svelte has:
<form method="POST" name="contact-footer" netlify netlify-honeypot="bot-field">
<input type="hidden" name="form-name" value="contact-footer" />
<div class="form__inputs">
<input type="text" name="first-name" />
<input type="text" name="last-name" />
<input type="email" name="email" />
<input type="tel" name="phone" />
<textarea name="message"></textarea>
</div>
</form>
I have three other forms on the page, but they are the same. My goal is to hide them on a route that people won’t stumble across.
Then, I updated the svelte.config.js
prerender: {
crawl: true,
entries: ['some-route-where-you-put-the-forms']
}
After that I built my normal route page and added the form the way I wanted it. I direct the form to my +page.server.js action.
In the +page.server.js action, I have;
export const actions = {
contact: async ({ request, url }) => {
let reply = {};
const formData = await request.formData();
const firstName = formData.get('first-name');
const lastName = formData.get('last-name');
const email = formData.get('email');
const validation = formData.get('work-validation');
let location = formData.get('location');
if (isJson(location)) {
location = JSON.parse(location);
} else {
location = { value: location, label: location };
}
//Validate entries:
...
//Check Validation:
if (Object.entries(reply).some((el) => el[1] == true) > 0)
return fail(409, { ...reply, firstName, lastName, email, location, validation });
let origin = url.origin;
if (url.origin.includes('localhost')) origin = '[site url on netlify]';
try {
const response = await fetch(`${origin}/[route to forms, ie. /form-are-here]`, {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body: new URLSearchParams(formData).toString()
});
const data = await response.text();
if (response.status !== 200)
return fail(response.status, {
postFail: true,
err: `Something went wrong, please try again., Error: ${data}`,
firstName,
lastName,
email,
location,
validation
});
return { success: true };
} catch (err) {
console.log('error: ', err);
return fail(500, { postFail: true, err, firstName, lastName, email, location, validation });
}
}
};
This allows me to handle validation from +page.server.js and use use:enhance with no javascript in my +page.svelte.
<script>
import { enhance } from '$app/forms';
import { page } from '$app/stores';
import Select from 'svelte-select';
import SelectFb from '$lib/reusable/Select.svelte';
export let data;
const { locations } = data;
onMount(() => js = true);
</script>
<section>
...
<form
action="?/apply"
method="POST"
name="employment"
enctype="multipart/form-data"
netlify
netlify-honeypot="bot-field"
use:enhance
>
<input type="hidden" name="form-name" value="employment" />
{#if $page?.form?.firstNameMissing}
<p class="error">First name is required.</p>
{/if}
<input
class="lato-regular"
type="text"
name="first-name"
placeholder="First name"
aria-label="Enter first name."
value={$page?.form?.firstName || null}
/>
{#if $page?.form?.lastNameMissing}
<p class="error">Last name is required.</p>
{/if}
<input
class="lato-regular"
type="text"
name="last-name"
placeholder="Last name"
aria-label="Enter last name."
value={$page?.form?.lastName || null}
/>
...other inputs...
{#if $page?.form?.postFail}
<p class="error">{$page?.form?.err}</p>
{/if}
{#if $page?.form?.success}
<p class="success">Form submitted, we will get back to your shortly.</p>
{/if}
<input class="submit" type="submit" value="Apply Now!" />
</form>
</section>
Sorry this post is so long. I don’t know if anyone will find it helpful, but I wanted to share it after spending the last day working through putting it together. I went through serveral issues with cors, method not authorized, and Netlify not finding the forms before putting it all together. Also, if anyone sees any improvements, let me know.