apps/web + apps/admin + apps/api

Three apps, one monorepo.

8 mineasy

Tour all three apps. We already covered apps/api in the Go API course; this lesson focuses on apps/web and apps/admin — what's the same, what's different.

apps/web — the public Next.js site

apps/web/
apps/web/
ā”œā”€ā”€ app/
│ ā”œā”€ā”€ (marketing)/ public pages — landing, pricing, blog
│ │ ā”œā”€ā”€ page.tsx
│ │ ā”œā”€ā”€ pricing/page.tsx
│ │ └── layout.tsx header + footer
│ ā”œā”€ā”€ (auth)/ login, signup, forgot-password
│ ā”œā”€ā”€ (app)/ logged-in pages — dashboard, settings
│ │ ā”œā”€ā”€ dashboard/page.tsx
│ │ └── layout.tsx sidebar + topbar
│ ā”œā”€ā”€ api/ Next.js route handlers (mostly empty)
│ └── layout.tsx root layout — theme, providers
ā”œā”€ā”€ components/ reusable React components
ā”œā”€ā”€ hooks/ useUsers, useCurrentUser, …
ā”œā”€ā”€ lib/ api client, auth helpers, utils
└── public/ static assets

Three route groups: (marketing), (auth), (app). Each has its own layout. The parens don't appear in URLs.

apps/admin — the staff panel

apps/admin/
apps/admin/
ā”œā”€ā”€ app/
│ ā”œā”€ā”€ (auth)/login/page.tsx
│ ā”œā”€ā”€ dashboard/page.tsx
│ ā”œā”€ā”€ resources/
│ │ ā”œā”€ā”€ users/page.tsx defineResource() — generates CRUD
│ │ └── products/page.tsx
│ └── layout.tsx admin shell — sidebar, top nav
ā”œā”€ā”€ components/
│ ā”œā”€ā”€ admin/ DataTable, FormBuilder, etc.
│ └── ui/ shadcn primitives
ā”œā”€ā”€ hooks/
└── lib/

The killer file is app/resources/x/page.tsx — we cover defineResource() in chapter 4. Almost every admin page is one of these.

What's the same across both apps

  • Both use Next.js 14 App Router (no Pages Router)
  • Both import types from @workspace/shared
  • Both use React Query for data
  • Both use shadcn/ui + Tailwind CSS

What differs

  • Auth scope — web cookies are scoped to customer-token; admin to staff-token. One can't accidentally log into the other.
  • Layout — web is marketing-shaped (header / hero / footer); admin is dashboard-shaped (sidebar / topbar).
  • Robots — admin has noindex,nofollow on every page.
The shared API client trick: both apps import the same lib/api.ts shape but configure it with different cookie names. We'll see this in chapter 3.

Quick check

A teammate suggests deleting apps/admin and gating admin URLs inside apps/web by role. Trade-off check — what's the biggest downside?

Try it

In your scaffolded project, open both apps/web/app/layout.tsx and apps/admin/app/layout.tsx. In notes.md, write:

  • What providers does each app wrap children in?
  • What's in each app's root metadata (title, OG, etc.)?
  • What one component or import is DIFFERENT between them?

What's next

Last lesson of the chapter — packages/shared, the glue between the three apps.

Spot a typo? Have an idea?

Help us improve this lesson. One click opens a GitHub issue with the lesson URL pre-filled — suggest clearer wording, report a bug, or request more depth. The course keeps improving thanks to learners like you.

Suggest an improvement on GitHub