Skip to content
AGNT

Frontend

Route groups.

The Next.js App Router conventions used across the PWA: three route groups, each with its own layout and auth model.

Three groups

The src/app/ directory splits into three route groups using parenthesised folder names. The parentheses are stripped from the URL, so a file at app/(public)/landing/page.tsx serves /landing.

GroupLayoutAuthPurpose
(public)Marketing shell, skip-link, JSON-LDNoneLanding, product pages, legal, docs.
(authed)App chrome (nav, profile drawer)Reads agnt_token cookieConsumer app and venue admin dashboard.
apiNone (route handlers)Forwards cookie to backendThin proxies to the FastAPI backend.

Public routes

Everything under src/app/(public)/. The layout injects the skip link, the Organization / WebApplication / WebSite JSON-LD, and forces dynamic = "force-dynamic" as a workaround for the Next 16 + React 19 SSG prerender bug.

/landing
/for-you
/for-businesses
/pricing
/partners
/developers
/stack
/prompts
/commerce
/network
/docs
/manifesto
/team
/signals
/guides
/comparisons
/benchmarks
/glossary
/changelog
/case-studies
/faq
/blog
/privacy
/terms
/cookies
/start
/p/[id]
/r/[code]
/u/[username]
/v/[slug]
/cities/[city]

Authed routes

Everything under src/app/(authed)/. These routes read the agnt_token cookie and redirect to /startif it's missing. The consumer app lives under /me; the venue admin dashboard lives under /venue/admin.

/me
/me/bookings
/me/lists
/me/lists/[id]
/me/settings
/notifications
/upgrade
/lemming
/scan-demo
/venue/claim
/venue/admin
/venue/admin/agent
/venue/admin/bookings
/venue/admin/customers
/venue/admin/crm
/venue/admin/crm/[id]
/venue/admin/knowledge
/venue/admin/menu
/venue/admin/finance
/venue/admin/accounting
/venue/admin/commerce
/venue/admin/analytics
/venue/admin/escalations
/venue/admin/settings
/venue/admin/visibility
/venue/admin/network
/venue/admin/promote
/venue/admin/clients

API route handlers

The PWA exposes 51 route handlers under src/app/api/. They do not implement business logic. Every handler is a thin proxy that:

  1. Reads the agnt_token cookie from the incoming request.
  2. Forwards to the Python backend via backendFetch or authBackendFetch.
  3. Preserves HTTP status codes by catching BackendError and rethrowing with the right status.
typescriptsrc/app/api/venues/[slug]/route.ts (illustrative)
import { NextRequest, NextResponse } from "next/server";
import { authBackendFetch, BackendError } from "@/lib/api";

export async function GET(req: NextRequest, { params }: { params: { slug: string } }) {
  try {
    const data = await authBackendFetch(req, `/api/venues/${params.slug}`);
    return NextResponse.json(data);
  } catch (err) {
    if (err instanceof BackendError) {
      return NextResponse.json({ error: err.message }, { status: err.status });
    }
    throw err;
  }
}

Layouts

Nested layouts are used for the docs shell and the venue admin chrome. For example, this page renders through:

  1. src/app/layout.tsx(root) — fonts, global CSS, viewport
  2. src/app/(public)/layout.tsx— skip-link, root JSON-LD,force-dynamic
  3. src/app/(public)/docs/layout.tsx— marketing nav, ambient background, marketing footer
  4. src/app/(public)/docs/frontend/routes/page.tsx— this page

Related