Next.js — App Router, Folder Structure, Rendering and Full Stack with SQL Server
In short: React is a library for building UI components.
- Next.js is a React framework that adds file-based routing, server-side and static rendering, Server Components, data fetching and caching, API endpoints (route handlers, Server Actions), image/font optimisation, SEO metadata and production build/deployment tooling.
- It produces full HTML from the server, improving SEO and first load.
In short: Folders inside app/ map to URL segments; a segment becomes routable with page.tsx (UI) or route.ts (API).
layout.tsxwraps child pages and persists across navigation;loading.tsxis the Suspense fallback;error.tsxis the error boundary;not-found.tsxshows 404s.[id]is a dynamic segment,[...slug]catch-all,(group)organises without affecting URLs,_folderis private.
In short: Server Components (default in the App Router) render on the server, can be async and access databases/secrets directly, and send no JavaScript to the browser.
- Client Components (
"use client") are hydrated in the browser and can use state, effects and event handlers. - Use server by default and client only for interactive parts.
In short: Static generation at build time (with generateStaticParams), Incremental Static Regeneration (time-based revalidate or on-demand revalidatePath/Tag), dynamic server rendering per request, streaming with Suspense, Partial Prerendering/Cache Components (static shell + dynamic holes), and client-side rendering inside Client Components.
- Choose per page/component based on how fresh and personalised the data must be.
In short: Async functions marked "use server" that run on the server and can be called from forms (<form action={fn}>) or client code, used for mutations without writing API routes;
- they integrate with revalidation and redirects and work without JavaScript.
- Careful: each action is effectively a public HTTP endpoint — always authenticate, authorise and validate input inside it, and don't return sensitive data.
In short: Only from server code — Server Components, Server Actions and route handlers on the Node.js runtime — using mssql (one shared connection pool kept on globalThis in development) or Prisma with the sqlserver provider;
- mark modules
import "server-only", keep credentials in environment variables, use parameterised queries, and keep the database close to the hosting region. - Alternatively call an ASP.NET Core API that owns the database.
In short: Code that runs before a request is routed — redirects, rewrites, authentication gates, A/B testing, adding headers, localisation — configured with a matcher.
- It should be fast and must not be the only security check; validate access again in pages, actions and route handlers.
In short: Pages render to full HTML on the server (static or dynamic), so crawlers see content immediately;
- the Metadata API and
generateMetadataset titles, descriptions, canonical URLs and Open Graph tags; - file conventions generate
sitemap.xml,robots.txtand OG images; next/imageandnext/fontimprove Core Web Vitals;- clean URLs from file routing.
In short: Pages Router uses pages/, getServerSideProps/getStaticProps, _app/_document and API routes; every component is a client component.
- App Router uses
app/, nested layouts, React Server Components, streaming, Server Actions, route handlers and the Metadata API, with fetch/caching integrated. - New projects use the App Router; both can coexist for incremental migration.
In short: Hydration attaches React's event handlers and state to server-rendered HTML in the browser.
- Errors happen when the client's first render differs from the server HTML — using
Date.now()/random values,window/localStorageduring render, locale-dependent formatting, invalid HTML nesting, or browser extensions modifying the DOM. - Fix by rendering client-only values in
useEffect, consistent formatting, orsuppressHydrationWarningfor intentional differences.
In short: Make it static or cached: use generateStaticParams + revalidate = 86400 (ISR) or cache the query function ("use cache" with a cache life / unstable_cache in older versions), and call revalidatePath("/products") or revalidateTag from the admin update action so changes appear immediately.
- Add proper indexes for the query, and keep only truly personalised parts (cart badge) dynamic.
In short: The route or fetch is statically generated or cached (build-time rendering, revalidate, "use cache", cached fetch).
- Trigger on-demand revalidation (
revalidatePath/revalidateTag/updateTag) after mutations, lower the revalidate interval, or make the route dynamic if it must always be fresh (reading cookies/headers orconnection()).
In short: Environment variables set in the Vercel project for the right environment;
- the database firewall allows Vercel's outbound IPs (or use Azure SQL with public access rules / private networking);
encrypt: trueand valid certificates (notrustServerCertificateagainst a misconfigured server);- the route runs on the Node.js runtime (not Edge);
- connection limits from many serverless instances (small pools);
- region latency.
next/link and <a>?In short: <Link> performs client-side navigation — it fetches only the new route's payload, keeps layouts mounted and prefetches linked routes in the viewport — so navigation is fast without full page reloads.
- A plain
<a>causes a full browser navigation. - Use
<Link>for internal links and<a>for external ones.
In short: Server-only variables in .env.local/hosting settings are read via process.env.X on the server.
- Variables prefixed
NEXT_PUBLIC_are inlined into client bundles at build time — never put secrets there. - Different files per environment (
.env.development,.env.production); validate them at startup (zod).