Industrial Luxury meets Engineering Authority. Built with Next.js 15, PayloadCMS 3.6, and React 19.
This repository houses the official website for Smatch, designed to convey high-end industrial proficiency and data density. The architecture is a "Monster" hybrid of a static-first frontend and a dynamic headless CMS, unified in a single Next.js repo.
Key Features:
- Dynamic Block System: Over 17 custom CMS blocks for flexible page building.
- Premium Aesthetics: Custom "Industrial Luxury" design system with GSAP/Framer Motion animations.
- Type-Safe: End-to-end type safety from database to frontend components.
- Global Editing: Full control over headers, footers, and SEO metadata via Payload Globals.
| Category | Technology | Version | Purpose |
|---|---|---|---|
| Core | Next.js | 15.4.10 | App Router, Server Components |
| CMS | PayloadCMS | 3.68.5 | Headless content management |
| DB | PostgreSQL | Latest | Structured data persistence |
| UI | TailwindCSS | 3.4.3 | Utility-first styling |
| Animation | GSAP + Framer Motion | Latest | High-performance interactions |
| Icons | Phosphor Icons | 2.1.10 | Consistent iconography |
| Language | TypeScript | 5.7.3 | Strict type checking |
- Node.js: v20.9.0 or higher
- pnpm: v9 or v10 (
npm i -g pnpm) - PostgreSQL: A running Postgres instance
-
Clone the repository:
git clone <repo-url> cd smatch-website
-
Install dependencies:
pnpm install
-
Environment Setup: Duplicate
.env.exampleto.envand fill in your secrets.# Database DATABASE_URI="postgresql://user:password@localhost:5432/smatch" # Payload PAYLOAD_SECRET="<generate-a-long-random-string>" NEXT_PUBLIC_SERVER_URL="http://localhost:3000" # Optional S3 (for media) S3_ENABLED=true S3_BUCKET=... S3_ACCESS_KEY_ID=... S3_SECRET_ACCESS_KEY=... S3_REGION=...
-
Run Development Server:
pnpm dev
- Website: http://localhost:3000
- Admin Panel: http://localhost:3000/admin
The project follows a standard Next.js App Router structure with PayloadCMS integrated.
src/
βββ app/
β βββ (frontend)/ # Public facing pages website
β βββ (payload)/ # Payload Admin panel routes
βββ blocks/ # Modular CMS blocks (Config + Component)
β βββ ArchiveBlock/
β βββ MissionVision/
β βββ ...
βββ collections/ # Payload Collection definitions
β βββ Pages/
β βββ Projects/
β βββ Media/
βββ components/ # Shared React components
β βββ ui/ # Shadcn/Radix primitives
β βββ landing/ # Landing page specific components
βββ globals/ # Global CMS configs (Header, Footer)
βββ heros/ # Hero component variants
βββ utilities/ # Helper functions (formatters, seeders)
βββ payload.config.ts # Main CMS configuration
We adhere to a strict "Smatch" design language defined in tailwind.config.mjs.
- Backgrounds:
smatch-black(#050505),smatch-charcoal(#0F0F0F) - Accents:
smatch-gold(#FFC800) for primary actions and highlights. - Text:
smatch-text-primary(White),smatch-text-secondary(Zinc-400).
- Headings:
Antonio(Variable, uppercase, industrial). - Body:
Inter(Clean, legible). - Code/Data:
JetBrains Mono(Technical data visualization).
- Use Tokens: Never hardcode hex values. Use
bg-smatch-black,text-smatch-gold. - Visual Hierarchy: Use whitespace as an active element.
- Gold Usage: Reserved for high-importance interactions and "success" states.
- Folder: Create
src/blocks/MyNewBlock/. - Config: Add
config.ts(Payload Field definition). - Component: Add
Component.tsx(React server component). - Register:
- Add to
src/collections/Pages/index.ts(schema). - Add to
src/components/RenderBlocks.tsx(rendering).
- Add to
- Types: Run
pnpm generate:types.
When you modify a Collection or Global config:
- Run
pnpm generate:typesto update TypeScript interfaces. - Run
pnpm migrate(if using strict migrations, otherwise Payload handles schema sync in dev).
| Command | Description |
|---|---|
pnpm dev |
Start dev server with TurboPack |
pnpm build |
Build for production |
pnpm generate:types |
Regenerate TypeScript types from CMS config |
pnpm lint:fix |
Fix ESLint and Prettier issues |
pnpm payload |
Run Payload CLI commands |
Deployed via Vercel.
- Build Command:
next build - Output Directory:
.next - Environment: Ensure all
PAYLOAD_SECRETand Database variables are set in Vercel.
Note: For Vercel deployment, ensure the Postgres database allows connections from Vercel's IP range or use a connection pooling string (e.g., Supabase Transaction Mode).
- Follow the "Monster" Rules: Robust error handling, strict typing, and high-end aesthetics.
- Avoid "Any": Utilize generated types (
@/payload-types). - Library First: Use existing Shadcn/Radix components before building custom ones.
Β© 2025 Smatch Digital. All rights reserved.