Restaurant Profile
Restaurant Profile
The /restaurants/:slug route is a Nuxt layout route (restaurants/[slug].vue) that wraps all restaurant sub-pages. It fetches the restaurant profile once via useDomain().getRestaurantBySlug() inside useAsyncData, then renders the hero, sticky tab navigation, sidebar, and the active child route. If no restaurant is returned, the layout throws a 404 via createError().
JSON-LD LocalBusiness schema (XSchemaLocalBusiness) is injected automatically — only when restaurant is truthy. The page also emits a page_view analytics event via useAnalytics().trackPageView() on mount.
The default child (/restaurants/:slug/) renders the profile overview: about section, promotions, FAQ, and contact details.
Routes
| Route | Description |
|---|---|
/restaurants/:slug | Layout — data provider, renders hero, navigation, and sidebar. |
/restaurants/:slug/ | Overview child — about, promotions, FAQ, and contact. |
/restaurants/:slug/menu | Menu child. |
/restaurants/:slug/reviews | Reviews child. |
/restaurants/:slug/photos | Photos child. |
/restaurants/:slug/articles | Related articles child. |
Components Used
| Component | Role |
|---|---|
XRDProfileHero | Full-width restaurant hero image with name, rating stars, cuisine, and price. |
XRDProfileNavigation | Sticky tab navigation (Home, Menu, Local Reviews, Photos, Articles). |
XRDProfileSidebar | Sticky sidebar in the right column on desktop. |
XRDProfileCard | Compact card used in related restaurants sections. |
XRDProfileAbout | About text and highlights section. |
XRDProfileDescription | Extended description block. |
XRDProfileContact | Contact details (phone, email, website). |
XRDProfileContactInfo | Structured contact info display. |
XRDProfileHours | Opening hours table. |
XRDProfileMap | Embedded map showing restaurant location. |
XRDProfileCuisine | Cuisine tags display. |
XRDProfileDietary | Dietary option badges. |
XRDProfileAmenities | Amenities icon list. |
XRDProfileMenuSection | Menu category section. |
XRDProfileMenuItem | Individual menu item. |
XRDProfileReviews | Reviews container. |
XRDProfileReviewsItem | Single review item. |
XRDProfileSocial | Social media links. |
XRDProfilePromotions | Current promotions / offers. |
XRDProfileNewsletter | Email newsletter signup widget. |
XRDProfileFAQ | Restaurant-specific FAQ accordion. |
XRDProfileBreadcrumb | Breadcrumb navigation. |
Data Fetching
The layout calls useDomain().getRestaurantBySlug(slug) inside useAsyncData, keyed by restaurant-${slug}:
const { data: restaurant } = await useAsyncData<RestaurantApiResponse>(
`restaurant-${slug.value}`,
async () => (await domain.getRestaurantBySlug(slug.value)) as RestaurantApiResponse,
)
The restaurant ref is then provide('restaurant', restaurant)'d to child pages so they can read it via inject('restaurant') without re-fetching. Child pages should use this pattern rather than calling useDomain() again.
useSiteMeta({...}) builds SEO meta + OpenGraph + Twitter Card from the restaurant object (metaTitle, metaDescription, description, tagline, coverImage, images[0], slug) in one call.
AI Context
route: /restaurants/:slug
package: "@xenterprises/nuxt-x-restaurants"
use-when: >
Rendering any restaurant profile page. The layout at /restaurants/:slug
is the data provider — it calls useDomain().getRestaurantBySlug() once,
provides the result to children, and emits an analytics page_view event.
JSON-LD LocalBusiness schema is injected via XSchemaLocalBusiness.
Child pages should read the restaurant via inject('restaurant') rather
than re-fetching.
