Pagination with scroll to
This example shows a paginated list that scrolls back to the top whenever the page changes, improving the user experience.
To archieve this we leverage Crelte's data attributes and an event.
App.svelte:
svelte
<script module>
// this should be in a plugin or in the app.init function
export function init(crelte) {
// todo onRequest we could also already disable the scroll
// so the attribute data-disable-scroll does not need to be added
// after render gets excuted once the new dom was rendered
crelte.events.on('afterRender', (cr, route) => {
// all data-* are stored inside the context
const scrollTo = route.getContext('scrollTo');
if (scrollTo) {
const el = document.querySelector(scrollTo);
el?.scrollIntoView({ behavior: 'smooth' });
}
});
}
</script>PaginatedList.svelte:
svelte
<script module>
/** @type {import('crelte').LoadData} */
export const loadData = ({ req }) => {
const page = parseInt(req.getSearchParam('page')) || 0;
// this could of course also be a query
const content = Array(10).fill(0).map((_, i) => `Item ${page * 10 + i}`);
return { page, content };
};
</script>
<script>
import { getRoute } from 'crelte';
let { page, content } = $props();
function paginatedUrl(route, page) {
route.setSearchParam('page', page > 0 ? page : null);
return route.url;
}
</script>
<div id="list">
{#each content as item}
<div class="item">{item}</div>
{/each}
</div>
<div class="navigation">
{#if page > 0}
<a
href={paginatedUrl($route, page - 1)}
data-disable-scroll
data-scroll-to="#list"
>Previous page</a>
{/if}
<a
href={paginatedUrl($route, page + 1)}
data-disable-scroll
data-scroll-to="#list"
>Next page</a>
</div>
<style lang="scss">
.item {
min-height: 20vh;
}
</style>