Sveltekit shallow routing with form
How to use sveltekits shallow routing with forms
Work in progress! Basic example should work
Main page
src/routes/+page.svelte
<script>
import { preloadData, pushState, goto, replaceState } from '$app/navigation';
import { page } from '$app/stores';
import Form from './form/+page.svelte';
</script>
<a
href="/form"
on:click={async (e) => {
// bail if opening a new tab, or we're on too small a screen
if (e.metaKey || innerWidth < 640) return;
// prevent navigation
e.preventDefault();
const { href } = e.currentTarget;
// run `load` functions (or rather, get the result of the `load` functions
// that are already running because of `data-sveltekit-preload-data`)
const result = await preloadData(href);
if (result.type === 'loaded' && result.status === 200) {
pushState(href, { selected: result.data });
} else {
// something bad happened! try navigating
goto(href);
}
}}
>
Go to form
</a>
{#if $page.state.selected}
<button on:click={() => history.back()}>Close</button>
<Form data={$page.state.selected} shallow={true} />
{/if}
Form route
export let shallow
lets the page know its "embedded"
action="/form
lets the main page know where to submit the form
src/routes/form/+page.svelte
<script>
import { enhance } from '$app/forms';
import { goto, preloadData, replaceState } from '$app/navigation';
export let data;
export let shallow = false;
</script>
<p>Hello {data.name}</p>
<form
method="POST"
action="/form"
use:enhance={() => {
return async ({ update }) => {
await update();
if (shallow) {
const result = await preloadData('/form');
if (result.type === 'loaded' && result.status === 200) {
replaceState('/form', { selected: result.data });
} else {
goto('/form');
}
}
};
}}
>
<input type="text" name="name" />
<button>Submit</button>
</form>