Frontend Init
What we’re building
Section titled “What we’re building”A Next.js application at apps/web, using the App Router with a top-level app/ directory (no src/), pointed at the NestJS API through NEXT_PUBLIC_API_URL.
Architecture already committed to the App Router: Server Components fetch from the GraphQL API on the server for the public, cacheable read path, and Client Components hold the admin session for the JWT-authed write path. create-next-app scaffolds that structure directly instead of you assembling it by hand.
Pros & cons
Section titled “Pros & cons”App Router vs. Pages Router. The App Router gives you React Server Components — a component that runs on the server, fetches data directly, and never ships its code to the browser — plus nested layouts and per-segment revalidation, which is exactly the ISR model the architecture lesson describes. The older Pages Router is simpler and has no server/client component split to reason about, but it also has no Server Components, so every data fetch either happens in getServerSideProps/getStaticProps or on the client. For a course built around SSR/ISR, App Router is the only real option.
src/ vs. no src/. A src/ directory keeps application code separate from root-level config files (next.config.ts, package.json) — useful in larger projects with many top-level files. apps/web is already namespaced inside the devblog/ monorepo, so that separation buys less here. This course keeps app/ at the top level of apps/web, consistently, in every lesson that touches the front end.
Set it up
Section titled “Set it up”Scaffold the app into apps/web, non-interactively:
cd devblognpx create-next-app@latest apps/web --typescript --app --no-src-dir --no-tailwind --eslint --import-alias "@/*" --use-npmcd apps/webInstall the two dependencies this course needs beyond what create-next-app already includes:
# graphql-request: a minimal client for calling the NestJS GraphQL API# react-markdown + remark-gfm: render a post's Markdown body, including GFM tables/strikethroughnpm install graphql-request react-markdown remark-gfmCreate apps/web/.env.local so the app knows where the API lives:
NEXT_PUBLIC_API_URL=http://localhost:4000/graphqlThis mirrors the root .env.example value from Repo layout. .env.local is a Next.js convention — it’s gitignored by the scaffold’s own .gitignore and always wins over other env files in local development.
Start the dev server:
npm run devVerify
Section titled “Verify”Open http://localhost:3000# The default Next.js starter page loads, with a live-reloading dev server in the terminalThe resulting app/ layout, fresh from the scaffold:
apps/web/├── app/│ ├── favicon.ico│ ├── globals.css│ ├── layout.tsx # root layout — wraps every page, holds <html>/<body>│ └── page.tsx # the "/" route├── public/├── .env.local├── next.config.ts├── package.json├── tsconfig.json└── eslint.config.mjs(The exact file set can vary slightly with the Next.js version you install — the app/ folder holding layout.tsx and page.tsx is the part that matters.)
apps/web is a Next.js App Router project, scaffolded with create-next-app --app --no-src-dir, with graphql-request and react-markdown/remark-gfm installed for calling the API and rendering post bodies. NEXT_PUBLIC_API_URL in .env.local points it at http://localhost:4000/graphql, matching the API’s port from Backend init. npm run dev confirms it boots on port 3000.
Next: Compose skeleton →