Skip to content

Page Params with URL State ​

Problem ​

You need bookmarkable search and page state without coupling Sourcerer to one router or URL codec.

Solution ​

Validate URL values, set params, and navigate with direct page commands.

ts
import { createPageSource } from '@vielzeug/sourcerer';

type Item = { id: number; name: string };
const items: Item[] = [{ id: 1, name: 'Ada' }, { id: 2, name: 'Grace' }];
const source = createPageSource({
  load: async ({ page, pageSize, params: search }) => {
    const matching = items.filter((item) => item.name.toLowerCase().includes(search.toLowerCase()));
    const start = (page - 1) * pageSize;
    return { items: matching.slice(start, start + pageSize), totalItems: matching.length };
  },
  params: '',
});

const url = new URL('https://example.test/users?page=1&search=ada');
const parsedPage = Number.parseInt(url.searchParams.get('page') ?? '1', 10);
const page = Number.isInteger(parsedPage) && parsedPage > 0 ? parsedPage : 1;
await source.setParams(url.searchParams.get('search') ?? '');
await source.goTo(page);

history.replaceState(null, '', `?page=${source.state.pagination.page}&search=${encodeURIComponent(source.state.params)}`);
source.dispose();

Pitfalls ​

  • Validate page numbers before calling goTo().
  • Serialize committed state.params, not state.pendingParams.
  • Keep route decoding at the application boundary.