Dead simple infinite scroll for Svelte 5 - just add to the end of any list
About • Features • Installation • Usage • Examples
A minimal infinite scroll component that you simply add to the end of your list. When it becomes visible, it calls your load function. When that function returns an empty array, it stops. No complex configuration, no managing state - it just works.
pnpm add sly-svelte-infinite-scroll
npm install sly-svelte-infinite-scroll
yarn add sly-svelte-infinite-scroll
<script lang="ts">
import { InfiniteScroll } from 'sly-svelte-infinite-scroll';
let items = $state([]);
async function loadMore() {
const response = await fetch('/api/items?offset=' + items.length);
const newItems = await response.json();
items = [...items, ...newItems];
return newItems; // Return empty array to stop
}
</script>
<div class="list">
{#each items as item}
<div>{item.name}</div>
{/each}
<InfiniteScroll onLoadMore={loadMore} />
</div>
The component leverages modern web APIs and Svelte's latest features for optimal performance:
$state
and $props
docs<script lang="ts">
import { InfiniteScroll } from 'sly-svelte-infinite-scroll';
interface Post {
id: number;
title: string;
body: string;
}
let posts = $state<Post[]>([]);
let page = $state(1);
async function loadMore() {
const res = await fetch(`/api/posts?page=${page}&limit=20`);
const newPosts = await res.json();
posts = [...posts, ...newPosts];
page++;
return newPosts; // Component stops when this is empty
}
</script>
<div class="posts">
{#each posts as post (post.id)}
<article>
<h2>{post.title}</h2>
<p>{post.body}</p>
</article>
{/each}
<InfiniteScroll onLoadMore={loadMore} threshold={300} />
</div>
<script lang="ts">
import { InfiniteScroll } from 'sly-svelte-infinite-scroll';
import LogLine from './LogLine.svelte';
let logs = $state([]);
let cursor = $state('');
async function loadMore() {
// Stop after 2000 items
if (logs.length >= 2000) return [];
const res = await fetch(`/api/logs?cursor=${cursor}`);
const { items, nextCursor } = await res.json();
logs = [...logs, ...items];
cursor = nextCursor;
return items;
}
$effect(() => {
loadMore(); // Load initial data
});
</script>
<div class="log-viewer">
{#each logs as log (log.id)}
<LogLine {log} />
{/each}
<InfiniteScroll onLoadMore={loadMore} threshold={200} />
</div>
Check out the full example app in the repository for a complete implementation with a device console log viewer.