Build Phases
Phase 1 — Next.js Scaffold
Bootstrap the frontend project with TypeScript, Tailwind, and the App Router.
Create the Project
npx create-next-app@latest my-project \
--typescript \
--tailwind \
--eslint \
--app \
--src-dir \
--import-alias "@/*"
cd my-projectInstall Dependencies
pnpm add framer-motion # Animations
pnpm add sharp # Required for Next.js Image
pnpm add @tailwindcss/typography # Styles WordPress HTML content
pnpm add -D @types/node # Node.js type definitionsFolder Structure
src/
├── app/
│ ├── layout.tsx # Root layout (header, footer, fonts)
│ ├── page.tsx # Homepage
│ ├── blog/
│ │ ├── page.tsx # Blog listing
│ │ └── [slug]/page.tsx # Individual blog post
│ ├── projects/
│ │ ├── page.tsx # Projects listing
│ │ └── [slug]/page.tsx # Individual project
│ └── api/revalidate/
│ └── route.ts # Webhook endpoint for ISR
├── components/ # Reusable UI components
├── lib/
│ └── wordpress.ts # All WordPress API fetch functions
└── types/
└── wordpress.ts # TypeScript type definitionsConfigure next.config.ts
// next.config.ts
import type { NextConfig } from "next";
const nextConfig: NextConfig = {
images: {
remotePatterns: [
{
protocol: "https",
hostname: "cms.yourdomain.com", // Your WordPress domain
pathname: "/wp-content/uploads/**",
},
],
},
};
export default nextConfig;Without adding the WordPress hostname to remotePatterns, all WordPress media images will fail to load in Image components.
Environment Variables
Create .env.local in your project root:
# .env.local
NEXT_PUBLIC_WP_API_URL=https://cms.yourdomain.com/wp-json/wp/v2
REVALIDATION_SECRET=your-super-secret-key-hereNever prefix secrets with NEXT_PUBLIC_ — that exposes them to the browser. Only the API URL is safe to expose.