Most restaurant bookings are lost after the decision has already been made. Someone has chosen the place, tapped the reservation button, and then run into a booking step that does not work properly on the phone in their hand. The gap between “I want to eat here” and a confirmed table is usually four or five screens, and every one of them is a place to lose a person who was already sold.
This piece is about closing that gap. Not about which reservation platform to use, which depends on the room, but about the website around it: where the entry point lives, how the widget is embedded, what breaks on a small screen, and what the page says when the answer is that there is no table.
The test throughout is simple. Can a person standing on a pavement, one handed, on a patchy connection, finish a booking without switching to a laptop or giving up and calling?
Where the reservation entry point belongs
The reservation entry point belongs in the same place on every page of the site, visible without scrolling, in a position that never moves. A visitor who decides on the menu page, the gallery, or a blog post should not have to navigate back to the homepage to act on that decision.
In practice that means three things. A persistent button in the header on both mobile and desktop. A second, larger entry point inside the hero area of the homepage, where the decision is most often made. And a third near the foot of long pages, for the person who read the whole way down before making up their mind. That repetition is deliberate, not a design failure. The cost of showing the same button three times is small; the cost of a decided visitor scrolling back up to find it is a booking.
One button, one label, one destination
Use one label across the whole site and do not vary it. “Book a table” and “Reserve” and “Check availability” scattered across different pages read as three different features to someone skimming, and skimming is how phone visitors read. Pick the phrasing that matches the room and use it everywhere, including in the footer and in any banner.
The same applies to the destination. Two competing booking paths on the same page, for example an embedded widget alongside a link to an outbound booking page, split attention and create doubt about which one is the real one. If the restaurant runs both a reservation system and a separate waitlist tool, they still need to feel like one path with two outcomes, not two systems bolted onto the same page.
The walk in only exception
A room that takes no reservations still needs an entry point in the same position, because a visitor is looking for it there. The difference is what the button does. Instead of a booking widget, it should open a short, plain statement of the walk in policy: when the queue typically forms, whether there is bar seating, and whether the restaurant holds any tables back. A room that says “walk ins only, the bar seats twelve and rarely fills before seven” has answered the question. A room that simply omits the reservation button has left the visitor guessing, and guessing sends people back to the search results.
Embed the booking step instead of bouncing to an outbound link
Embed the booking widget in the page wherever the reservation platform supports it. Sending someone to an outbound booking page hands the most fragile part of the journey to a site you do not control, at the exact moment the visitor is most likely to abandon.
The reason is context. On an embedded booking step, the restaurant’s name, photography, address and hours stay on screen while the person picks a party size and a time. On an outbound page, all of that disappears and is replaced by a generic booking interface that looks the same for every restaurant in the city. The person who was booking a specific neighborhood bistro is now looking at a form that could belong to anyone, and any hesitation at that point resolves as a back tap.
There are also practical consequences. An outbound link usually opens a new tab or a new app, which on a phone means the person has left the site entirely. If they abandon, there is no way back except retyping the search. And an outbound jump breaks the measurement of the flow, because the last thing the website knows is that a link was tapped.
When an embed is not available
Some reservation platforms do not offer an embed, or offer one that is too constrained to be usable. In that case the honest approach is to prepare the visitor rather than pretend the jump does not happen. Say plainly, next to the button, that booking is completed on the reservation platform. Keep the restaurant’s essential details, including the phone number, on the page they are leaving so that anyone who backs out lands somewhere useful rather than on a blank screen.
We cover how the embed and the fallback are built and maintained on the reservation website integration page, including what happens when a restaurant changes platforms later.
What a booking widget breaks on a phone
Most mobile booking failures are layout failures inside the host page, not faults in the reservation platform. The widget itself usually works; the frame around it does not. Four problems account for the majority of what goes wrong.
Iframe height
A booking widget embedded in a frame of fixed height is the single most common defect. Most widgets are documented as an iframe embed, and an iframe does not grow to fit its content by default. The result on a phone is an inner scroll region: the visitor scrolls the page, the widget scrolls separately, and the “Confirm” button sits just below the visible edge of the frame where it can be reached only by scrolling inside a box the person did not realise was scrollable.
The fix is to give the frame enough height for the tallest step of the flow at the narrowest supported screen width, or to use the resize messaging the platform provides if it offers one. Test the tallest step specifically. A frame sized for the party size screen will almost always clip the confirmation screen, which is the one that matters most.
Focus traps
A widget that opens inside a modal can trap keyboard focus, or fail to trap it when it should. Both are failures. If focus escapes the open widget, someone navigating by keyboard or switch control can tab into the page behind and lose their place entirely. If focus is trapped with no way out, they cannot close the widget without reloading the page.
The host page is responsible for the modal that contains the widget, even when the widget’s internals are not yours. The close control must be reachable, the escape key must close the modal, and focus must return to the button that opened it.
Tap targets that are too small
Time slots are typically rendered as a dense grid of small buttons, which is exactly the pattern most likely to produce mis taps. WCAG 2.2 sets a minimum target size of 24 by 24 CSS pixels as a floor, with spacing counted where targets are smaller. Treat that as a floor rather than a goal. A time slot grid that fits a thumb comfortably is worth more than one that fits four more slots per row.
Where the widget’s own styling cannot be changed, the host page can often still control the width it renders at, which changes how many slots pack into a row. A narrower container with fewer, larger slots per row usually performs better than a full width grid of tiny ones.
Date pickers
Native date inputs on a phone open the operating system’s own picker, which is familiar and reliable. Custom date pickers written in JavaScript are where problems appear: calendars that open off the top of the screen, month navigation arrows too small to hit, and no way to type a date directly for someone who knows exactly when they want to come.
For a restaurant the date range is usually short, often the next two to four weeks. A row of upcoming dates presented as a horizontal strip, with a full calendar available behind a secondary control, removes the picker from the common path altogether. Most bookings are for tonight, tomorrow or the weekend.
Party size and time selection
Party size should come first and default to the most common size for the room, and the time step should show real availability rather than a list of times that may fail on submission.
Party size first is the right order because it filters everything after it. A visitor who picks a time and then discovers that no table exists for six people has been walked down a path that was never going to work. Defaulting the control matters too: a party size selector that starts empty asks the visitor to make a choice before they have understood the question, while one defaulted to two for a bistro or four for a family room is correct most of the time and needs only a tap to change.
For the time step, the useful patterns are:
- Show available times as tappable options, not as a dropdown list the visitor must open to discover is mostly empty.
- Group times by service where the room has distinct services, so an early sitting and a late sitting read as different experiences rather than a continuous list.
- Mark times that are close to a kitchen close or a last seating, so nobody books a nine forty five table expecting a full menu.
- Keep the current selection visible while the person browses alternatives, so changing their mind never means starting again.
Responsiveness matters here more than anywhere else in the flow. Each tap on a time slot triggers a query against availability, and a slow response reads as a broken button, which produces repeat taps and duplicate submissions. Interaction to Next Paint is the metric that describes exactly this, how quickly the page responds visibly after an interaction, and a booking grid is the part of a restaurant website where it is felt most sharply.
When the answer is “fully booked”
A fully booked state is a design state, not an error message. The visitor has already decided to eat at this restaurant; the only question is what they are offered instead of the table they wanted.
The waitlist
A waitlist works when it asks for the minimum and sets a clear expectation. Name, phone number, party size and the window the person is willing to accept. Then one plain sentence about what happens next: whether they will be contacted if a table opens, roughly how often that happens for that night of the week, and by what time they will know either way. A waitlist that collects a phone number and says nothing about the follow up feels like a form sent into a void.
Keep the waitlist in the same view as the failed search rather than on a separate page. The moment someone learns there is no table is the moment they are most willing to join a list, and any navigation step between the two loses people.
Alternative times and dates
Offer the nearest alternatives automatically rather than making the visitor search for them. Three kinds of alternative cover almost every case:
| Alternative offered | Works well for | What the page should say |
|---|---|---|
| Earlier or later the same night | Flexible parties, couples | The two or three closest available times, with the gap stated plainly |
| Same time, nearby date | Occasion bookings, groups | The next two dates with that exact time free |
| Bar or counter seating | Walk in friendly rooms, solo diners | Whether it is bookable, first come, or held back for walk ins |
| Another room in the group | Multi location brands | The nearest sibling location with availability at that time |
The last row applies only to a group, and only where the rooms are close enough that the swap is realistic. Offering a location forty minutes away is not an alternative, it is noise.
Walk ins and bar seating
State the walk in policy on the same screen, in plain language, even when reservations are the primary path. Many rooms hold back bar seats or a section of counter for walk ins, and that fact is invisible to a visitor who has just been told there are no tables. One sentence covers it: whether walk ins are taken, where they sit, and when the queue usually forms. For bars and late night rooms this is often the main path rather than the exception, which is why our bar and nightlife website design work treats the walk in message as a first class element rather than a footnote under the booking button.
Large parties and private dining need a different door
Route large parties out of the standard booking widget before they hit an error. Nearly every reservation platform caps the party size it will accept online, because past a certain number of covers the kitchen, the seating plan and often a deposit all need a person involved.
The failure mode is familiar. Someone planning a birthday for twelve selects the largest party size the widget offers, finds nothing available, and concludes the restaurant cannot host them. In reality the restaurant would happily take the booking with a phone call and a set menu.
The fix is three small pieces of copy and one form. State the online booking cap next to the party size control, in the widget’s own terms. Above that cap, show an inquiry path instead of a failed search. And make the inquiry form short: date, approximate party size, occasion, contact details, and a free text box. Everything else, including menu choices and deposits, is a conversation.
Private dining deserves its own page rather than living as a paragraph on the contact page, because it is a different decision with different questions: room capacity, minimum spend, whether the space is private or semi private, and what the menu looks like for a group. Our group dining and private parties page covers how that page is structured and what the inquiry hand off needs to carry. Wine and cocktail rooms have a related version of the same problem, where a large standing party is a different product from a seated booking, which is why the wine and cocktail bars page treats them separately.
Confirmations, reminders and what happens when things break
The booking is not finished when the table is held, and the flow is not reliable until you have planned for the reservation platform being unavailable. Both of those live after the tap, and both are usually configured somewhere other than the website while still being promised by it.
Confirmation and reminder expectations
Confirmation should arrive immediately and state everything the guest needs to show up correctly. The booking flow is not finished when the table is held; it is finished when the guest knows where to be, at what time, with how many people, and what happens if plans change.
A confirmation that works contains the restaurant name and address, the date and time in a format that reads unambiguously, the party size, the cancellation window, and a way to change or cancel without a phone call. If a deposit or card hold applies, it is stated here in plain terms and not only in a linked policy.
The reminder is a separate message with a separate job. Sent the day before or the morning of, it should make cancelling easy rather than hard. A restaurant that makes cancelling difficult does not keep the booking; it gains a no show, which is worse, because a cancelled table can be refilled and an empty one cannot.
Most of this is configured in the reservation platform rather than on the website, but the website sets the expectation. If the site says a confirmation arrives by text and the platform sends email only, the guest spends the afternoon wondering whether the booking exists. The two need to describe the same thing, and that check belongs in the same routine as the hours and menu checks described in our local search to seated table playbook.
What to do when the reservation platform is down
Plan for the outage before it happens, because the website will still be up when the booking widget is not. An embedded widget that fails to load leaves a blank rectangle where the most important control on the site should be, and a visitor reads a blank rectangle as a broken restaurant.
Three measures cover almost every outage:
- A visible fallback in the container. The element that hosts the widget should contain readable content before the widget loads, so that if the widget never arrives the visitor sees the phone number, the email address and the hours instead of empty space.
- A phone number that is always present. Even on a site where booking is entirely online, the number belongs in the header or footer. During an outage it is the only path left.
- A way to post a notice quickly. A short banner saying that online booking is temporarily unavailable and asking people to call converts an invisible failure into a manageable one. This needs to be something the restaurant can publish in a minute, not a support ticket.
The same fallback content covers a slower and more common case: a visitor on a connection poor enough that the third party widget never finishes loading, while the rest of the page has rendered fine.
Accessibility of the flow
An accessible booking flow and a booking flow that converts on a phone are largely the same build. Clear labels, a sensible focus order and useful error messages help a screen reader user and a distracted person on a train in exactly the same way.
Labels that stay visible
Every control in the flow needs a real label, associated with its input. Placeholder text is not a label, because it disappears the moment the person types. MDN’s guidance on the label element covers the mechanics, and WCAG 2.2’s Labels or Instructions criterion covers why it matters: a person needs to know what is being asked of them at the moment they are answering, not before they started typing.
This matters particularly for the phone number field, where format expectations vary, and for any field marked required. Say what is required and why, next to the field, rather than revealing it only after a failed submission.
Keyboard and focus order
The whole flow must be completable without a mouse or a touch screen. Tab order should follow the visual order of the page, the currently focused element must be visibly outlined, and opening the booking modal should move focus into it while closing it returns focus to the control that opened it.
Time slot grids deserve particular attention, because a grid of forty buttons is a long tab sequence. Grouping slots by service, as described earlier, shortens that sequence for everyone.
Error messages that say what to do
An error message needs to identify which field is wrong and what would make it right. WCAG 2.2’s Error Identification criterion describes exactly this: the item in error is identified and the error is described to the user in text. “Invalid input” fails that test. “Enter a phone number so we can text you if the table changes” passes it and also explains why the field exists.
Errors should also appear next to the field rather than only at the top of the form, because on a phone the top of the form is often off screen by the time the person submits.
Measuring the flow honestly
Measure the steps you control, name the steps you do not, and reconcile the two against the covers the reservation platform actually reports. A single headline conversion number for a booking flow that spans two systems is almost always misleading.
The steps a website can observe cleanly are: how many people reached a page with a reservation entry point, how many tapped it, how many loaded the booking widget, and where the journey left your domain. Everything after that belongs to the reservation platform, which reports on its own terms and its own definitions.
The useful comparison is therefore not a funnel percentage but a set of relationships watched over time:
- Entry point taps compared with sessions, which tells you whether the button is in the right place.
- Widget loads compared with entry point taps, which tells you whether the embed is loading reliably on real devices.
- Platform reported covers compared with widget loads, which tells you whether the flow itself finishes.
Watch these month over month rather than day to day, and read them alongside what the floor staff report. A restaurant that suddenly hears more phone bookings than usual is often describing a broken widget before any dashboard shows it. Be equally careful about attributing a change to a website edit when the weather, a holiday or a local event moved covers that week.
One bistro, or a group with several rooms
A single room needs one booking path; a group needs a location decision before the booking path begins, and getting that order wrong is the most common structural mistake in group restaurant sites.
For a single location bistro, the flow is linear. Entry point, party size, date, time, details, confirmation. There is no ambiguity about which room the person is booking, so the page should never ask. The work is all in the quality of each step, which is where the restaurant website design build focuses.
For a group, a location step has to come first, and it should be answered by the page the visitor is already on rather than by a dropdown. Someone reading a specific location’s page has already chosen that room, and the booking entry point on that page should carry the location with it. A location selector belongs only on the homepage or a locations index, where the choice genuinely has not been made yet.
Groups have two further complications worth naming. Rooms within the same brand often run on different reservation systems, particularly after an acquisition, and the site needs to handle that without the visitor ever learning about it. And cross location alternatives, as described earlier, need distance stated honestly rather than presented as an equivalent option. How that is structured across several rooms is covered on the multi-location restaurant website page.
Where to start
Start by completing a booking on your own site, on your own phone, on mobile data rather than the restaurant’s wifi, for a party of six on a Saturday. Note every point where you hesitate, scroll inside a box, mis tap a time slot, or cannot tell whether something worked. That list, in order, is the work.
Then do the same test on a night that is genuinely full, because the fully booked path is the one nobody rehearses and the one that decides whether a decided visitor ends up at your table or someone else’s.
If you would rather have someone walk that path with you and show what the fixes look like on your own screen, book a demo and we will go through the flow together.
Sources
Frequently asked questions
Should the booking widget be embedded in the page or linked out to the reservation platform?
Embed it in the page whenever the platform supports an embed. Sending someone to an outbound booking page hands the finish of the booking to a site you do not control, on a phone, at the exact moment they are most likely to abandon. An embedded widget keeps the restaurant's name, room and hours visible while the person picks a time, which is the context that makes them finish.
What is the most common reason a mobile booking is abandoned partway through?
A step that does not fit the screen. The usual culprits are an embedded widget in a fixed-height frame that forces an inner scroll, a date picker that opens off screen, and tap targets too small to hit reliably one-handed. Each of these is fixable in the page that hosts the widget, even when the widget itself belongs to the reservation platform.
What should a restaurant website show when every table is booked?
Show the nearest alternatives rather than a dead end. A waitlist sign up, the next two or three available times, the same time on nearby dates, and a plain statement about bar seating or walk in policy all give a decided visitor somewhere to go. A page that says only that no tables are available sends that person back to the search results.
How should a website handle large party and private dining requests?
Route them out of the standard booking widget and into a short inquiry form. Most reservation platforms cap online bookings at a party size the kitchen can absorb without warning, and anything above that needs a person to confirm a room, a menu and a deposit. The website's job is to state the cap plainly and make the hand off obvious rather than letting someone hit an error.
How do you measure a booking flow honestly?
Measure the steps you actually control and name the ones you do not. Count entry point taps, widget loads, and the point where the visitor leaves your page for the platform, then reconcile against the covers the reservation platform reports. Avoid treating a single number as the conversion rate for the flow when part of the path happens on a system that reports separately.