The frontend is a Next.js 15 App Router application that provides the complete shopping experience for Shop Microservers: browsing a product catalog, managing a cart, authenticating, and viewing order history. It is a fully client-rendered experience — all data fetching happens in the browser viaDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/astrxnomo/shop-microservers/llms.txt
Use this file to discover all available pages before exploring further.
fetch calls that go through the Nginx gateway. The frontend never connects directly to any microservice; every request is routed through NEXT_PUBLIC_API_URL, which points to the gateway address. Authentication state is stored in localStorage as a raw JWT string.
Overview
Framework
Next.js 15 with App Router. Runs on port 3000 inside Docker.
UI Stack
React 19, Tailwind CSS 3, Radix UI primitives (
@radix-ui/react-label, @radix-ui/react-slot), Lucide icons.API Communication
All requests go to
NEXT_PUBLIC_API_URL (default http://localhost). No direct microservice calls.Auth Storage
JWT stored in
localStorage under the key "token". Removed on logout (not yet implemented — clear manually or extend the app).Pages
| Route | File | Description |
|---|---|---|
/ | app/page.tsx | Product catalog grid with add-to-cart |
/login | app/login/page.tsx | Login form — stores JWT on success |
/register | app/register/page.tsx | Registration form — stores JWT on success |
/cart | app/cart/page.tsx | Cart view with item removal and checkout |
/orders | app/orders/page.tsx | Order history list for the current user |
/ — Product Catalog
Fetches GET /api/catalog/products on mount and renders a responsive grid of product cards. Each card shows the product image, category badge, name, price, and stock level. Authenticated users can add items to the cart directly from the grid. Unauthenticated users see a prompt to log in when they attempt to add an item.
/login and /register
Simple forms that call api.login() or api.register(). On success, both routes store the returned token and user object in localStorage and redirect to /.
/cart
Protected — redirects to /login if no token is found. Displays all cart items with quantity, per-item subtotal, and a grand total. Users can remove individual items or proceed to checkout, which calls api.placeOrder() and redirects to /orders on success.
/orders
Protected — redirects to /login if no token is found. Lists all orders in reverse-chronological order. Each order card shows an order ID (last 8 chars), creation date, status badge, line items, and the total.
API Client
Theapi object in frontend/lib/api.ts is a typed wrapper around fetch. All methods call through the gateway and handle the { success, data, error } envelope:
TypeScript Types
Theapi.ts module exports the following types, which are used throughout the app:
Authentication Flow
User submits login or register form
The form calls
api.login(email, password) or api.register(email, password), which posts to the gateway at /api/auth/login or /api/auth/register.Subsequent requests include the token
authHeaders() reads localStorage.getItem("token") before every request() call and injects Authorization: Bearer <token>. This happens automatically for all api.* calls — no per-call configuration needed.Environment Variable
The base URL for all gateway calls. In Docker Compose this is set to
http://localhost (or the host machine’s address when the gateway is exposed on port 80). Override this in your .env.local or docker-compose.yml if the gateway runs on a different host or port.Response Handling
All API calls go through therequest<T> function. It checks the success field of the response envelope and throws an Error with the error message if the call failed:
setError(err.message)).