# Frontend Vite List Pages

> Vite admin list pages: URL-synced filters, debounced search, tables, pagination, bulk select, AlertDialog delete, deep-link modals. Use when building admin table list views or data grids.

- Skill: `xmuhameed/frontend-vite-list-pages` (Agent Skill)
- Install (CLI): `npx skillmds@latest add xmuhameed/frontend-vite-list-pages`
- Raw SKILL.md: https://api.skillmd.com/api/skills/xmuhameed/frontend-vite-list-pages/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Web & Frontend
- Author: xmuhameed (https://skillmd.com/u/xmuhameed)
- Updated: 2026-09-21
- Page: https://skillmd.com/skills/xmuhameed/frontend-vite-list-pages

---


# List Pages

## Standard Layout

```
PageTitle → Card (toolbar) → Table → Pagination
```

## URL-Synced Filters

```typescript
const [searchParams, setSearchParams] = useSearchParams();

const filters = useMemo(() => ({
  search: searchParams.get('search') ?? '',
  page: Number(searchParams.get('page') ?? 1),
  pageItemsCount: Number(searchParams.get('pageItemsCount') ?? 10),
  status: searchParams.get('status') ?? undefined,
}), [searchParams]);

const updateFilters = (patch: Partial<Filters>) => {
  const next = new URLSearchParams(searchParams);
  Object.entries(patch).forEach(([k, v]) => {
    if (v) next.set(k, String(v)); else next.delete(k);
  });
  if (!patch.page) next.set('page', '1'); // reset page on filter change
  setSearchParams(next);
};
```

Shareable/bookmarkable admin URLs.

## Debounced Search

```typescript
const [searchInput, setSearchInput] = useState(filters.search);
const debouncedSearch = useDebounce(searchInput, 500);
useEffect(() => { updateFilters({ search: debouncedSearch }); }, [debouncedSearch]);
```

## Table + Delete

```typescript
const [deleteId, setDeleteId] = useState<string | null>(null);
<AlertDialog open={!!deleteId} onOpenChange={() => setDeleteId(null)}>
  <AlertDialogAction onClick={() => deleteMutation.mutate(deleteId!)}>Delete</AlertDialogAction>
</AlertDialog>
```

## Bulk Select

Checkbox column + shift-click range select (products page pattern).

## Images in Table

`` <img src={`${API_URL}${row.imageUrl}`} /> ``

## Deep-Link Modal

```typescript
// ?orderId= opens OrderDetailsModal — useOrderDetailsDeepLink hook
```

## Drag-and-Drop Sort

@dnd-kit on list pages — `arrayMove` → optimistic UI → sort API → revert on error.

## Loading/Empty

Spinner while `isLoading`. Empty state message in Table body.

