Skip to content
WingoUI
ComponentsTemplatesDocsPricingAI agentsBlogChangelogContact
Components
Buttons & Actions
ButtonButton GroupCopy ButtonDelete ButtonTheme ToggleToggleToggle Group
Inputs
Avatar UploadCalendarCheckboxColor PickerComboboxCountry SelectCron PickerCurrency InputDate PickerDate Range PickerDate Time PickerDuration PickerEmail InputEmoji PickerFile UploadFilter BuilderInputInput GroupListboxMasked InputMention InputMonth PickerMulti SelectNumber InputOTP InputPassword InputPhone InputRadio GroupRatingSearch InputSegmented ControlSelectSignature PadSliderSwitchTag InputTextareaTime PickerTimezone SelectTree Select
Forms
Address InputBooking WidgetCSV ImportFieldForm WizardInline EditInvoice line itemsRich Text EditorSchema Builder
Navigation
Back To TopBounce SidebarBreadcrumbCommand MenuGlobal SearchGooey NavHook SidebarNav MenuNav TabsPaginationProximity SidebarScroll ProgressSidebarStepsTable Of ContentsTabsTopbarUser MenuWorkspace Switcher
Overlays
Alert DialogContext MenuDialogDrawerDropdown MenuFamily DrawerHover CardPopoverShare DialogSheetShortcuts DialogTooltipTour
Feedback
AlertBannerCookie ConsentEmoji ReactionEmpty StateNotification BellNotification CenterProgressRoute ProgressSetup ChecklistSkeletonSpinnerToast
Data Display
Approval FlowAvatarBadgeCalendar ViewCode BlockComment ThreadContact cardCountdownDescription ListDiff ViewerFile ListFile managerFolderGanttJSON ViewerKbdLog ViewerMarkdownPresenceSchedulerTagTimelineTree View
Tables & Lists
Audit LogData TableDeal PipelineEditable GridKanbanListMembers tablePermissions MatrixTableTask ListVirtual List
Charts & Stats
Animated CounterArea chartBar chartDonut chartFunnel chartGaugeGitHub ActivityHeatmap calendarLeaderboardLine chartRadar chartRadial barSparklineStat CardTrackerTrend badge
Layout
AccordionApp ShellCardCollapsibleDetail LayoutEntity HeaderPage HeaderScroll AreaSeparatorSettings LayoutSplit ViewToolbar
Media
Audio PlayerCarouselCSV ViewerDOCX EditorDOCX ViewerExcel ViewerFile SystemImage compareImage CropperImage GalleryImage LightboxLocation MapPDF ViewerPowerPoint ViewerQR CodeStep PlayerVideo Player
AI Kit
Agent Status CardChat MessageChat ThreadChat WidgetConversation ListFluid OrbGrid RevealMatrix OrbModel PickerPrompt InputReasoning IndicatorRule BuilderSuggestion ChipsTool Call TimelineUsage MeterVoice InputWorkflow Canvas
Text & Effects
Background PatternGravity LettersMarqueeTerminalText AnimateText Rotate
Mobile
Action SheetBottom Tab BarFABHaptic ButtonHero HeaderInstall PromptLarge Title HeaderNotification BannerOnboarding CarouselPicker WheelPull To RefreshSlide To ConfirmSticky CTA BarSwipe DeckSwipeable Tabs
Commerce
Cart drawerCategory pickerCheckout stepsCoupon inputFavorite buttonFilter panelListing cardListing gridOrder trackerPricePrice rangePricing tableProduct galleryQuantity stepperReviewsSeller card
Marketing Sections
App Download SectionBlog Cards SectionCTA SectionFAQ SectionFeature GridFeature ShowcaseHero SectionIntegrations SectionLogo CloudMarketing FooterMarketing HeaderMarketing SectionNewsletter SectionPricing SectionStats SectionSteps SectionTeam SectionTestimonials SectionTimeline SectionVideo Section
Blocks
Admin Dashboard PageAdmin ShellAI Chat PageAPI Keys PageAutomation Builder PageCheckout PageCRM Contact PageCRM Pipeline PageError PagesInbox PageInvoice PageKPI DashboardListing Detail PageLogin PageMarketplace Home PageMarketplace Search PageMarketplace ShellMobile App HomeOnboarding FlowOrder History PagePost Listing WizardPricing PageProfile PageRegister PageSettings PageUsers Admin Page
Templates
About PageAcademy PageAccessibility PageAffiliate PageAgency PageAI Product PageAppointment Booking PageBlog PageBlog Post PageBug Bounty PageCareers PageChangelog PageCommunity PageCompare PageContact PageCustomer Story PageCustomers PageDemo Booking PageDevelopers PageDocs Home PageDownload PageEnterprise PageEvents PageExperts PageFAQ PageFeature PageGlossary PageHelp Article PageHelp Center PageHome Services PageImpact PageIntegration Detail PageIntegrations PageJob Detail PageLanding PageLaunch PageLegal PageManifesto PagePortfolio PagePress PageProduct Tour PagePromo PageReal Estate PageReferral PageResearch Report PageRestaurant PageRoadmap PageROI Calculator PageSecurity PageSolutions PageStartups PageStatus PageStorefront PageSwitch PageTemplate Gallery PageTravel PageWaitlist PageYear in Review Page
Hooks & Utilities
AI ChatChart kitCommerceDate utilsFile exportFile typesFiltersForm validationHapticsInvoicingMotion presetsNavigationNumber formatRelative timeRomanian locationsSpreadsheetText matchTonesUIProvideruseClipboarduseConsentuseControllableStateuseCooldownuseDebounceuseKeyboardInsetuseLocaleuseLongPressuseMediaControlsuseMediaQueryuseOverflowItemsusePersistedStateuseScrollEdgesuseScrollStateuseSelectionuseShortcutuseStickToBottom
GalleryTheme

Templates

Restaurant Page

Templates

Restaurant Page React template for Tailwind CSS v4

Design
Research Report PageRoadmap Page
Design
Live props
Appearance
design
tone
ctaTone
radius
background
backgroundColor
bandBackground
bandColor
Content
heroImage
orderHref
eventsHref
giftCardsHref
directionsHref
currency
locale
Behavior
partySizeMin
partySizeMax
defaultPartySize
timeStep
lastSeating
minNotice
bookingWindow
timeInput
timeZone
animateIn
Layout
menuColumns2
showMenu
showReservation
showStory
showGallery
showEvents
showReviews
showLocation
showCta
stickyReserveBar
header
footer
Code
import RestaurantPage from "@/components/templates/restaurant-page"

<RestaurantPage />
  1. Home
  2. Templates
  3. Restaurant Page
Pro

Restaurant Page React template for Tailwind CSS v4

v1.0.0·Added in 1.14.0

A React restaurant website template: live opening hours, a tabbed menu with dietary filters, table booking, a gallery, events and a map.

A restaurant's home page. The full-bleed hero shows whether the restaurant is open right now in its own time zone (Open until 11 PM, Closing soon, Closed now, opens tomorrow at 10 AM) and updates every minute; Reserve a table glides down to the booking form and focuses it, Order online links out. The menu has category tabs (arrow keys move between them) and dietary filter toggles (Vegan, Vegetarian, Gluten free, Spicy) in one bar that sticks under the header while you scroll the list; on phones both are swipeable chip rows. Filters combine, the tabs then show how many dishes match, and an empty section offers Clear filters. Every dish shows its price (glass and bottle for wines), dietary tags and a highlight badge. The reservation form takes the party size (steppers, typing, arrow keys), a date from the calendar (closed weekdays and past days are disabled, a bottom sheet on phones) and a time from chips per service (Brunch, Dinner) every timeStep minutes, with booked times struck through and past times hidden; the next bookable day is preselected. Name and email are validated on submit and focus moves to the first problem; the button spins while onReserve runs, then a confirmation shows the date, time, guests and a confirmation number with Add to calendar (an .ics file) and Make another booking. The gallery opens a full-screen lightbox (swipe, arrows, pinch zoom). Private event cards are one link each. The visit section has the address, Get directions, call, the week's hours grouped by day with today marked, and a map that opens full screen on touch. On phones a Reserve a table bar sticks to the bottom while the form is off screen.

Restaurant Page is a Pro React template in the React website templates category, written in TypeScript for React 19 and Tailwind CSS v4. It installs as source with npx wingo-ui@latest add restaurant-page, together with Marketing Section, Marketing Header, Marketing Footer, Testimonials Section, CTA Section and 15 more and the npm packages lucide-react and motion.

Built with

The sections this page is made of. In the full-screen preview, hold Alt to outline each one on the page.

  • Marketing Sectionmarketing-section
  • Marketing Headermarketing-header
  • Marketing Footermarketing-footer
  • Testimonials Sectiontestimonials-section
  • CTA Sectioncta-section

Add to a project

Requirements: React 19 and Tailwind CSS v4, in Next.js (App Router or Pages), Vite or React Router. Installation guide · Next.js setup · Vite setup

npx wingo-ui@latest add restaurant-page

Restaurant Page is part of Pro, with 298 more Pro items: $8 a month or $150 once. 14-day refund before you download any Pro item. See plans

Usage

Import RestaurantPage from @/components/templates/restaurant-page.

// app/page.tsx
"use client"

import Link from "next/link"
import { RestaurantPage, type RestaurantReservation } from "@/components/templates/restaurant-page"

async function reserve(reservation: RestaurantReservation) {
  const response = await fetch("/api/reservations", { method: "POST", body: JSON.stringify(reservation) })
  if (!response.ok) throw new Error("Booking failed")
  return (await response.json()) as { confirmation: string }
}

export default function HomeRoute() {
  return <RestaurantPage linkComponent={Link} timeZone="America/Chicago" partySizeMax={8} onReserve={reserve} />
}

Props

  • designdefault "warm"
    "warm" | "dark" | "minimal"

    The whole page's look. warm: a soft amber page with tinted bands and raised cards; dark: a night page in both themes (the tokens switch to dark under the root, overlays render inside it); minimal: a plain page with no bands, an inset hero and border-only cards. Each design picks its own backgrounds unless you set them.

  • restaurantdefault "RESTAURANT_INFO"
    RestaurantInfo

    { name, cuisine, priceRange?, street, city, neighborhood?, phone, email, point: { lat, lng }, rating?, reviewCount?, directionsNote? }: the brand, hero line, contact block and map pin.

  • hoursdefault "RESTAURANT_HOURS"
    RestaurantDayHours[]

    { day: 0 Sunday ... 6 Saturday, ranges: { label?, open: "17:00", close: "23:00" }[] } per weekday; no ranges is closed, a close at or before the open runs past midnight. Drives the open status, the hours table, the closed days of the calendar and the time slots.

  • categoriesdefault "RESTAURANT_MENU_CATEGORIES"
    RestaurantMenuCategory[]

    { id, label, description? }: the menu tabs, in order.

  • menudefault "RESTAURANT_MENU"
    RestaurantMenuItem[]

    { id, category, name, description?, price, variants?: { label, price }[], tags?: string[], highlight?, soldOut? }: the dishes and drinks. variants (Glass, Bottle) replace the price; tags are dietary tag ids.

  • dietaryTagsdefault "RESTAURANT_DIETARY_TAGS"
    RestaurantDietaryTag[]

    { id, label, icon?, tone? }: the dietary marks and filters. vegan, vegetarian, gluten-free and spicy get a drawn icon by id; an empty array hides the filters.

  • storydefault "RESTAURANT_STORY"
    RestaurantStory

    { eyebrow, title, paragraphs, chefName, chefRole, stats: { value, label }[], scene?, image? }: the chef story beside a picture.

  • gallerydefault "RESTAURANT_GALLERY"
    RestaurantGalleryImage[]

    { src?, scene?, alt, caption? }: the gallery tiles; without src the scene is drawn (pasta, pizza, salad, steak, fish, dessert, cocktail, wine, room, oven, cellar, terrace).

  • eventSpacesdefault "RESTAURANT_EVENT_SPACES"
    RestaurantEventSpace[]

    { id, name, description, capacity, minimum?, scene?, image?, href? }: the private event cards; href defaults to eventsHref#id.

  • reviewsdefault "RESTAURANT_REVIEWS"
    Testimonial[]

    Guest quotes with names, the occasion as role and star ratings, shown by TestimonialsSection.

  • heroImagedefault ""
    string

    A photo url for the hero; without it the dining room with the oven is drawn in code.

  • orderHrefdefault "/order"
    string

    The hero's Order online button; empty hides it.

  • eventsHrefdefault "/private-events"
    string

    Plan an event and the event cards link here.

  • giftCardsHrefdefault "/gift-cards"
    string

    The gift card band's main button.

  • directionsHrefdefault ""
    string

    Get directions; defaults to a Google Maps search for the address.

  • labels
    Partial<RestaurantPageLabels>

    Every string on the page (DEFAULT_RESTAURANT_PAGE_LABELS), including the open status sentences, validation messages and the confirmation.

  • partySizeMindefault 1
    number

    The smallest party the form books.

  • partySizeMaxdefault 10
    number

    The largest party the form books; larger groups are pointed to private events.

  • defaultPartySizedefault 2
    number

    The starting party size, kept inside the range.

  • timeStepdefault 30
    number

    Minutes between bookable times (at least 5).

  • lastSeatingdefault 60
    number

    Minutes before a service closes when the last table can be booked.

  • minNoticedefault 30
    number

    Minutes from now before the first time that can still be booked today.

  • bookingWindowdefault 60
    number

    How many days ahead the calendar opens.

  • timeInputdefault "slots"
    "slots" | "picker"

    slots: a grid of time chips per service with booked times struck through; picker: a TimePicker field limited to the open times.

  • isBooked
    (date: string, time: string) => boolean

    Marks taken times ("2026-11-06", "19:30") as booked: struck through and not selectable.

  • onReserve
    (reservation: RestaurantReservation) => void | RestaurantReservationResult | Promise<RestaurantReservationResult | void | unknown>

    Called with { date, time, partySize, name, email, phone, notes } once the form is valid. A returned promise keeps the button loading; resolve with { confirmation } to show your number, reject to keep the form and show labels.reserveFailed. Without it, a 900 ms pretend booking.

  • timeZonedefault "America/Chicago"
    string

    The restaurant's IANA time zone: the open status, today's row, today's past times and the first bookable day follow it, wherever the guest is.

  • now
    Date

    A fixed clock for screenshots and tests; default the live time, read after hydration (the server renders labels.hoursFallback).

  • currencydefault "USD"
    string

    ISO 4217 code for the menu prices.

  • localedefault ""
    string

    Intl locale for prices, dates and times; empty uses the UIProvider's, else en-US.

  • tonedefault "neutral"
    "neutral" | "brand" | "success" | "warning" | "danger" | "info"

    Accents: highlight badges, the active menu tab, pressed filters, the chosen time, the calendar selection and review stars.

  • ctaTonedefault "neutral"
    "neutral" | "brand" | "success" | "warning" | "danger" | "info"

    Reserve a table buttons, the form's submit, the sticky bar and the gift card band.

  • radiusdefault "lg"
    "none" | "sm" | "md" | "lg"

    Corners of panels and cards (0 / 12 / 16 / 24px), with matching inner tiles and time chips.

  • menuColumnsdefault 2
    1 | 2

    Dish columns from 768px; phones always get one.

  • backgrounddefault "soft"
    "plain" | "soft" | "glow" | "aurora" | "grid" | "dots"

    The main background. A design picks its own unless you set one (warm: soft, dark: glow, minimal: plain).

  • backgroundColordefault "oklch(0.72 0.11 58)"
    string

    The tint and glow color of the main background; each design has its own (warm amber, ember, sand).

  • bandBackgrounddefault "tinted"
    "muted" | "tinted" | "gradient" | "dots"

    The look of the alternating bands (warm: tinted, dark: muted; minimal has no bands). Cards and fields inside a band are lifted above it.

  • bandColordefault "oklch(0.72 0.11 58)"
    string

    The tint of tinted and gradient bands; defaults to backgroundColor.

  • showMenudefault true
    boolean

    The menu with its tabs and filters.

  • showReservationdefault true
    boolean

    The booking form. Off, the Reserve buttons and the sticky bar go too.

  • showStorydefault true
    boolean

    The chef story with its picture and numbers.

  • showGallerydefault true
    boolean

    The photo grid and its lightbox.

  • showEventsdefault true
    boolean

    The private event spaces.

  • showReviewsdefault true
    boolean

    The guest reviews.

  • showLocationdefault true
    boolean

    The address, hours table and map.

  • showCtadefault true
    boolean

    The gift card band before the footer.

  • stickyReserveBardefault true
    boolean

    On phones, a Reserve a table bar with the open status sticks to the bottom while the form is off screen.

  • headerdefault true
    boolean

    The sticky header with the brand, section links, call and Reserve.

  • footerdefault true
    boolean

    The footer with Visit, About and Help links.

  • headerProps
    Partial<MarketingHeaderProps>

    Anything for MarketingHeader (layout, variant, items...).

  • footerProps
    Partial<MarketingFooterProps>

    Anything for MarketingFooter (variant, columns, socials...).

  • tabsProps
    Partial<TabsRootProps>

    Anything for the menu TabsRoot (variant, size, activationMode...).

  • datePickerProps
    Partial<DatePickerProps>

    Anything for the reservation DatePicker (disabled days, presets, calendarProps...).

  • timePickerProps
    Partial<TimePickerProps>

    Anything for the TimePicker when timeInput is "picker".

  • galleryProps
    Partial<LightboxGalleryProps>

    Anything for the LightboxGallery (columns, aspect, maxVisible, featured...).

  • reviewsProps
    Partial<TestimonialsSectionProps>

    Anything for TestimonialsSection (layout, columns, card...).

  • mapProps
    Partial<LocationMapProps>

    Anything for the LocationMap (tileUrl, height, staticOnly, interactive...).

  • ctaProps
    Partial<CtaSectionProps>

    Anything for the gift card CtaSection (variant, title, hrefs...).

  • stickyBarProps
    Partial<StickyCtaBarProps>

    Anything for the phone StickyCtaBar (variant, showOn, hideOnScroll...).

  • animateIndefault true
    boolean

    The hero copy rises in once when the page mounts on the client; never during hydration, under reduced motion or in thumbnails.

  • linkComponent
    (props: LinkComponentProps) => ReactNode

    The router link for the header, event cards and footer links (next/link in an app).

  • className
    string

    Classes for the root.

  • classNames
    Partial<Record<RestaurantPageSlot, string>>

    Classes for header, hero, heroMedia, status, menu, menuBar, filters, menuPanel, menuItem, reservation, reservationForm, slots, confirmation, story, gallery, events, eventCard, reviews, location, hours, map, cta, footer and stickyBar.

Parts

  • RESTAURANT_PAGE_SAMPLE

    constant

    All the sample content of Olive & Ember in one object: restaurant, hours, categories, dietary tags, menu, story, gallery, event spaces and reviews.

  • RESTAURANT_INFO

    constant

    Olive & Ember, a wood-fired Mediterranean restaurant on Fulton Market, Chicago.

  • RESTAURANT_HOURS

    constant

    Closed Mondays, dinner Tuesday to Sunday, brunch on weekends, until 11 PM on Fridays and Saturdays.

  • RESTAURANT_MENU_CATEGORIES

    constant

    Starters, Mains, Desserts and Drinks.

  • RESTAURANT_DIETARY_TAGS

    constant

    Vegan, Vegetarian, Gluten free and Spicy.

  • RESTAURANT_MENU

    constant

    22 dishes and drinks with prices, tags, highlights, glass and bottle prices and one sold out.

  • RESTAURANT_STORY

    constant

    Chef Sofia Marino's story with three numbers.

  • RESTAURANT_GALLERY

    constant

    Nine drawn scenes: the room, pasta, pizza, a negroni, salad, ribeye, branzino, tiramisu and wine.

  • RESTAURANT_EVENT_SPACES

    constant

    The Ember Room, The Cellar and a full buyout.

  • RESTAURANT_REVIEWS

    constant

    Six guest reviews.

  • RESTAURANT_PAGE_DESIGNS

    constant

    The design names: ["warm", "dark", "minimal"].

  • DEFAULT_RESTAURANT_PAGE_LABELS

    constant

    The English strings.

  • drawRestaurantScene

    function

    (kind) returns an svg data url of a drawn scene (a plate from above, a glass, the room, the oven), for an img or a lightbox image.

  • drawRestaurantHero

    function

    () returns the wide drawn hero picture (the dining room with the oven) as an svg data url.

  • RestaurantPageProps

    type

    Props of RestaurantPage, including the attributes of the root element.

  • RestaurantPageLabels

    type

    Every string of the page.

  • RestaurantPageSlot

    type

    The keys of classNames.

  • RestaurantPageDesign

    type

    "warm" | "dark" | "minimal".

  • RestaurantPageRadius

    type

    "none" | "sm" | "md" | "lg".

  • RestaurantPageTimeInput

    type

    "slots" | "picker".

  • RestaurantPageMenuColumns

    type

    1 | 2.

  • RestaurantReservation

    type

    What onReserve receives: { date: yyyy-MM-dd, time: HH:mm, partySize, name, email, phone, notes }.

  • RestaurantReservationResult

    type

    What onReserve may resolve with: { confirmation? }.

  • RestaurantInfo

    type

    The restaurant's name, cuisine, address, contact, map point and rating.

  • RestaurantDayHours

    type

    { day, ranges }: one weekday's services.

  • RestaurantHoursRange

    type

    { label?, open, close }: one service, "HH:mm" 24h.

  • RestaurantMenuCategory

    type

    { id, label, description? }: one menu tab.

  • RestaurantMenuItem

    type

    One dish or drink.

  • RestaurantMenuVariant

    type

    { label, price }: a glass or bottle price.

  • RestaurantDietaryTag

    type

    { id, label, icon?, tone? }: a dietary mark and filter.

  • RestaurantStory

    type

    The chef story.

  • RestaurantChefStat

    type

    { value, label }: one number of the story.

  • RestaurantGalleryImage

    type

    { src?, scene?, alt, caption? }: one gallery tile.

  • RestaurantEventSpace

    type

    One private event card.

  • RestaurantSceneKind

    type

    The drawn scenes: pasta, pizza, salad, steak, fish, dessert, cocktail, wine, room, oven, cellar, terrace.

Examples

Open

Dark design

A night page in both themes: the tokens switch to dark under the root, with an ember glow and muted bands.

Open

Minimal design

A plain page with an inset hero, no bands and border-only cards.

Open

Brand accents

ctaTone and tone set to brand: orange Reserve buttons, highlight badges, chosen time and calendar day.

Open

A time picker and 15 minute slots

timeInput="picker" with timeStep 15 and parties up to 6: the time field only offers open, free times.

Open

When booking fails

onReserve rejects: the button spins, the form stays filled and says the table could not be booked.

Dependencies

lucide-reactmotionmarketing-sectionmarketing-headermarketing-footertestimonials-sectioncta-sectionbuttondate-pickerimage-lightboxinputlocation-mapnumber-inputsticky-cta-bartabstextareatime-pickertoggle-groupnavigationmotiontonesui-config

Files

  • components/templates/restaurant-page.tsx
  • components/templates/restaurant-page-data.ts

FAQ

Is the React Restaurant Page template free?

The preview, props and docs are free; copying the source needs a Pro plan. See plans.

How do I install Restaurant Page?

Run npx wingo-ui@latest add restaurant-page. It also adds the Wingo UI items it builds on (Marketing Section, Marketing Header, Marketing Footer, Testimonials Section, CTA Section and 15 more) and the npm packages lucide-react and motion. With shadcn, add the @wingo-ui registry with your API key, then run npx shadcn@latest add @wingo-ui/restaurant-page.

How does Restaurant Page behave on phones?

The menu has category tabs (arrow keys move between them) and dietary filter toggles (Vegan, Vegetarian, Gluten free, Spicy) in one bar that sticks under the header while you scroll the list; on phones both are swipeable chip rows.

See also

Storefront PageLanding PageDate PickerImage LightboxLocation Map

Related guides

  • Nextjs Restaurant Template: Open Now, Menu, Book a Table

    Build it: screens and apps · Nov 6, 2026 · 10 min read

PreviousResearch Report PageNext Roadmap Page