Repository navigation
Seating and the Export
Who sits where, who is being fed, and the sheet you hand the caterer.
The seating chart lives at Admin → Seating. It is one plan shown two ways, and it ends in an Export that prints as paper or downloads as a spreadsheet.
Switch between them in the page header.
- Canvas — draw the room, drop tables into it, drag people from the guest panel into chairs. Tables can be round, rectangular or a sweetheart table. A party is coloured so you can see when one invitation has been split across two tables. The guest panel is a Guests / Hide guests toggle: a column from tablet width up, a drawer below it.
-
List — the same plan as a roster, grouped by table (rows are people,
with a Not seated block on top) or by guest (rows are whole parties).
Click, ⌘/Ctrl-click and Shift-click to multi-select, then use the bulk bar to
move people to a table, unseat them, swap two people, gather a split party or
auto-seat everyone into free chairs. Double-click a seat to rename it, which is
how
Anna's guest 1becomes a person.
Below 768px the page opens on the List view, because a pan-and-zoom canvas on a 400px screen is no way to seat anybody. On a phone the workflow is select, then the bulk bar — touch has no drag-and-drop.
A party takes one chair per person, minus anyone who answered not attending.
| Where they come from | Takes a chair | Counted as invited | |
|---|---|---|---|
| Guests | The guest list | Yes | Yes |
| The couple | The guest list, marked as the couple | Yes | No |
| Vendors | The Vendors tab | No | No |
The two of you need to be on the guest list so the chart can give you chairs and the kitchen can count your plates — but you were not invited to your own wedding, so you are not counted as guests.
- Go to Admin → RSVPs & Guests → Guest List.
- While you are not on the list, a banner offers Add the couple. Click it.
- One row is created, holding both of you, with the names taken from Settings → Bride / Groom.
- Click Edit on that row to change anything — including the names, which is how settings saying "Heaven" becomes a place card saying "Heaven Lucas" — and to set each of your dietary restrictions, exactly as for any guest.
The row is pinned to the top of the guest list with a 💍 badge. It is left out of Total Invited, missing RSVPs and the other statistics, out of the mailing export (nobody posts themselves an invitation), and its dietary answers do not appear as a reply on the RSVPs tab.
Both of you then show up in the seating panel as separate people to drag.
The photographer, the DJ, the planner. They are at the wedding working, they are often being fed, and none of it is an invitation — so they are kept entirely apart from the guest list.
- Go to Admin → RSVPs & Guests → Vendors.
- + Add vendor, then fill in name, role, company, email, phone.
- Leave Needs a meal ticked if their contract includes a plate. Untick it and they stay on the sheet but stop counting toward the vendor plates.
- Set their food preference with the same pills the guest cards use. Nothing selected means the standard plate — the chicken.
- Notes is for arrival time, where they set up, anything the planner needs.
One row is one person. A DJ who brings an assistant is two rows sharing a company, because one row with a headcount of two cannot say which of them is the one who eats no gluten.
Vendors never appear on the floor plan and never take a chair.
Export in the seating page header. Options on the left, a live preview of the actual sheet on the right — the preview is the same component the printer gets, laid out at the real printable width of A4, so what you approve is what comes out.
What to include
- By table — seating order, a block per table
- Alphabetical list — every guest A–Z by surname, for finding a name at the door
- Both — the two as two sections
Level of detail
- Every name — the full roster
- Counts only — headings and numbers, no names. The sheet you pin up in the kitchen
- Names + counts — both
Also show
| Option | What it adds |
|---|---|
| Kitchen summary | Whole-wedding totals on page one |
| Household | Which invitation each person came in on |
| Side | Bride's or groom's |
| Empty seats | How many chairs at each table are still free |
| Not seated yet | Attending people holding no chair |
| Vendors | The vendor block, and the vendor half of the plate count |
| New page per table | One table per sheet, for a place-card table |
| Entrée choice | Disabled — the RSVP form has never asked for one |
Format — Print / PDF (opens the printer dialog; choose "Save as PDF" there) or Spreadsheet (.csv).
-
For the kitchen — two rows of tiles with the same nine columns, so a number reads straight down. Guests: plates, then one tile per answer (the five restrictions, Kids meal, Not eating), then Chicken. Vendors: the same columns again — their Not eating is counted from the Needs a meal checkbox rather than from a dietary answer. Underneath, the grand total — "114 plates in total — 110 guests and 4 vendors (not eating: 1 guest, 1 vendor)". Guests and vendors are counted apart because a vendor meal is usually its own line on its own contract, and often a cheaper plate.
The first tile is plates, not chairs. They are the same number until somebody is marked not eating, and then they are not — a caterer handed the headcount would cook one too many. The chairs are on each table's own heading.
-
The legend — what each restriction code means.
-
A block per table — name, type, occupancy, the counts line, and the roster if names are on. Restriction codes in the counts line are drawn as the same bordered, coloured chips the legend defines, so a green boxed
VGNunder a table and a green boxedVGNin the legend are visibly the same mark. -
Not seated yet — if asked for.
-
Vendors — if asked for. In Every name and Names + counts it is a full roster: role, name, company, whether they are eating, restrictions. In Counts only it collapses to the tally plus the one thing a count cannot carry — who is not getting a plate.
Five of them are restrictions — things that change what is on a plate: Vegetarian, Vegan, Gluten free, Nut allergy, Other (with a free-text note).
Two of them decide the plate itself:
- Kids meal — a child's plate instead of the adult one. Still a plate, so it still counts toward the total; it is simply not the chicken. It can sit alongside a restriction, because a child can be gluten free too.
- Not eating — a chair with no plate against it. The baby whose food comes with their mother. They are still seated, still on the roster, still counted in "seated of" on their table — they are just not a meal. Ticking it clears the other answers and greys them out, in both the RSVP form and the admin card: restrictions on a plate that is not being served say nothing, and "not eating, vegetarian" leaves the kitchen to guess which half was meant.
A plate carrying no answer at all prints as Chicken, because the standard plate is the chicken. This is the whole of what can honestly be said: the RSVP form has never asked for an entrée, so the sheet cannot tell you how many want the fish. Someone who would have chosen the fish is currently indistinguishable from someone who wanted the chicken.
A kids' meal and a not eating are not counted as chicken — both are answers, so neither falls into the no-answer bucket.
Counts only is meant to be one sheet, so it is fitted to one page.
The layout does most of the work — three columns once there are more than eight tables, and no vendor roster. A thirteen-table wedding comes to 997px against the 1032px A4 gives you inside its 12mm margins, and prints at full size.
Past that the sheet is measured and shrunk by exactly the amount it is over: 31 tables print on one page at 61%. It will not shrink below 60%, because a sheet nobody can read across a kitchen has not fitted on one page in any sense worth having — so 51 tables reports "2 pages — too much for one, even shrunk" rather than producing something illegible.
The dialog header says which it is before you reach the printer: "13 tables · 131 people · fits one page", or fits one page, shrunk to 61%, or the page count.
Fitting is skipped when New page per table is on, which is a request for many pages.
One row per person — never one per party, because a caterer counting plates
counts rows. Each restriction is its own yes/blank column so a pivot table
totals them without anyone parsing anything.
Columns: Table, Seat, Name, (Household), (Side), (Role, Meal), RSVP, the
seven answers (five restrictions, Kids meal, Not eating), Note. Role and Meal appear only when Vendors is on — a
vendor's role is not a household, and "is this one eating" is a question no guest
column asks. A guest row is Meal = yes unless they are marked not eating, so
totalling that column counts every plate in the file. Note that this is the printed grand total plus anyone
not seated yet: the sheet counts chairs, the spreadsheet counts people.
The file is named seating-chart-YYYY-MM-DD.csv, so a folder of them sorts by
date.
Dietary answers live on the RSVP (rsvps.dietary_restrictions), one entry per
attending person, matched to a seat by name. Each entry is a set of booleans
— vegetarian, vegan, gluten_free, nut_allergy, other (+ other_text),
kids_meal, no_meal. That is the only thread tying a
chair to a restriction, which is why renaming someone in the guest list carries
the rename to both their chair and their dietary answer.
A vendor's answer is on the vendor's own row instead, in the same shape, so the same counting code handles both.
- No entrée count. See "Chicken", not "no restrictions" above. Adding a meal question to the RSVP form means re-asking the households who have already answered.
- It prints rosters, not the room. There is no drawing of the floor plan on the export — tables as they actually sit, for a planner's walk-through. The canvas is a React Flow surface whose DOM does not print, so that would be a separate renderer drawn from the table coordinates.
Both are tracked in docs/parkinglot.md in the repository.
Setting it up
Using the admin panel
- Guests and RSVPs
- Seating and the Export
- Registry
- Finances
- Honeymoon Portal
- Content and Settings
- Offline
How it works