A multi-tenant bar inventory and cocktail app built with Nuxt 3, supporting multiple bars with tenant-specific data from Cockpit CMS.
- Inventory Management: Track bottles with size, state, and images per tenant
- Recipe Discovery: Find cocktails from your custom cocktails or The Cocktail DB
- Smart Matching: See which drinks you can make with your current inventory
- Non-Alcoholic Support: Includes mocktails, beer, and wine
- Live Data: Fetches fresh data directly from Cockpit CMS API
- Multi-Tenant Support: Host multiple bars with separate inventories and drinks using path-based routing
Once deployed, your tenants will be accessible at:
https://booz.bar/(Home Page)https://booz.bar/about- About Pagehttps://booz.bar/foo- Home page for a tenant named "foo"https://booz.bar/foo/available- Available drinks for "foo" (follow similar structure for drinks, bottles, essentials, et al)
The deployed site fetches data directly from your Cockpit CMS API at runtime. This means:
- Visitors see fresh, up-to-date inventory and drink data
- No need to rebuild/redeploy when data changes in Cockpit CMS
- Updates to your CMS are immediately reflected on the live site
- Each tenant fetches from their configured Cockpit collections
All TypeScript interfaces and types are defined in types/index.ts. This file contains comprehensive type definitions for:
- Tenant Configuration - Multi-tenant setup and routing
- Bar Data - Complete bar inventory structure
- Bottles - Spirit inventory with detailed metadata
- Drinks - Cocktail recipes with ingredients and instructions
- Beer/Wine - Non-spirit bottle inventory
- Bitters - Cocktail bitters and flavor profiles
- Essentials - Bar essentials and mixers
- Search Types - Omnisearch and drink search interfaces
The root data structure for each tenant is a BarData object containing arrays of bottles, drinks, beers, wines, bitters, and essentials.
For detailed field descriptions and comments, see the type definitions in types/index.ts.
The app uses Nuxt's dynamic routing with a [tenant] parameter:
- All pages are under
/pages/[tenant]/ - Middleware (
middleware/tenant.global.ts) handles:- Non-tenant routes (home, about)
- Redirecting root paths to default tenant
- Validating tenant slugs
- Showing error pages for unknown tenants
All composables accept an optional tenant parameter:
const { fetchBottles, fetchDrinks } = useCockpitAPI(tenantSlug);
const { loadInventory } = useCocktails(tenantSlug);
const { loadBeerWine } = useBeerWine(tenantSlug);Each tenant has isolated state using tenant-prefixed keys:
const inventory = useState(`${tenantSlug}_inventory`, () => []);# With Bun
bun test
# Or with npm
npm test# With Bun
bun run format
# Or with npm
npm run format- The docs folder
- Tenant Configuration: See
utils/tenants.tsfor adding/modifying tenants - API Configuration: See
utils/cockpitConfig.tsfor Cockpit CMS settings - Copilot Instructions: See
.github/copilot-instructions.mdfor AI development guidelines
CC-BY-4.0 - Creative Commons Attribution 4.0 International License
