Frontend for the postcode-pt API — search Portuguese postal codes (CP4-CP3) and browse the district → municipality → locality hierarchy.
Live demo: https://postcode-pt-web.vercel.app
- Postal code search — type 7 digits (with or without the hyphen) and get every entry for that code, including street, locality, municipality and district.
- District browser — list of all 29 Portuguese districts with drill-down to each district's municipalities.
- Dark mode — light / dark / system toggle persisted via
next-themes. - Mobile-first responsive — layouts adapted for phone, tablet and desktop.
- Server Components + cache — data fetched on the server with a 1-day revalidate for static endpoints.
| Layer | Technology |
|---|---|
| Framework | Next.js 16 (App Router, Turbopack, Server Components) |
| Language | TypeScript 5 (strict) |
| Styling | Tailwind CSS 4 |
| Components | shadcn/ui (Base UI) |
| Theming | next-themes |
| Linting | ESLint 9 |
| Hosting | Vercel |
| CI | GitHub Actions |
src/
├── app/
│ ├── layout.tsx # Root layout + ThemeProvider + SiteHeader
│ ├── page.tsx # Home: search form + districts link
│ ├── districts/
│ │ ├── page.tsx # List of the 29 districts
│ │ └── [code]/page.tsx # District + municipalities
│ └── postal-codes/
│ └── [code]/
│ ├── page.tsx # Postal code details
│ └── not-found.tsx # Message for invalid / missing codes
├── components/
│ ├── site-header.tsx # Header with nav + theme toggle
│ ├── theme-provider.tsx # next-themes wrapper
│ ├── theme-toggle.tsx # Light / dark / system dropdown
│ ├── search-form.tsx # Client form with CP4-CP3 validation
│ └── ui/ # shadcn primitives
└── lib/
└── api.ts # Typed client + normalization helpers
npm install
npm run devThen open http://localhost:3000.
The app consumes https://postcode-pt.onrender.com/v1 by default. To point at a local backend, create .env.local:
NEXT_PUBLIC_API_BASE_URL=http://localhost:8000/v1| Command | Description |
|---|---|
npm run dev |
Development server (Turbopack) |
npm run build |
Production build |
npm run start |
Serve the production build |
npm run lint |
ESLint |
npm run typecheck |
Type-check (tsc --noEmit) |
Every push to main and every PR runs GitHub Actions with lint, typecheck and build. Vercel also reacts to every push on main and publishes automatically to https://postcode-pt-web.vercel.app.
- postcode-pt — FastAPI service that powers this frontend
- postcode-pt-cli — Go CLI for the same API (
pcpt 1100-038)
- Search history (localStorage)
- Per-municipality page with the list of localities
- Locality name suggestions / autocomplete
- Sitemap.xml + dynamic OpenGraph images
- E2E tests (Playwright)