Skip to content

Commit 5c6e6ae

Browse files
committed
more involved example - show importing a +page.svelte and correctly handling a click event, and avoid
1 parent 3a2ff3b commit 5c6e6ae

File tree

1 file changed

+45
-24
lines changed

1 file changed

+45
-24
lines changed

documentation/docs/30-advanced/67-shallow-routing.md

Lines changed: 45 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -37,36 +37,57 @@ The second argument is the new page state, which can be accessed via the [page s
3737

3838
To set page state without creating a new history entry, use `replaceState` instead of `pushState`.
3939

40-
## Loading data from a route
40+
## Loading data for a route
4141

42-
When doing a shallow navigation you might want to show a reduced version of a page in a modal, for which you need the data of that page. You can retrieve it by calling `preloadData` with the desired page URL and use its result to populate the component. This will call the load function(s) associated with that route and give you back the result.
42+
When shallow routing, you may want to render another `+page.svelte` inside the current page. For example, clicking on a photo thumbnail could pop up the detail view without navigating to the photo page.
43+
44+
For this to work, you need to load the data that the `+page.svelte` expects. A convenient way to do this is to use [`preloadData`](/docs/modules#$app-navigation-preloaddata) inside the `click` handler of an `<a>` element. If the element (or a parent) uses [`data-sveltekit-preload-data`](/docs/link-options#data-sveltekit-preload-data), the data will have already been requested, and `preloadData` will reuse that request.
4345

4446
```svelte
45-
<!--- file: Model.svelte --->
47+
<!--- file: src/routes/photos/+page.svelte --->
4648
<script>
47-
import { preloadData, goto } from '$app/navigation';
48-
49-
export let close;
50-
51-
const data = preloadData('/path/to/page/this/modal/represents').then(result => {
52-
if (result.type === 'loaded' && result.status === 200) {
53-
return result.data;
54-
} else {
55-
// Something went wrong, navigate to page directly
56-
goto('/path/to/page/this/modal/represents');
57-
}
58-
});
49+
import { preloadData, pushState, goto } from '$app/navigation';
50+
import Modal from './Modal.svelte';
51+
import PhotoPage from './[id]/+page.svelte';
52+
53+
export let data;
5954
</script>
6055
61-
<dialog open>
62-
{#await data}
63-
<!-- add your loading UI here -->
64-
{:then }
65-
<h1>{data.title}</h1>
66-
<p>{data.content}</p>
67-
{/await}
68-
<button on:click={close}>Close</button>
69-
</dialog>
56+
{#each data.thumbnails as thumbnail}
57+
<a
58+
href="/photos/{thumbnail.id}"
59+
on:click={async (e) => {
60+
// bail if opening a new tab, or we're on too small a screen
61+
if (e.metaKey || innerWidth < 640) return;
62+
63+
// prevent navigation
64+
e.preventDefault();
65+
66+
const { href } = e.currentTarget;
67+
68+
// run `load` functions (or rather, get the result of the `load` functions
69+
// that are already running because of `data-sveltekit-preload-data`)
70+
const result = await preloadData(href);
71+
72+
if (result.type === 'loaded' && result.status === 200) {
73+
pushState(href, { selected: result.data });
74+
} else {
75+
// something bad happened! try navigating
76+
goto(href);
77+
}
78+
}}
79+
>
80+
<img alt={thumbnail.alt} src={thumbnail.src} />
81+
</a>
82+
{/each}
83+
84+
{#if $page.state.selected}
85+
<Modal on:close={() => history.goBack()}>
86+
<!-- pass page data to the +page.svelte component,
87+
just like SvelteKit would on navigation -->
88+
<PhotoPage data={$page.state.selected} />
89+
</Modal>
90+
{/if}
7091
```
7192

7293
## Caveats

0 commit comments

Comments
 (0)