X Enterprises
Composables

useOpenNow

Reactive composable + pure helper to determine if a restaurant is currently open, plus its closing time or next opening.

useOpenNow

Given a restaurant's hours data, returns whether it's currently open plus the closing time (if open) or the next opening time (if closed).

Supports both data shapes the layer encounters:

  • Schema.org array (API responses): [{ dayOfWeek: 'Monday', opens: '09:00', closes: '21:00' }, ...]
  • Plain object (mock data): { monday: '11:00 AM - 10:00 PM', tuesday: '11:00 AM - 10:00 PM', ... }

Usage

<script setup>
const props = defineProps<{ restaurant: any }>()

// Reactive — re-evaluates if the hours change
const { isOpen, status, closesAt, opensAt } = useOpenNow(
  computed(() => props.restaurant.openingHours ?? props.restaurant.hours),
)
</script>

<template>
  <UBadge :color="isOpen ? 'success' : 'neutral'">
    {{ isOpen ? 'Open Now' : 'Closed' }}
  </UBadge>
  <span v-if="isOpen && closesAt">Open until {{ formatTime12h(closesAt) }}</span>
  <span v-else-if="opensAt">Closed · Opens {{ formatTime12h(opensAt) }}</span>
</template>

Pure function form

For non-reactive contexts (filter callbacks, event handlers), use isOpenNow() directly:

import { isOpenNow } from '#imports'  // or auto-imported in setup

const filtered = list.filter(r => isOpenNow(r.openingHours ?? r.hours).isOpen)

Returns

KeyTypeDescription
isOpenbooleanWhether the restaurant is currently open. false if hours data is missing or the restaurant is closed.
status'open' | 'closed' | 'unknown''open' if within hours, 'closed' if outside hours, 'unknown' if hours data is missing/invalid.
closesAtstring | undefinedHH:MM (24h) when the restaurant closes today. Only set when status === 'open'.
opensAtstring | undefinedHH:MM (24h) when the restaurant next opens. Only set when status === 'closed'.

Notes

  • Times are evaluated against the current local time (new Date()).
  • The composable accepts a ref, computed, or plain value for hours.
  • Crosses midnight correctly — a restaurant open until "23:00" is shown as closing at 23:00, not as "closed since 23:00".

AI Context

composable: useOpenNow
package: "@xenterprises/nuxt-x-restaurants"
use-when: >
  Showing whether a restaurant is currently open. Two forms: useOpenNow(hours)
  for reactive display in components (cards, hero, sidebar), and isOpenNow(hours)
  as a pure helper for filtering lists. Handles both schema.org array format and
  plain object format. Returns { isOpen, status, closesAt?, opensAt? }.
Copyright © 2026