Guides

Next.js integration

Use App Router server actions or route handlers for secret work, and client components or embeds for the booking UI.

Server-side calls (session)

In Server Components or route.js handlers running on the same deployment, use the Supabase server client or forward the user cookie—dashboard APIs like /api/resources already read the session.

Server Component fetching tenant data
// app/(dashboard)/example/page.tsx — same origin, user logged in
export default async function ExamplePage() {
  const res = await fetch(`${process.env.NEXT_PUBLIC_APP_URL}/api/resources`, {
    cache: 'no-store',
    headers: {
      // When rendering in this app, cookies are forwarded automatically in RSC fetch in many setups.
      // If calling from another service, use a server secret key pattern instead.
    },
  })
  const { resources } = await res.json()
  return <pre>{JSON.stringify(resources, null, 2)}</pre>
}

Same app vs external Next app

If your Next app is not this BaaS repo, you cannot use session cookies. Call the widget endpoints with a publishable key from the browser, or proxy through your backend with a server secret.

Client widget calls

From use client components, call /api/widget/* on your BaaS base URL with NEXT_PUBLIC_BAAS_PUBLISHABLE_KEY (never the server secret).

Client fetch
'use client'

const base = process.env.NEXT_PUBLIC_APP_URL
const key = process.env.NEXT_PUBLIC_BAAS_PUBLISHABLE_KEY

export async function loadAvailability(resourceId: string) {
  const q = new URLSearchParams({
    key: key!,
    resource_id: resourceId,
    start_date: '2025-06-01',
    end_date: '2025-06-30',
  })
  const res = await fetch(`${base}/api/widget/availability?${q}`)
  if (!res.ok) throw new Error(await res.text())
  return res.json()
}

Embed

Fastest path: iframe the hosted embed URL and pass tenant_id, publishable key, and widget config id.