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-project

Install 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 definitions

Folder 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 definitions

Configure 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-here
!

Never prefix secrets with NEXT_PUBLIC_ — that exposes them to the browser. Only the API URL is safe to expose.

PreviousPhase 0 — WordPressNextPhase 2 — API Layer