Wedding seating planner with drag-and-drop seating, built on Next.js App Router.
npm install
npm run dev- Next.js 16 (App Router)
- React 19
- Tailwind CSS 4
- Vercel Blob for persistence
- The UI is client-side and uses drag-and-drop for seating changes.
- Changes are saved via
/api/seatingafter a 1s debounce. - The server writes each save to a versioned blob and reads the newest one on load.
- A simple shared password is required to load/save data.
- The password is sent in the
x-app-passwordheader.
type SeatingState = {
tables: { id: string; name: string; capacity: number; guests: string[] }[];
unassigned: string[];
removed: string[];
customGuests: { id: string; firstName: string; lastName: string }[];
};- Bridal guests are defined in
BRIDAL_PARTYand are not draggable. - They are intentionally not part of
ALL_GUESTSto avoid double-seating.
- Each save writes a new blob named
seating-data-<timestamp>.json. - The newest blob by
uploadedAtis read for loading. - Old blobs are pruned after each save (keeps the latest 20).
BLOB_READ_WRITE_TOKEN
APP_PASSWORD
- GitHub:
https://github.com/matthendrix/table-picker - Vercel:
https://table-picker-ashen.vercel.app/
- If saves fail, check that
APP_PASSWORDmatches the password you enter. - If loads fail, check
BLOB_READ_WRITE_TOKENand function logs.