Loading...
Loading...
React for production. Routing, server rendering, and full-stack capabilities built in.
Module 12 · Path to Frameworks
Frameworks like React and Next.js build on JavaScript fundamentals. Node.js runs JavaScript on servers, npm manages packages, and build tools prepare code for production. This module bridges vanilla JS to the modern ecosystem.
Learn Introduction to Next.js in JavaScript — covering Why Next.js, App Router, Server Components, Data Fetching with interactive visual examples and step-by-step explanations.
Vanilla JavaScript teaches you how the language works. Frameworks like React teach you how teams ship user interfaces at scale. This module bridges the gap — showing how the fundamentals you have learned map directly to React components, Node.js servers, and npm workflows.
You do not need to pick a framework on day one, but understanding how JavaScript powers React, Next.js, and Node.js makes every future tutorial easier to follow.
Understanding introduction to next.js is essential for every JavaScript developer. It shows up in frontend UI code, backend APIs, and framework internals — and getting it wrong leads to bugs that are hard to trace. This chapter builds intuition with visuals so the behavior sticks.
React is a library. Next.js is the framework that makes it production-ready.
// React alone gives you: // - Components and state management // - Virtual DOM diffing // ...and that's it. You still need: // - Routing (which page to show) // - Server rendering (SEO, performance) // - Data fetching patterns // - Code splitting // - Image optimization // - Deployment pipeline // Next.js gives you ALL of that, pre-configured: // ✓ File-based routing (folders = URLs) // ✓ Server-side rendering (SSR) + static generation (SSG) // ✓ Server Components (less JS shipped to browser) // ✓ API routes (full-stack in one project) // ✓ Image optimization (next/image) // ✓ Font optimization (next/font) // ✓ Built-in TypeScript support // ✓ Middleware, redirects, rewrites // ✓ One-command deployment (Vercel) // Create a Next.js project: // $ pnpm create next-app my-app // $ cd my-app && pnpm dev // This site (visualjs.in) is built with Next.js!
Folders become URLs. Files become pages.
// File-based routing: // app/ // ├── page.tsx → / // ├── about/ // │ └── page.tsx → /about // ├── blog/ // │ ├── page.tsx → /blog // │ └── [slug]/ // │ └── page.tsx → /blog/my-first-post // └── layout.tsx → wraps ALL pages // page.tsx — the page component (required for route to exist): export default function HomePage() { return <h1>Welcome to my site</h1>; } // layout.tsx — shared wrapper (header, footer, providers): export default function RootLayout({ children }) { return ( <html lang="en"> <body> <nav>...</nav> {children} {/* page content goes here */} <footer>...</footer> </body> </html> ); } // Dynamic routes — [param] folder: // app/blog/[slug]/page.tsx export default async function BlogPost({ params }) { const { slug } = await params; // slug = "my-first-post" for /blog/my-first-post const post = await getPost(slug); return <article>{post.content}</article>; }
Create a folder → it becomes a URL. Add page.tsx → it becomes a route. Dynamic segments use [brackets].
Components that run on the server. Zero JavaScript sent to the browser.
// In Next.js App Router, ALL components are Server Components by default. // They run on the server and send HTML to the browser. // Server Component (default — no directive needed): async function UserProfile({ userId }) { // This runs on the server — direct database access! const user = await db.query("SELECT * FROM users WHERE id = $1", [userId]); return ( <div> <h1>{user.name}</h1> <p>{user.email}</p> </div> ); } // ✓ Can use async/await directly // ✓ Can access databases, file system, secrets // ✓ Zero JS sent to browser for this component // ✗ Cannot use useState, useEffect, onClick // Client Component — add "use client" directive: "use client"; import { useState } from "react"; function LikeButton() { const [likes, setLikes] = useState(0); return ( <button onClick={() => setLikes(likes + 1)}> ♥ {likes} </button> ); } // ✓ Can use state, effects, event handlers // ✓ Can use browser APIs // ✗ Cannot be async // ✗ JS is sent to browser (adds to bundle) // The pattern: Server Components for data + layout, // Client Components for interactivity (keep them small!) // page.tsx (Server) → fetches data, renders layout // └── LikeButton (Client) → handles clicks // └── CommentForm (Client) → handles input
Fetch data where you need it — directly in components.
// Fetch data in Server Components (simplest pattern): async function ProductPage({ params }) { const { id } = await params; const product = await fetch( "https://api.example.com/products/" + id ).then(r => r.json()); return ( <div> <h1>{product.name}</h1> <p>{product.price}</p> </div> ); } // Parallel data fetching: async function Dashboard() { // These run in parallel (not waterfall): const [user, posts, stats] = await Promise.all([ getUser(), getPosts(), getStats(), ]); return ( <div> <UserCard user={user} /> <PostList posts={posts} /> <StatsPanel stats={stats} /> </div> ); } // Server Actions — mutations from the client: // app/actions.ts: "use server"; async function addTodo(formData) { const text = formData.get("text"); await db.insert({ text, done: false }); revalidatePath("/todos"); // refresh the page data } // In a Client Component: function TodoForm() { return ( <form action={addTodo}> <input name="text" placeholder="New todo..." /> <button type="submit">Add</button> </form> ); } // The form submits to the server action — no API route needed! // Works with and without JavaScript (progressive enhancement)
Frontend + backend in one project. Deploy anywhere.
// Next.js is full-stack: // - React pages (frontend) // - Server Components (server-rendered UI) // - Server Actions (mutations) // - Route Handlers (REST API endpoints) // - Middleware (auth, redirects) // All in ONE project, ONE deployment. // Route Handler (API endpoint): // app/api/users/route.ts: import { NextResponse } from "next/server"; export async function GET() { const users = await db.query("SELECT * FROM users"); return NextResponse.json(users); } export async function POST(request) { const body = await request.json(); const user = await db.insert(body); return NextResponse.json(user, { status: 201 }); } // → GET /api/users, POST /api/users // Middleware (runs before every request): // middleware.ts (in project root): import { NextResponse } from "next/server"; export function middleware(request) { const token = request.cookies.get("session"); if (!token && request.nextUrl.pathname.startsWith("/dashboard")) { return NextResponse.redirect(new URL("/login", request.url)); } } export const config = { matcher: ["/dashboard/:path*"], }; // Deployment: // $ pnpm build → optimized production build // Deploy to: Vercel (zero-config), AWS, Docker, anywhere Node runs // Vercel: git push → auto-deploys in ~30 seconds // What you've learned in this course prepares you for Next.js: // ✓ JavaScript fundamentals → write React components // ✓ DOM + events → understand what React abstracts // ✓ Async/await → data fetching in components // ✓ ES modules → imports/exports everywhere // ✓ Design patterns → component architecture // ✓ Build tools → understand the pipeline // You're ready. Go build something.
Common questions about introduction to next.js.