SvelteKit Form Action plus Netlify Form Submission

Hello

I was able to successfully setup my form to receive and see the submissions in the Netlify Form Dashboard. After that, I have implemented a custom SvelteKit Form Action to POST the form data to a database. But now the submissions don’t appear in the Netlify Form Dashboard anymore.

The form is still being detected successfully and is set as active.

I have a custom redirect in the +page.server.js file to a /success page.

Any hints, ideas on where I can start looking is appreciated.

My site is: https://r1--suhrteig.netlify.app

Thank you! :slight_smile:

Any reason why you didn’t use the submission-created function: Forms and Functions?

If SvelteKit is handling the form submissions, Netlify won’t be receiving those.

Thanks for your reply :slight_smile:

It’s the first time I’m trying to implement a form that posts to a database. So I was trying to use the Svelte Form Action to post to the database, and use the built in Netlify form functionality for easy e-mail notifications when a form is submitted. In case if one would fail, I would still see the submission in one place or the other.

So I tried it through a submission-created.js but it’s not posting to the database anymore. Any idea where it’s failing? Submissions arrive in the Netlify Form Dashboard though, so that works again :slight_smile:

const {Client} = require("@notionhq/client")

exports.handler = async function (event) {
	const notion = new Client({ auth: process.env.SECRET_NOTION_TOKEN });
	const formData = JSON.parse(event.body).payload.data;

	const formName = formData.get("form-name");
	const name = formData.get("name");
	const email = formData.get("email");
	const address = formData.get("address");
	const order = formData.get("order");
	const total = formData.get("total");
	const note = formData.get("note") === "" ? "—" : formData.get("note");
	const delivery = formData.get("delivery");
	const confirm = formData.get("confirm");

	const new_row = {
		parent: {
			type: "database_id",
			database_id: process.env.SECRET_DATABASE_ID,
		},
		properties: {
			Name: {
				title: [
					{
						text: {
							content: name,
						},
					},
				],
			},
			Email: {
				email: email,
			},
			Address: {
				rich_text: [
					{
						text: {
							content: address,
						},
					},
				],
			},
			Order: {
				rich_text: [
					{
						text: {
							content: order,
						},
					},
				],
			},
			Total: {
				number: parseFloat(total),
			},
			Note: {
				rich_text: [
					{
						text: {
							content: note.toString(),
						},
					},
				],
			},
			Delivery: {
				select: {
					name: delivery,
				},
			},
			Confirm: {
				checkbox: JSON.parse(confirm),
			},
		},
	};
	await notion.pages.create(new_row);
	return {
		statusCode: 200,
	};
};

Hi @refchef ,

Glad to hear submissions are working on Netlify Form Dashboard! Troubleshooting Svelte Form Action does fall outside of our support scope. We recommend taking a look at Svelte docs or reaching out to their support to troubleshoot their form action Form actions • Docs • SvelteKit

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.