X Enterprises
Composables

useDomain

Builds and returns typed API endpoint methods for all restaurant data resources plus domain/site config.

useDomain

API endpoint management composable. Reads runtimeConfig.public.apiEndpoint and the domain set in app.config.ts to construct typed fetch methods for every restaurant data resource the layer consumes.

URL convention:

  • Domain-scoped collection endpoints are built against ${apiEndpoint}/public/domains/${xRestaurants.domain}.
  • Per-restaurant detail endpoints (used by useRestaurant(slug)) resolve directly against ${apiEndpoint}/public/restaurants/${slug}.

The composable also exposes the resolved domain, siteUrl, and siteName so consumers don't have to re-read them from useAppConfig() / useRuntimeConfig().

Usage

const domain = useDomain()

// Read methods return null on any error (network, 404, 500) — no try/catch needed
const info = await domain.getInfo()
if (!info) {
  // domain not found or network error
  return navigateTo('/coming-soon')
}

const featured = (await domain.getRestaurantsFeatured()) ?? []
const menu = await domain.getRestaurantMenuBySlug("the-cafe")

// suggestRestaurant throws so the contact form can show the API's user-facing error
try {
  await domain.suggestRestaurant({
    restaurantName: "Joe's Diner",
    city: "Portland",
    submitterName: "Alex",
    submitterEmail: "alex@example.com",
  })
} catch (e: any) {
  errorMessage.value = e?.data?.message ?? "Please try again."
}

Error handling — null on failure

Every read method is wrapped so it returns null on any failure: network error, 404 (domain or slug not found), 500, etc. Pages can drop the try/catch boilerplate:

// Before: 6 lines of try/catch
let info: any = null
let domainNotFound = false
try {
  info = await domain.getInfo()
} catch (e: any) {
  if (e?.statusCode === 404 || e?.status === 404 || e?.response?.status === 404) {
    domainNotFound = true
  }
}

// After: 2 lines
const info = await domain.getInfo()
const domainNotFound = !info

For Promise.all, the wrapper returns null instead of rejecting, so plain Promise.all works with ?? [] defaults:

const [featured, popular, newest] = await Promise.all([
  domain.getRestaurantsFeatured(),
  domain.getRestaurantsTopRated(),
  domain.getNewestRestaurants(4),
])
const featuredRestaurants = (featured as any[]) ?? []
const popularRestaurants = (popular as any[]) ?? []
const newestRestaurants = (newest as any[]) ?? []

The one exception is suggestRestaurant, which still throws so /list-restaurant can display the API's user-facing error message.

Returns

KeyTypeDescription
domainstringResolved domain from appConfig.xRestaurants.domain (empty string if unset).
siteUrlstringResolved site URL from runtimeConfig.public.siteUrl.
siteNamestringResolved site name from runtimeConfig.public.siteName.
getInfo() => Promise<T | null>Fetches general domain/site information. Returns null on error.
getRestaurants(params?: { page?, limit?, cuisineType?, neighborhood?, priceRange?, featured?, sortBy?, sortOrder? }) => Promise<T | null>Fetches the full restaurant listing with optional filters. Returns null on error.
getRestaurantsByCuisine(cuisine: string, page?: number, limit?: number) => Promise<T | null>Fetches restaurants filtered by a single cuisine. Returns null on error.
getRestaurantsByNeighborhood(neighborhood: string, page?: number, limit?: number) => Promise<T | null>Fetches restaurants filtered by a single neighborhood. Returns null on error.
getRestaurantsByPrice() => Promise<T | null>Fetches restaurants grouped by price range. Returns null on error.
getRestaurantBySlug(slug: string) => Promise<T | null>Fetches a single restaurant by its slug. Returns null on error (use to detect 404).
getRestaurantMenuBySlug(slug: string) => Promise<T | null>Fetches the menu for a restaurant. Returns null on error.
getRestaurantReviewsBySlug(slug: string) => Promise<T | null>Fetches reviews for a restaurant. Returns null on error.
getRestaurantPhotosBySlug(slug: string) => Promise<T | null>Fetches photos for a restaurant. Returns null on error.
getNewestRestaurants(limit?: number) => Promise<T | null>Fetches the most recently added restaurants. Returns null on error.
getRestaurantsFeatured() => Promise<T | null>Fetches the featured restaurants list. Returns null on error.
getRestaurantsNew() => Promise<T | null>Fetches newly added restaurants. Returns null on error.
getRestaurantsRandom() => Promise<T | null>Fetches a random selection of restaurants. Returns null on error.
getRestaurantsSearch(query: string) => Promise<T | null>Full-text search across restaurants. Returns null on error.
getRestaurantsTopRated() => Promise<T | null>Fetches top-rated restaurants. Returns null on error.
getSitemap() => Promise<T | null>Fetches sitemap data for all restaurant slugs. Returns null on error.
suggestRestaurant(body: { restaurantName, address?, city?, phoneNumber?, website?, submitterName, submitterEmail, notes? }) => Promise<T>POSTs a restaurant-suggestion form (used by /list-restaurant). Throws on error — wrap in try/catch to show the API error message to users.

AI Context

composable: useDomain
package: "@xenterprises/nuxt-x-restaurants"
use-when: >
  Fetching any restaurant data from the API — listing, individual profile,
  menu, reviews, photos, featured/new/random/top-rated collections, search,
  or sitemap generation. Also use for restaurant-suggestion form submissions
  via suggestRestaurant(). All page-level data fetching goes through this composable.
Copyright © 2026