From f48b8a68eeff35c30a33ed164c08f80c3f153bce Mon Sep 17 00:00:00 2001 From: satyajeet1152000 Date: Tue, 11 Aug 2026 15:10:15 +0530 Subject: [PATCH 01/36] Create foundational content for Next.js, including an introduction, project setup, routing, web rendering, and SEO best practices. --- .../01.nextjs_introduction.md | 198 ++++ .../02.project_setup_and_structure.md | 948 ++++++++++++++++++ .../03.routing_and_navigation.md | 344 +++++++ .../04.web_rendering.md | 611 +++++++++++ .../05.metadata_&_seo.md | 844 ++++++++++++++++ 5 files changed, 2945 insertions(+) create mode 100644 s3_full_stack_using_nextjs/01.nextjs_introduction.md create mode 100644 s3_full_stack_using_nextjs/02.project_setup_and_structure.md create mode 100644 s3_full_stack_using_nextjs/03.routing_and_navigation.md create mode 100644 s3_full_stack_using_nextjs/04.web_rendering.md create mode 100644 s3_full_stack_using_nextjs/05.metadata_&_seo.md diff --git a/s3_full_stack_using_nextjs/01.nextjs_introduction.md b/s3_full_stack_using_nextjs/01.nextjs_introduction.md new file mode 100644 index 00000000..1166e888 --- /dev/null +++ b/s3_full_stack_using_nextjs/01.nextjs_introduction.md @@ -0,0 +1,198 @@ +# 01 Introduction to Next.js + +## What is Next.js? + +**Next.js** is a powerful, open-source full stack framework built on top of **React** for creating production-ready web applications. Developed and maintained by Vercel. + +React focuses mainly on building user interfaces. Next.js provides a framework around React with conventions and features for building complete web applications. + +Next.js is designed to make web development faster, more scalable, and SEO-friendly, while maintaining React’s flexibility for building dynamic user interfaces. + +## Why Next.js? + +A React application usually needs additional tools and decisions for things such as routing, rendering, server-side code, and application structure. + +Next.js provides framework-level solutions for many of these requirements. + +### Main reasons to use Next.js + +- File-based routing +- Multiple rendering strategies +- Server and Client Components +- Server-side capabilities +- SEO-friendly rendering options +- Data fetching and caching +- Image and font optimization +- Error and loading UI +- Production-oriented tooling + +--- + +### Key Features of Next.js +1. **File-Based Routing**: + - Next.js uses a file-system-based router. Files in the `pages/` or `app/` directory (depending on the version) automatically become routes. + - Example: `pages/about.js` maps to `/about`. +2. **Multiple Rendering Strategies**: + - **CSR** — Client-Side Rendering + - **SSR** — Server-Side Rendering + - **SSG** — Static Site Generation + - **ISR** — Incremental Static Regeneration +3. **Server and Client Components** + The App Router supports: + - Server Components + - Client Components + + These determine where component code can execute. +4. **API Routes**: + - Next.js allows you to create backend API endpoints within the same project using the `pages/api/` or `app/api/` directory. + - Useful for full-stack apps without needing a separate backend server. +5. **Built-in Optimizations**: + - **Image Optimization**: The `next/image` component optimizes images for faster loading and responsive sizes. + - **Font Optimization**: Automatic font loading and subsetting for better performance. + - **Static Asset Handling**: Efficient handling of CSS, images, and other assets. + - **Automatic Code Splitting**: Next.js splits JavaScript bundles by page, ensuring only the necessary code is loaded, improving performance. +6. **SEO and Metadata**: + - Next.js provides built-in SEO support through Metadata API, allowing you to set page titles, descriptions, Open Graph tags, and other meta information. + - It also supports dynamic metadata, sitemap, robots.txt, and structured data, helping search engines crawl and rank your website better. +7. **TypeScript Support**: + - Built-in TypeScript support with zero configuration, making it easy to write type-safe code. +8. **Error and Loading UI** + - The Next.js App Router provides special files for handling different UI states: + - **`loading.tsx`** – Displays a loading UI while a route is loading. + - **`error.tsx`** – Displays a fallback UI when an error occurs. + - **`not-found.tsx`** – Displays a custom 404 UI when a page or resource is not found. +9. **Internationalization (i18n)**: + - Built-in support for multi-language sites with domain or subpath routing. +10. **Middleware**: + - Next.js middleware allows you to run code before a request is completed, enabling features like authentication, redirects, or A/B testing. +11. **Vercel Integration**: + - Seamless deployment and scaling with Vercel, though Next.js works with other hosting platforms like Netlify or AWS. +12. **Developer Experience**: + - Features like Fast Refresh, hot module replacement, and an intuitive CLI improve development speed. + +--- + +### How Next.js Differs from React + +**React** is a JavaScript **library** for building user interfaces, focusing on component-based UI development. **Next.js** is a **framework** built on top of React, adding structure and features to make it easier to build complete web applications. Here’s how they differ: + +| **Aspect** | **React** | **Next.js** | +| --- | --- | --- | +| **Type** | Library for UI components | Framework built on React | +| **Rendering** | Client-side rendering (CSR) by default | Supports CSR, SSR, SSG, and ISR | +| **Routing** | Requires external libraries (e.g., React Router) | Built-in file-based routing (`pages/` or `app/` directory) | +| **SEO** | Poor for CSR; requires manual SSR setup | SEO-friendly with SSR and SSG | +| **Setup Complexity** | Requires manual configuration (e.g., Webpack, Babel, routing) | Minimal setup with built-in tools and conventions | +| **API Routes** | No built-in API support; needs separate backend | Built-in API routes for full-stack development | +| **Performance** | Manual optimization needed for code splitting, lazy loading | Automatic code splitting, image optimization, and performance features | +| **State Management** | Relies on libraries like Redux, Context, or Zustand | Same as React, but server components can reduce client-side state needs | +| **Use Case** | Single-page apps (SPAs), dynamic UIs, or highly custom projects | Full-stack apps, SEO-heavy sites, e-commerce, blogs, or static sites | +| **Learning Curve** | Moderate; requires learning additional tools for full app development | Slightly steeper due to framework conventions but simplifies many tasks | +| **Deployment** | Requires custom setup (e.g., on Node.js, Netlify) | Simplified with Vercel or other platforms; optimized for static hosting | + +**When to Use**: + +- **React**: Choose for SPAs, client-heavy apps (e.g., dashboards), or when you need maximum flexibility and control over the stack. Example: A real-time chat app. +- **Next.js**: Choose for SEO-critical apps, static sites, e-commerce platforms, or full-stack apps where performance and developer experience are priorities. Example: A blog or online store. + +--- + +### How Next.js Differs from Angular + +**Angular** is a full-fledged **framework** developed by Google, built with TypeScript for large-scale, enterprise-level applications. It’s a comprehensive solution with its own ecosystem, differing significantly from Next.js and React. Here’s a comparison: + +| **Aspect** | **Next.js** | **Angular** | +| --- | --- | --- | +| **Base Technology** | Built on React (JavaScript/TypeScript) | Standalone framework (TypeScript-based) | +| **Rendering** | Supports CSR, SSR, SSG, and ISR | Primarily CSR; SSR possible with Angular Universal but more complex | +| **Routing** | File-based routing (simple, intuitive) | Component-based routing with explicit configuration | +| **Learning Curve** | Moderate; easier for React developers | Steeper; requires learning Angular-specific concepts (e.g., modules, DI) | +| **TypeScript** | Optional, but first-class support | Mandatory; deeply integrated | +| **State Management** | Uses React tools (Redux, Context, Zustand) or server components | Built-in services, RxJS, or NgRx for complex state management | +| **Ecosystem** | Leverages React ecosystem; lightweight and flexible | Comprehensive, opinionated ecosystem with built-in tools | +| **Performance** | Optimized for web with automatic code splitting, image optimization | Fast, but heavier client-side bundle; SSR setup is less seamless | +| **SEO** | Excellent due to SSR and SSG | Decent with Universal, but requires extra setup | +| **Dependency Injection** | Not built-in; relies on React patterns | Built-in DI system for managing services and dependencies | +| **Use Case** | Web apps, static sites, e-commerce, blogs, full-stack apps | Enterprise apps, complex SPAs, or apps needing strict structure | +| **Community & Libraries** | Large React community; many lightweight libraries | Smaller but dedicated community; fewer third-party libraries | +| **Bundle Size** | Smaller, especially with SSG and server components | Larger due to comprehensive framework features | +| **Developer Experience** | Fast setup, hot reload, Vercel integration | More setup for complex apps; powerful CLI but steeper learning curve | + +**When to Use**: + +- **Next.js**: Ideal for web developers building SEO-friendly, performance-optimized apps with React’s flexibility. Great for startups, e-commerce, blogs, or full-stack projects. Example: A marketing site with dynamic content. +- **Angular**: Best for enterprise-grade applications requiring strict structure, TypeScript, and built-in tools for large teams. Example: A corporate CRM or admin portal. + +--- + +### Key Differences Summary + +- **Next.js vs. React**: + - Next.js is a framework that extends React with server-side capabilities, routing, and optimizations. React is a library focused on UI components, requiring more manual setup for full apps. + - Next.js simplifies building production-ready apps; React is better for custom, client-side-heavy projects. +- **Next.js vs. Angular**: + - Next.js is lighter, more flexible, and React-based, with a focus on web performance and SEO. Angular is a heavier, opinionated framework for structured, enterprise apps. + - Next.js has a simpler learning curve for React developers; Angular requires learning its unique ecosystem (RxJS, modules, DI). + +--- + +### Example Use Cases + +- **Next.js**: E-commerce platforms (Shopify-like), blogs (like Medium), landing pages, or full-stack apps with API routes. +- **React**: Real-time dashboards, SPAs like a chat app, or projects needing custom build setups. +- **Angular**: Enterprise apps like banking systems, CRMs, or large-scale internal tools. + +--- + +### Practical Example: Next.js vs. React + +**React (Basic SPA)**: + +```jsx +// src/App.js +import { useState } from 'react'; +import { BrowserRouter, Route, Routes } from 'react-router-dom'; + +function Home() { + const [data, setData] = useState(null); + return
Home Page
; +} + +function App() { + return ( + + + } /> + + + ); +} + +``` + +**Next.js (SSR/SSG)**: + +```jsx +// pages/index.js +export async function getServerSideProps() { + const data = await fetch('').then(res => res.json()); + return { props: { data } }; +} + +export default function Home({ data }) { + return
Data from server: {data.title}
; +} + +``` + +- Next.js handles routing and SSR automatically; React requires manual setup. + +--- + +### Conclusion + +- **Next.js** is the go-to choice for most modern web projects needing SEO, performance, or full-stack capabilities with React’s simplicity. It’s ideal for developers who want a streamlined, production-ready framework. +- **React** suits projects where client-side rendering and maximum flexibility are priorities, but it requires more setup for advanced features. +- **Angular** is best for large, structured, enterprise apps where TypeScript and a comprehensive framework are beneficial, but it’s heavier and less flexible than Next.js. + +If you’re starting a new project, **Next.js** is often the best choice for its balance of simplicity, performance, and scalability, especially for web apps. Use **React** for SPAs or custom setups, and **Angular** for enterprise-scale applications with complex requirements. diff --git a/s3_full_stack_using_nextjs/02.project_setup_and_structure.md b/s3_full_stack_using_nextjs/02.project_setup_and_structure.md new file mode 100644 index 00000000..f86f2c8d --- /dev/null +++ b/s3_full_stack_using_nextjs/02.project_setup_and_structure.md @@ -0,0 +1,948 @@ +# 02. Next.js Project Setup & Project Structure + +Before creating a Next.js project, it is important to understand the two routing systems available in Next.js: + +- **Pages Router** +- **App Router** + +Both can be used to build Next.js applications, but they follow different conventions and provide different features. + +--- + +# 1. Pages Router vs App Router + +### Pages Router + +The **Pages Router** is the traditional Next.js routing system. + +It uses the `pages/` directory to define routes. + +### App Router + +The **App Router** is the newer routing system introduced in Next.js 13. + +It uses the `app/` directory and provides the modern Next.js application architecture. + +--- + +# 2. Pages Router + +The Pages Router uses the `pages/` directory to create routes. + +Example: + +```text +pages/ +├── index.tsx +├── about.tsx +└── products/ + └── index.tsx +``` + +Routes: + +```text +/ → pages/index.tsx +/about → pages/about.tsx +/products → pages/products/index.tsx +``` + +The filename and folder structure determine the URL. + +## Example + +```tsx +// pages/about.tsx + +export default function About() { + return

About Page

; +} +``` + +Visiting: + +```text +/about +``` + +renders the `About` component. + +--- + +## Pages Router Features + +The Pages Router provides: + +- File-based routing +- Dynamic routes +- API Routes +- `getServerSideProps` +- `getStaticProps` +- `getStaticPaths` +- `_app.tsx` +- `_document.tsx` +- Custom 404 pages +- Custom error pages + +Example SSR: + +```tsx +export async function getServerSideProps() { + const response = await fetch("https://api.example.com/products"); + + const products = await response.json(); + + return { + props: { + products, + }, + }; +} +``` + +`getServerSideProps` is a **Pages Router API**. + +--- + +## Advantages of Pages Router + +- **Mature and Stable:** The Pages Router has been available for many years and is used by many existing production applications. +- **Important for Existing Projects:** Many existing Next.js applications use the Pages Router. Understanding it is useful when: + - Joining an existing project + - Maintaining an older application + - Working with a legacy codebase + - Migrating an application to the App Router + +- **Explicit Data Fetching APIs:** The Pages Router provides APIs such as: + + ```text + getServerSideProps + getStaticProps + getStaticPaths + ``` + + These make traditional SSR and SSG concepts explicit. + +--- + +## Disadvantages of Pages Router + +The Pages Router does not provide the newer App Router architecture. +It does not provide the same built-in model for: + +- Server Components +- Nested layouts +- Route-level `loading.tsx` +- Route-level `error.tsx` +- Route Handlers +- App Router streaming patterns + +For new applications, the App Router is generally the preferred choice. + +## When Should You Use Pages Router? + +Use the Pages Router when: + +- You are working on an existing Pages Router project. +- The project already has a large `pages/` codebase. +- You are maintaining an older Next.js application. +- You are gradually migrating an existing application. +- The existing architecture already works well. + +You do not need to migrate an existing application simply because the App Router exists. + +--- + +# 3. App Router + +The App Router uses the `app/` directory. + +Example: + +```text +app/ +├── page.tsx +├── about/ +│ └── page.tsx +└── products/ + └── page.tsx +``` + +Routes: + +```text +/ → app/page.tsx +/about → app/about/page.tsx +/products → app/products/page.tsx +``` + +A major difference is that **a folder alone does not automatically create a route**. + +A route is created when the folder contains: + +```text +page.tsx +``` + +For example: + +```text +app/ +└── about/ + └── page.tsx +``` + +creates: + +```text +/about +``` + +But: + +```text +app/ +└── components/ + └── Navbar.tsx +``` + +does not create `/components`. + +--- + +## App Router Features + +The App Router provides a modern application architecture with features such as: + +- Server Components +- Client Components +- Nested layouts +- `loading.tsx` +- `error.tsx` +- `not-found.tsx` +- Route Groups +- Route Handlers +- Streaming +- Modern data-fetching and caching patterns + +These concepts will be covered in their respective topics. + +--- + +## Advantages of App Router + +- **Server Components:** In the App Router, components are Server Components by default. Client-side features can be enabled with: + + ```tsx + "use client"; + ``` + + This allows a component to use features such as: + - `useState` + - `useEffect` + - Event handlers + - Browser APIs + +- **Nested Layouts:** Layouts can be shared between multiple pages. + + ```text + app/ + ├── layout.tsx + ├── dashboard/ + │ ├── layout.tsx + │ ├── page.tsx + │ └── settings/ + │ └── page.tsx + ``` + + A dashboard layout can remain shared while navigating between dashboard pages. + +- **Built-in Loading and Error UI:** The App Router provides special files such as: + + ```text + loading.tsx + error.tsx + not-found.tsx + ``` + + These make route-level loading, error, and not-found UI easier to organize. + +- **Route Handlers:** The App Router provides Route Handlers for server endpoints. + + ```text + app/ + └── api/ + └── products/ + └── route.ts + ``` + + ```ts + export async function GET() { + return Response.json({ + message: "Products API", + }); + } + ``` + + Endpoint: + + ```text + GET /api/products + ``` + +--- + +## Disadvantages of App Router + +The App Router introduces more concepts than the basic Pages Router. + +Developers need to understand: + +- Server Components +- Client Components +- Layouts +- Data fetching +- Caching +- Revalidation +- Loading UI +- Error boundaries +- Streaming + +Therefore, the initial learning curve can be higher. + +## When Should You Use App Router? + +Use the App Router when: + +- Starting a new Next.js application. +- You want the modern Next.js architecture. +- You want to use Server Components. +- You need nested layouts. +- You want route-level loading and error UI. +- You want modern data-fetching and caching patterns. + +For **new projects, App Router is the recommended choice**. + +--- + +# 4. Can Both Routers Exist in One Project? + +Yes. + +A Next.js project can contain both: + +```text +project/ +├── app/ +└── pages/ +``` + +This can be useful during migration from the Pages Router to the App Router. + +[How to migrate from Pages to the App Router](https://nextjs.org/docs/app/guides/migrating/app-router-migration) + +However, avoid mixing them unnecessarily. + +For a new project, it is usually simpler to use the App Router. + +--- + +# 5. Pages Router Project Structure + +This example shows a typical layout **without** `src/`. Section 14 explains how to wrap the same folders inside `src/` when using that convention. + +A typical Pages Router project can look like: + +```text +my-next-app/ +│ +├── pages/ +│ ├── index.tsx +│ ├── about.tsx +│ │ +│ ├── products/ +│ │ ├── index.tsx +│ │ └── [id].tsx +│ │ +│ ├── 404.tsx +│ ├── _app.tsx +│ ├── _document.tsx +│ │ +│ └── api/ +│ └── products.ts +│ +├── public/ +│ ├── images/ +│ └── logo.png +│ +├── styles/ +│ └── globals.css +│ +├── components/ +│ ├── Navbar.tsx +│ └── ProductCard.tsx +│ +├── next.config.ts +├── package.json +├── tsconfig.json +└── .env.local +``` + +- **`pages/`**: This directory contains application routes. + + ```text + pages/ + ├── index.tsx + ├── about.tsx + └── products/ + ├── index.tsx + └── [id].tsx + ``` + + Routes: + + ```text + / → pages/index.tsx + /about → pages/about.tsx + /products → pages/products/index.tsx + /products/123 → pages/products/[id].tsx + ``` + +- **`pages/api/`:** The Pages Router uses API Routes inside: + + ```text + pages/api/ + ``` + + Example: + + ```text + pages/ + └── api/ + └── products.ts + ``` + + ```ts + export default function handler(req, res) { + res.status(200).json({ + message: "Products API", + }); + } + ``` + + Endpoint: + + ```text + GET /api/products + ``` + +- **`_app.tsx`:** Used to customize the top-level application component. + + Common uses include: + - Global CSS + - Shared providers + - Global state providers + - Application-level configuration + +- **`_document.tsx`:** Allows customization of the document structure. It should not be used for normal page-level UI. +- **`404.tsx`:** Provides a custom 404 page. +- **`styles/globals.css`:** A common location for global styles in Pages Router projects. Global styles are typically imported in `_app.tsx`. In the App Router, global styles usually live in `app/globals.css` instead (see section 13). + +--- + +# 6. App Router Project Structure + +This example shows a typical layout **without** `src/`. Section 14 explains how to wrap the same folders inside `src/` when using that convention. + +A typical App Router project can look like: + +```text +my-next-app/ +│ +├── app/ +│ ├── layout.tsx +│ ├── page.tsx +│ ├── globals.css +│ │ +│ ├── about/ +│ │ └── page.tsx +│ │ +│ ├── products/ +│ │ ├── page.tsx +│ │ └── [id]/ +│ │ └── page.tsx +│ │ +│ ├── dashboard/ +│ │ ├── layout.tsx +│ │ ├── page.tsx +│ │ └── settings/ +│ │ └── page.tsx +│ │ +│ ├── api/ +│ │ └── products/ +│ │ └── route.ts +│ │ +│ ├── loading.tsx +│ ├── error.tsx +│ └── not-found.tsx +│ +├── components/ +│ ├── Navbar.tsx +│ └── ProductCard.tsx +│ +├── public/ +│ ├── images/ +│ └── logo.png +│ +├── next.config.ts +├── package.json +├── tsconfig.json +└── .env.local +``` + +--- + +- **`app/`:** This directory contains routes and route-specific files. Unlike the Pages Router, a folder alone does not create a route. + + A route requires: + + ```text + page.tsx + ``` + + Example: + + ```text + app/ + └── about/ + └── page.tsx + ``` + + creates: + + ```text + /about + ``` + +- **`page.tsx`:** Defines the UI for a route. +- **`globals.css`:** Holds global styles for the application. Imported in the root `layout.tsx`. +- **`layout.tsx`:** A layout provides shared UI around pages. + + ```text + app/ + ├── layout.tsx + ├── page.tsx + └── about/ + └── page.tsx + ``` + + Example: + + ```tsx + export default function RootLayout({ + children, + }: { + children: React.ReactNode; + }) { + return ( + + +
Navbar
+ + {children} + +
Footer
+ + + ); + } + ``` + + Layouts can be nested. + + ```text + app/ + ├── layout.tsx + └── dashboard/ + ├── layout.tsx + └── page.tsx + ``` + + The dashboard layout applies to the dashboard route and its child routes. + +- **`loading.tsx`:** This file defines loading UI for a route segment. + +- **`error.tsx`:** This file provides an error UI for a route segment. It must be a Client Component. + +- **`not-found.tsx`:** This file provides UI for not-found situations. +- **Route Handlers:** Route Handlers provide server endpoints in the App Router. + + ```text + app/ + └── api/ + └── products/ + └── route.ts + ``` + + ```ts + export async function GET() { + return Response.json({ + message: "Products API", + }); + } + ``` + + Endpoint: + + ```text + GET /api/products + ``` + +--- + +# 7. Shared Project Folders + +Next.js projects often use the same supporting folders regardless of whether the App Router or Pages Router is chosen. + +## `src/` (recommended) + +Keeping application source code inside `src/` separates it from configuration files at the project root. + +With the App Router: + +```text +my-next-app/ +│ +├── src/ +│ ├── app/ ← routes (App Router) +│ ├── components/ +│ ├── lib/ +│ └── hooks/ +│ +├── public/ +├── next.config.ts +├── package.json +└── tsconfig.json +``` + +With the Pages Router, replace `app/` with `pages/`: + +```text +my-next-app/ +│ +├── src/ +│ ├── pages/ ← routes (Pages Router) +│ ├── components/ +│ ├── lib/ +│ └── hooks/ +│ +├── public/ +├── next.config.ts +├── package.json +└── tsconfig.json +``` + +Using `src/` is optional. Sections 12 and 13 show structures without it for simplicity. When using `src/`, move `pages/` or `app/` (and `components/`, `lib/`, `hooks/`) inside it — for example, `src/pages/` instead of `pages/`. For medium or large projects, `src/` is a useful convention. + +## `components/` + +Reusable UI components that are not tied to a single route. + +```text +src/components/ +├── Navbar.tsx +├── Button.tsx +└── ProductCard.tsx +``` + +Route-specific UI can live inside `app/` or `pages/`, but shared components should stay here. + +## `lib/` + +Reusable application logic that is not UI. + +```text +src/lib/ +├── db.ts +├── auth.ts +└── api.ts +``` + +Typical uses: + +- Database clients +- API clients +- Utility functions +- Authentication helpers +- Server-side business utilities + +## `hooks/` + +Reusable custom React hooks. + +```text +src/hooks/ +├── useAuth.ts +└── useProducts.ts +``` + +## `public/` + +Static assets served from the site root. + +```text +public/ +├── logo.png +└── images/ + └── banner.jpg +``` + +These files are accessed as: + +```text +/logo.png +/images/banner.jpg +``` + +--- + +# 8. Configuration Files + +These files live at the project root (outside `src/`). + +## `next.config.ts` + +Used to customize Next.js behavior. + +Example — allow remote images from an external domain: + +```ts +const nextConfig = { + images: { + remotePatterns: [ + { + protocol: "https", + hostname: "images.example.com", + }, + ], + }, +}; + +export default nextConfig; +``` + +Add configuration only when the project actually needs it. Do not edit this file just because it exists. + +## `package.json` + +Contains project metadata, dependencies, dev dependencies, and scripts. + +Common scripts: + +```bash +npm run dev +npm run build +npm run start +``` + +## `tsconfig.json` + +TypeScript compiler configuration. Next.js can generate and update this file automatically when TypeScript is added to the project. + +## `.env.local` + +Local environment variables. This file should not be committed to version control. + +Example: + +```env +DATABASE_URL="..." +API_SECRET="..." +NEXT_PUBLIC_API_URL="https://api.example.com" +``` + +**Server-only** variables — no prefix: + +```ts +const databaseUrl = process.env.DATABASE_URL; +``` + +**Browser-exposed** variables require the `NEXT_PUBLIC_` prefix: + +```env +NEXT_PUBLIC_API_URL="https://api.example.com" +``` + +Never put secrets in `NEXT_PUBLIC_` variables. Anything with that prefix is bundled into client-side code. + +--- + +# 9. Organization Best Practices + +These principles apply to both routers. Use them together with the router-specific structures in sections 12 and 13. + +## Recommended starting structure + +For a new App Router project with `src/`: + +```text +my-next-app/ +│ +├── src/ +│ ├── app/ +│ │ ├── layout.tsx +│ │ ├── page.tsx +│ │ │ +│ │ ├── about/ +│ │ │ └── page.tsx +│ │ │ +│ │ └── products/ +│ │ ├── page.tsx +│ │ └── [id]/ +│ │ └── page.tsx +│ │ +│ ├── components/ +│ │ ├── Navbar.tsx +│ │ └── ProductCard.tsx +│ │ +│ ├── lib/ +│ │ └── api.ts +│ │ +│ └── hooks/ +│ └── useProducts.ts +│ +├── public/ +│ └── images/ +│ +├── next.config.ts +├── package.json +├── tsconfig.json +├── eslint.config.mjs +└── .env.local +``` + +This layout keeps three concerns separate: + +```text +src/ → application source code +public/ → static assets +root files/ → configuration +``` + +For the Pages Router, use the same layout but replace `src/app/` with `src/pages/` (see section 12). + +## Practices to follow + +| Practice | Why | +| ------------------------------------------- | ---------------------------------------------------------------------------------------- | +| Prefer **App Router** for new projects | Modern architecture, Server Components, nested layouts (see section 10) | +| Use **`src/`** for medium or large apps | Keeps source code separate from config at the root | +| Keep **shared components** in `components/` | Avoids cluttering route folders and makes reuse easier | +| Keep **business logic** in `lib/` | UI components stay focused; logic is easier to test and maintain | +| Keep **secrets server-side** | Use `.env.local` without `NEXT_PUBLIC_` for sensitive values | +| Add **config only when needed** | Unnecessary `next.config.ts` changes add complexity without benefit | +| Use **consistent naming** | `ProductCard.tsx`, `Navbar.tsx` for components; `useAuth.ts`, `useProducts.ts` for hooks | + +## Practices to avoid + +- Putting every component inside a route folder when it is reused elsewhere +- Mixing database or API logic directly inside UI components +- Exposing secrets with `NEXT_PUBLIC_`: + + ```env + # Do not do this + NEXT_PUBLIC_API_SECRET="..." + ``` + +- Modifying `next.config.ts` without a concrete requirement + +--- + +# 10. Creating a Next.js Project + +After understanding the routing systems and project structure, a new project can be created using: + +```bash +npx create-next-app@latest my-next-app +``` + +The CLI can ask about: + +- TypeScript +- ESLint +- Tailwind CSS +- `src/` directory +- App Router +- Import aliases (`@/*`) + +Answers depend on project needs. For learning and most new projects, a common starting point is: + +- TypeScript: **Yes** +- ESLint: **Yes** +- Tailwind CSS: optional +- `src/` directory: **Yes** (recommended for medium or large projects) +- App Router: **Yes** +- Import aliases: **Yes** + +Then start the project: + +```bash +cd my-next-app +npm run dev +``` + +The development server will normally be available at: + +```text +http://localhost:3000 +``` + +--- + +# Summary + +Next.js provides two routing systems. Both can share supporting folders such as `components/`, `lib/`, and `hooks/` (see section 14). + +```text +Pages Router + ↓ +pages/ +``` + +and: + +```text +App Router + ↓ +app/ +``` + +### Pages Router + +The traditional Next.js routing system. + +Best suited for: + +- Existing applications +- Older codebases +- Maintenance work +- Gradual migrations + +### App Router + +The modern Next.js routing system. + +Provides: + +- Server Components +- Client Components +- Nested layouts +- Loading UI +- Error UI +- Not-found UI +- Route Handlers +- Modern data-fetching and caching patterns + +For **new applications, use the App Router**. + +The `src/` directory is **recommended as an organizational convention for larger projects, but it is not required by Next.js**. diff --git a/s3_full_stack_using_nextjs/03.routing_and_navigation.md b/s3_full_stack_using_nextjs/03.routing_and_navigation.md new file mode 100644 index 00000000..d390bdd4 --- /dev/null +++ b/s3_full_stack_using_nextjs/03.routing_and_navigation.md @@ -0,0 +1,344 @@ +# 03. Routing and Navigation + +This guide covers the routing features of Next.js, including: + +1. **File-Based Routing** (Static, Dynamic, and Nested Routes) +2. **Custom 404 and `_error.js` Pages** +3. **Linking Between Pages using `` and `useRouter`** + +--- + +# 1. Routes + +### Static Routes + +```text +app/ +├── page.tsx +├── about/ +│ └── page.tsx +└── contact/ + └── page.tsx +``` + +Routes: + +```text +/ → app/page.tsx +/about → app/about/page.tsx +/contact → app/contact/page.tsx +``` + +--- + +### Nested Routes + +Folders can be nested. + +```text +app/ +└── dashboard/ + ├── page.tsx + └── settings/ + └── page.tsx +``` + +Routes: + +```text +/dashboard +/dashboard/settings +``` + +Nested routes are useful for organizing related sections. + +--- + +### Dynamic Routes + +Use square brackets for dynamic URL segments. + +```text +app/ +└── products/ + └── [id]/ + └── page.tsx +``` + +This can match: + +```text +/products/1 +/products/25 +/products/100 +``` + +The exact `params` API can vary with the Next.js version, so follow the version used by your project. + +--- + +### Catch-All Routes + +Use: + +```text +[...slug] +``` + +to match multiple path segments. + +```text +app/ +└── docs/ + └── [...slug]/ + └── page.tsx +``` + +Examples: + +```text +/docs/react +/docs/react/hooks +/docs/react/hooks/use-state +``` + +--- + +### Optional Catch-All Routes + +Use: + +```text +[[...slug]] +``` + +to allow the segment to be optional. + +```text +app/ +└── docs/ + └── [[...slug]]/ + └── page.tsx +``` + +This can match: + +```text +/docs +/docs/react +/docs/react/hooks +``` + +--- + +### Route Groups + +Route groups use parentheses: + +```text +(auth) +``` + +Example: + +```text +app/ +├── (marketing)/ +│ ├── page.tsx +│ └── pricing/ +│ └── page.tsx +│ +└── (dashboard)/ + └── dashboard/ + └── page.tsx +``` + +The group name does **not** appear in the URL. + +```text +(marketing)/pricing/page.tsx + ↓ +/pricing +``` + +Route groups are useful for: + +- Organizing routes +- Applying different layouts +- Separating application sections + +--- + +# 2. Layouts and Nested Layouts + +A layout can wrap multiple pages. + +```text +app/ +├── layout.tsx +└── dashboard/ + ├── layout.tsx + ├── page.tsx + └── settings/ + └── page.tsx +``` + +The root layout wraps the whole application. + +The dashboard layout wraps the dashboard section. + +--- + +# 3. Navigation with `` + +Next.js provides a `Link` component for smooth, **client-side transitions** without full page reloads. + +```tsx +import Link from "next/link"; + +export default function Navbar() { + return ( + + ); +} +``` + +Add `` in `app/layout.js` so it appears on all pages. + +--- + +# 4. Programmatic Navigation + +Use `useRouter` when navigation happens because of an action. + +```tsx +"use client"; + +import { useRouter } from "next/navigation"; + +export default function LoginForm() { + const router = useRouter(); + + function handleLogin() { + // login logic + router.push("/dashboard"); + } + + return ; +} +``` + +Common methods: + +```ts +router.push("/dashboard"); +router.replace("/dashboard"); +router.back(); +router.refresh(); +``` + +--- + +# 5. Redirect + +For server-side redirects, Next.js provides: + +```tsx +import { redirect } from "next/navigation"; + +export default function Page() { + const isLoggedIn = false; + + if (!isLoggedIn) { + redirect("/login"); + } + + return

Dashboard

; +} +``` + +--- + +# 6. Not Found + +Use `notFound()` when requested data does not exist. + +```tsx +import { notFound } from "next/navigation"; + +export default async function ProductPage() { + const product = await getProduct(); + + if (!product) { + notFound(); + } + + return

{product.title}

; +} +``` + +Next.js then uses the nearest applicable: + +```text +not-found.tsx +``` + +--- + +# 7. Loading UI + +A route can have: + +```text +loading.tsx +``` + +Example: + +```text +app/ +└── products/ + ├── loading.tsx + └── page.tsx +``` + +```tsx +export default function Loading() { + return

Loading products...

; +} +``` + +This provides a loading UI while the route's content is being prepared. + +--- + +# 8. Error UI + +A route segment can have: + +```text +error.tsx +``` + +It must be a Client Component. + +```tsx +"use client"; + +export default function Error({ reset }: { reset: () => void }) { + return ( +
+

Something went wrong.

+ +
+ ); +} +``` + +`error.tsx` acts as an error boundary for its route segment. + +--- diff --git a/s3_full_stack_using_nextjs/04.web_rendering.md b/s3_full_stack_using_nextjs/04.web_rendering.md new file mode 100644 index 00000000..fd6601ee --- /dev/null +++ b/s3_full_stack_using_nextjs/04.web_rendering.md @@ -0,0 +1,611 @@ +# 04. Web Rendering in Next.js + +## What is Rendering? + +**Web rendering** refers to the process of generating and displaying a web page’s content in a browser. It involves transforming code (HTML, CSS, JavaScript) into a visible, interactive page. Rendering can happen on the **client side** (in the browser), the **server side**, or a combination of both, depending on the approach. The choice of rendering method significantly impacts **SEO**, **performance**, and **UX**, which are critical for modern web applications. + +Rendering methods determine: + +- **When and where** content is generated (client or server). +- **How quickly** the user sees meaningful content (affecting UX and performance). +- **How easily** search engines can crawl and index the content (affecting SEO). + +The main rendering approaches are **Client-Side Rendering (CSR)**, **Server-Side Rendering (SSR)**, **Static Site Generation (SSG)**, and **Incremental Static Regeneration (ISR)**. Each has distinct mechanics and trade-offs. + +The main rendering approaches discussed in these notes are: + +1. CSR — Client-Side Rendering +2. SSR — Server-Side Rendering +3. SSG — Static Site Generation +4. ISR — Incremental Static Regeneration + +--- + +# 1. CSR — Client-Side Rendering + +- **Definition**: In CSR, the browser downloads a minimal HTML file and uses JavaScript to fetch data and render the content dynamically in the browser. +- **How It Works**: + - The server sends a basic HTML skeleton (e.g., `
`) with a JavaScript bundle. + - The browser executes the JavaScript, fetches data (e.g., via API calls), and renders the UI. +- **Example Frameworks**: React (default with **Create React App**), Angular (default without Universal). + +```text +Browser + ↓ +Load JavaScript + ↓ +React runs + ↓ +Fetch data + ↓ +Render UI +``` + +Pages Router example: + +```tsx +// pages/store.tsx + +import { useEffect, useState } from "react"; + +export default function StorePage() { + const [products, setProducts] = useState([]); + + useEffect(() => { + fetch("https://fakestoreapi.com/products") + .then((res) => res.json()) + .then(setProducts); + }, []); + + return ( +
+ {products.map((product) => ( +
{product.title}
+ ))} +
+ ); +} +``` + +App Router example: + +```tsx +// app/store/page.tsx + +"use client"; + +import { useEffect, useState } from "react"; + +export default function StorePage() { + const [products, setProducts] = useState([]); + + useEffect(() => { + fetch("https://fakestoreapi.com/products") + .then((res) => res.json()) + .then(setProducts); + }, []); + + return ( +
+ {products.map((product) => ( +
{product.title}
+ ))} +
+ ); +} +``` + +> In the **Pages Router**, page components can use `useState` and `useEffect` directly. In the **App Router**, components are Server Components by default, so `"use client"` is required for client-side data fetching with hooks. + +- **Pros**: + - Fast navigation after initial load (JavaScript handles updates in the browser). + - Ideal for dynamic, interactive apps (e.g., dashboards, SPAs). + - Reduces server load since rendering happens client-side. +- **Cons**: + - **SEO**: Poor for SEO because crawlers may see only the minimal HTML unless they fully execute JavaScript (Googlebot can, but it’s slower; other bots may not). + - **Performance**: Slower **First Contentful Paint (FCP)** and **Time to Interactive (TTI)** due to JavaScript download and execution. + - **UX**: Users may see a blank screen or loading spinner until JavaScript loads, especially on slow networks or devices. + +--- + +# 2. SSR — Server-Side Rendering + +- **Definition**: In SSR, the server generates the full HTML for a page in response to a request and sends it to the browser, which displays it immediately. +- **How It Works**: + - The server fetches data, renders the React/Angular components into HTML, and sends the complete HTML to the client. + - The browser displays the HTML, then “hydrates” it with JavaScript to make it interactive. +- **Example Frameworks**: **Next.js** (Pages Router via `getServerSideProps`, App Router via async Server Components), **Angular Universal**, or custom React SSR setups. + +```text +User Request + ↓ +Next.js Server + ↓ +Fetch request-specific data + ↓ +Generate HTML + ↓ +Browser +``` + +Pages Router example: + +```tsx +// pages/index.tsx + +export async function getServerSideProps() { + const response = await fetch("https://api.example.com/data"); + + const data = await response.json(); + + return { + props: { + data, + }, + }; +} + +export default function Home({ data }) { + return

{data.title}

; +} +``` + +App Router example: + +```tsx +// app/page.tsx + +async function getData() { + const response = await fetch("https://api.example.com/data", { + cache: "no-store", + }); + + return response.json(); +} + +export default async function Home() { + const data = await getData(); + + return

{data.title}

; +} +``` + +> In the **Pages Router**, `getServerSideProps` runs on the server for every request and passes data as props. In the **App Router**, SSR happens when an async Server Component fetches with `cache: "no-store"`, so the page is rendered on every request. + +### Good use cases + +- User-specific pages +- Request-specific data +- Pages depending on cookies or authentication +- Data that must be generated at request time + +--- + +# 3. SSG — Static Site Generation + +- **Definition**: In SSG, pages are pre-rendered at **build time** into static HTML files, which are served to the client without further server processing. +- **How It Works**: + - During the build process, data is fetched, and HTML is generated for each page. + - The static HTML is hosted on a CDN or server and served directly to clients. +- **Example Frameworks**: **Next.js** (Pages Router via `getStaticProps`, App Router via async Server Components with static caching), **Gatsby**, **Hugo**. + +```text +Build / Static Generation + ↓ +Fetch data + ↓ +Generate result + ↓ +Deploy / cache + ↓ +Users +``` + +Pages Router example: + +```tsx +// pages/store.tsx + +export async function getStaticProps() { + const response = await fetch("https://fakestoreapi.com/products"); + + const products = await response.json(); + + return { + props: { + products, + }, + }; +} + +export default function StorePage({ products }) { + return ( +
+ {products.map((product) => ( +
{product.title}
+ ))} +
+ ); +} +``` + +App Router example: + +```tsx +// app/store/page.tsx + +async function getProducts() { + const response = await fetch("https://fakestoreapi.com/products", { + cache: "force-cache", + }); + + return response.json(); +} + +export default async function StorePage() { + const products = await getProducts(); + + return ( +
+ {products.map((product) => ( +
{product.title}
+ ))} +
+ ); +} +``` + +> In the **Pages Router**, `getStaticProps` runs at build time and passes data as props. In the **App Router**, static generation happens when a Server Component fetches with default static caching (`cache: "force-cache"`). The build output is static HTML served directly to users. + +- **Pros**: + - **SEO**: Excellent, as crawlers receive complete HTML, similar to SSR. + - **Performance**: Fastest delivery, as static files are served from CDNs with minimal server processing. + - **UX**: Instant page loads, improving user satisfaction. + - **Scalability**: Static files can be hosted on CDNs, reducing server costs. +- **Cons**: + - Not ideal for highly dynamic content (e.g., real-time data), as pages are built in advance. + - Rebuilding the entire site for content updates can be slow for large sites. + +--- + +# 4. ISR — Incremental Static Regeneration + +- **Definition**: ISR is an extension of SSG, allowing static pages to be updated incrementally after the initial build without rebuilding the entire site. +- **How It Works**: + - Pages are pre-rendered at build time (like SSG). + - A revalidation period (e.g., 60 seconds) is set, after which the server regenerates the page in the background when accessed, updating the static content. +- **Example Framework**: **Next.js** (Pages Router via `revalidate` in `getStaticProps`, App Router via `fetch` with `next.revalidate`). + +Pages Router example: + +```tsx +// pages/store.tsx + +export async function getStaticProps() { + const response = await fetch("https://fakestoreapi.com/products"); + + const products = await response.json(); + + return { + props: { + products, + }, + revalidate: 60, + }; +} + +export default function StorePage({ products }) { + return ( +
+ {products.map((product) => ( +
{product.title}
+ ))} +
+ ); +} +``` + +App Router example: + +```tsx +// app/store/page.tsx + +async function getProducts() { + const response = await fetch("https://fakestoreapi.com/products", { + next: { + revalidate: 60, + }, + }); + + return response.json(); +} + +export default async function StorePage() { + const products = await getProducts(); + + return ( +
+ {products.map((product) => ( +
{product.title}
+ ))} +
+ ); +} +``` + +> In the **Pages Router**, `revalidate: 60` inside `getStaticProps` sets the revalidation interval. In the **App Router**, the same behavior uses `next: { revalidate: 60 }` in `fetch`. Both serve static HTML first and regenerate the page in the background when accessed after the interval. + +- **Pros**: + - **SEO**: Same as SSG, with pre-rendered HTML for crawlers. + - **Performance**: Combines SSG’s speed with dynamic updates, served from CDNs. + - **UX**: Fast initial loads with fresh content, balancing static and dynamic needs. + - **Scalability**: Reduces build times for large sites by updating only accessed pages. +- **Cons**: + - Requires a server or hosting platform that supports ISR (e.g., Vercel). + - Slightly more complex than pure SSG for dynamic content. + +--- + +### Problems with Create React App (CRA) + +**Create React App (CRA)** is a popular tool for bootstrapping React applications, but it relies on **Client-Side Rendering (CSR)** by default, which introduces several challenges, especially for **SEO**, **performance**, and **UX**. Here are the key problems: + +1. **SEO Limitations**: + - **Problem**: CRA generates minimal HTML (e.g., `
`), and content is rendered via JavaScript in the browser. Search engine crawlers may not see the full content, especially non-Google bots with limited JavaScript rendering. + - **Impact**: Poor indexing, lower search rankings, and reduced organic traffic for content-heavy sites like blogs or e-commerce. + - **Example**: A CRA-based blog may not rank well because crawlers see only a loading state unless JavaScript is executed. +2. **Performance Issues**: + - **Problem**: Users must download and execute JavaScript before seeing content, leading to slower **First Contentful Paint (FCP)** and **Largest Contentful Paint (LCP)**, key **Core Web Vitals** metrics. + - **Impact**: Slow initial loads degrade user experience, especially on mobile devices or slow networks, increasing bounce rates. + - **Example**: A CRA app with a large JavaScript bundle may take seconds to display content, frustrating users. +3. **UX Challenges**: + - **Problem**: Users often see a blank screen or loading spinner until JavaScript loads and renders, creating a poor first impression. + - **Impact**: Higher bounce rates and lower user engagement, especially for users on low-end devices or unstable connections. + - **Example**: A CRA e-commerce site may show “Loading…” for several seconds, causing users to leave before seeing products. +4. **Complex SSR Setup**: + - **Problem**: CRA doesn’t support SSR out of the box. Adding SSR requires ejecting from CRA or using custom server setups (e.g., with Node.js and `react-dom/server`), which is complex and error-prone. + - **Impact**: Developers spend significant time configuring SSR, negating CRA’s simplicity. + - **Example**: Implementing SSR in CRA for an SEO-critical site requires extensive boilerplate, unlike Next.js’s built-in `getServerSideProps`. +5. **No Static Generation**: + - **Problem**: CRA lacks native support for SSG or ISR, meaning all content is rendered client-side, missing out on static hosting benefits like CDN delivery. + - **Impact**: Higher hosting costs and slower performance compared to static or hybrid approaches. + - **Example**: A CRA site can’t pre-render pages like a blog, requiring dynamic rendering for every request. +6. **Large Bundle Sizes**: + - **Problem**: CRA apps often produce large JavaScript bundles, especially for complex apps, slowing down load times. + - **Impact**: Poor performance metrics (e.g., TTI), affecting both SEO and UX. + - **Example**: A CRA dashboard with many dependencies may load slowly, impacting user retention. + +--- + +### Benefits of CSR, SSR, SSG, and ISR + +Each rendering strategy has different strengths for **SEO**, **performance**, and **UX**. **SSR**, **SSG**, and **ISR** (as offered by frameworks like **Next.js**) address many shortcomings of pure **CSR** approaches such as **Create React App**. + +1. **SEO Benefits**: + - **CSR**: Sends minimal HTML; crawlers may not see full content unless JavaScript is executed. Weaker for content-heavy or marketing sites. + - **SSR**: Delivers fully-rendered HTML to crawlers, ensuring content is immediately accessible and indexable. Ideal for dynamic content like user profiles or product pages. + - **SSG**: Pre-renders pages at build time, providing static HTML that crawlers can easily index. Perfect for content that doesn’t change often (e.g., blog posts, documentation). + - **ISR**: Combines SSG’s SEO benefits with dynamic updates, ensuring fresh content is indexed without rebuilding the entire site. + - **Example**: A Next.js blog using SSG ensures Googlebot indexes every post’s full content, boosting search rankings. +2. **Performance Benefits**: + - **CSR**: Slower **FCP** and **TTI** on first load because JavaScript must download and run first. After that, client-side navigation can feel fast. + - **SSR**: Improves **FCP** and **LCP** by sending pre-rendered HTML, reducing the time users wait to see content. JavaScript hydration handles interactivity afterward. + - **SSG**: Offers the fastest performance by serving static HTML from CDNs, minimizing server processing and latency. Ideal for global audiences. + - **ISR**: Maintains SSG’s speed while allowing incremental updates, ensuring performance for dynamic sites. + - **Example**: A Next.js e-commerce site using SSG loads product pages instantly via CDN, improving Core Web Vitals metrics. +3. **UX Benefits**: + - **CSR**: Users may see a blank screen or loading spinner until JavaScript loads, but it works well for highly interactive apps such as dashboards and chat tools after the initial load. + - **SSR**: Users see content faster, reducing the “blank screen” problem of CSR. This improves perceived performance and engagement. + - **SSG**: Instant page loads enhance user satisfaction, especially on mobile or slow networks. + - **ISR**: Balances static performance with fresh content, ensuring users always see up-to-date information without delays. + - **Example**: A news site using ISR delivers fast, pre-rendered articles that update in the background, keeping users engaged. +4. **Scalability**: + - **CSR**: Reduces server rendering load because most work happens in the browser after the initial JavaScript bundle is served. + - **SSG/ISR**: Static files can be served from CDNs, reducing server load and hosting costs compared to SSR or CSR. + - **SSR**: While more server-intensive than SSG, it’s scalable with proper infrastructure (e.g., Vercel, AWS). + - **Example**: A Next.js site with thousands of pages can use SSG or ISR to serve content efficiently without overwhelming servers. +5. **Simplified Development**: + - **CSR**: Simple to start with tools like **Create React App** or a `"use client"` component in the App Router using `useState` and `useEffect`. + - **SSR/SSG/ISR in Next.js**: Built-in support simplifies rendering setup compared to CRA’s manual SSR configuration. Pages Router uses `getServerSideProps`, `getStaticProps`, and `revalidate`; App Router uses async Server Components with `fetch` caching options. + - **Example**: A developer can enable SSR in Next.js with a single function, while CRA requires custom server logic. +6. **Cost Efficiency**: + - **CSR**: A static JavaScript bundle can be hosted cheaply, but dynamic or SEO-heavy apps may still need extra backend or SSR tooling. + - **SSG/ISR**: Static hosting (e.g., Vercel, Netlify) is cheaper than running servers for SSR, as static files require minimal resources. + - **SSR**: Can cost more than SSG/ISR because pages are generated on each request or through dynamic hosting. + - **Example**: A marketing site using SSG can be hosted on a CDN for pennies, unlike a CRA app requiring a Node.js server for dynamic rendering. + +--- + +### SEO, Performance, and UX Considerations + +1. **SEO Considerations**: + - **CSR (CRA)**: Poor SEO due to minimal initial HTML. Crawlers may miss content unless they render JavaScript, which is slow or unreliable for non-Google bots. Adding meta tags or structured data is manual and error-prone. + - **SSR**: Excellent for SEO, as crawlers receive complete HTML. Ideal for dynamic, frequently updated content (e.g., e-commerce, news). + - **SSG**: Also excellent for SEO, providing static HTML that’s instantly crawlable. Best for static or semi-static content (e.g., blogs, docs). + - **ISR**: Matches SSG’s SEO benefits while supporting dynamic updates, perfect for sites needing fresh content (e.g., product listings). + - **Best Practice**: Use Next.js’s SSR or SSG with proper meta tags (`next/head`), structured data, and sitemaps to maximize indexing and rankings. +2. **Performance Considerations**: + - **CSR (CRA)**: Slower initial loads due to JavaScript download and execution. Large bundles hurt **LCP** and **TTI**, impacting Core Web Vitals. + - **SSR**: Faster **FCP** and **LCP** by delivering HTML, but **TTI** may lag due to hydration. Server load can be a bottleneck without optimization. + - **SSG**: Fastest performance, as static HTML is served from CDNs, minimizing latency and server processing. Optimizes all Core Web Vitals. + - **ISR**: Matches SSG’s performance for initial loads while allowing dynamic updates, maintaining low latency. + - **Best Practice**: Use SSG or ISR for performance-critical sites; optimize SSR with caching (e.g., Vercel’s edge caching) for dynamic content. +3. **UX Considerations**: + - **CSR (CRA)**: Blank screens or loading spinners degrade UX, especially on slow networks. Users may bounce before content appears. + - **SSR**: Faster content display improves perceived performance, but hydration delays interactivity. Ensure lightweight JavaScript bundles. + - **SSG**: Instant loads create a smooth, responsive experience, ideal for content-heavy sites. + - **ISR**: Combines SSG’s fast loads with fresh content, ensuring users see up-to-date information without delays. + - **Best Practice**: Prioritize fast **FCP** and **LCP** with SSR/SSG; use Next.js’s `next/image` and lazy loading for media to enhance UX. + +--- + +### Practical Example: Next.js vs. CRA + +**CRA (CSR)**: + +```jsx +// src/App.js +import { useState, useEffect } from "react"; + +function App() { + const [data, setData] = useState(null); + useEffect(() => { + fetch("") + .then((res) => res.json()) + .then(setData); + }, []); + + if (!data) return
Loading...
; + return ( +
+

{data.title}

+

{data.content}

+
+ ); +} +``` + +- **SEO**: Crawlers see `
Loading...
`, potentially missing content. +- **Performance**: Slow **FCP** due to JavaScript dependency. +- **UX**: Users see “Loading…” until data loads, risking bounce. + +**Next.js (SSG)**: + +```jsx +// pages/index.js +import Head from "next/head"; + +export async function getStaticProps() { + const data = await fetch("").then((res) => + res.json(), + ); + return { props: { data }, revalidate: 60 }; +} + +export default function Home({ data }) { + return ( +
+ + {data.title} + + +

{data.title}

+

{data.content}

+
+ ); +} +``` + +- **SEO**: Crawlers see complete HTML, ensuring accurate indexing. +- **Performance**: Static HTML loads instantly from a CDN, optimizing Core Web Vitals. +- **UX**: Users see content immediately, improving engagement. + +--- + +### Choosing the Rendering Strategy + +Ask these questions. + +## Can the content be generated ahead of time? + +```text +YES + ↓ +SSG +``` + +Examples: + +```text +/about +/pricing +/docs +``` + +## Can it be generated ahead of time but needs periodic updates? + +```text +YES + ↓ +ISR +``` + +Examples: + +```text +/products/123 +/news +/blog +``` + +## Does the server need request-specific information? + +```text +YES + ↓ +SSR / Dynamic Rendering +``` + +Examples: + +```text +/account +/orders +/personalized-dashboard +``` + +## Is the page mainly a highly interactive browser application? + +```text +YES + ↓ +Client-side rendering / client-side data fetching +``` + +Examples: + +```text +/admin/analytics +/chat +/interactive-dashboard +``` + +--- + +# Real-World Example + +An e-commerce application might use: + +```text +/about + ↓ +SSG + +/products + ↓ +ISR + +/products/123 + ↓ +ISR + +/account + ↓ +SSR / dynamic rendering + +/cart + ↓ +Client-side interactivity +``` + +The same Next.js application can therefore use multiple approaches. + +--- + +# Rendering and SEO + +Server/static rendering can make important page content available in the initial HTML, which is useful for search engines. + +However: + +> Rendering strategy alone does not guarantee good SEO. diff --git a/s3_full_stack_using_nextjs/05.metadata_&_seo.md b/s3_full_stack_using_nextjs/05.metadata_&_seo.md new file mode 100644 index 00000000..ab6e07af --- /dev/null +++ b/s3_full_stack_using_nextjs/05.metadata_&_seo.md @@ -0,0 +1,844 @@ +# 5. SEO & Metadata in Next.js + +## Why SEO and Metadata Matter + +Imagine you built the best **Swiggy clone** — beautiful UI, fast, all restaurant menus updated daily. +But when people search _"best biryani in Mumbai"_ on Google, your site **does not appear anywhere**. + +This is where **SEO (Search Engine Optimization)** and **metadata** come in. + +Metadata tells **search engines, social platforms, AI assistants, and browsers**: + +- What your page is about +- Who it is for +- How to display it in search results and link previews + +If you share a **Zomato restaurant link** on WhatsApp and see a preview with the name, photo, and ratings — that is **Open Graph metadata** in action. + +In modern **Next.js (App Router)**, SEO is managed mainly through: + +- **Metadata API** — `metadata` and `generateMetadata` +- `robots.ts` — Crawler instructions +- `sitemap.ts` — URL discovery for search engines +- **Canonical URLs** — Preferred URL for duplicate variants +- **Structured data (JSON-LD)** — Rich results and clearer machine-readable content + +> For new projects, prefer the **App Router Metadata API**. The Pages Router `next/head` approach is still valid for older projects. + +--- + +## Types of SEO + +SEO is not one single task. Different channels need different optimization. + +| Type | Goal | Examples | +| ------------------- | -------------------------------------------------- | ------------------------------------------------------------------------------------------------ | +| **Traditional SEO** | Rank in search engines like Google and Bing | Titles, descriptions, headings, internal links, backlinks | +| **Technical SEO** | Make the site crawlable, fast, and well-structured | Sitemap, robots.txt, canonical URLs, Core Web Vitals, mobile-friendly layout | +| **On-page SEO** | Optimize individual page content | Useful headings, semantic HTML, alt text, clear URLs | +| **Local SEO** | Appear in location-based searches | Business name, address, maps, local keywords | +| **E-commerce SEO** | Rank product and category pages | Product titles, prices, availability, reviews, structured data | +| **Social SEO** | Control link previews on social/messaging apps | Open Graph, Twitter/X cards | +| **AI Search / GEO** | Help AI systems understand and cite your content | Clear content structure, FAQ sections, structured data, authoritative pages, llms.txt (optional) | + +### What is AI Search / GEO? + +**GEO (Generative Engine Optimization)** is optimization for **AI-powered search and assistants** such as ChatGPT search, Perplexity, Google AI Overviews, and Copilot. + +These systems still rely on crawlable, trustworthy content, but they also favor: + +- **Clear, factual, well-structured content** — short summaries, headings, bullet points +- **Authoritative pages** — about pages, docs, product pages with complete information +- **Structured data** — Schema.org JSON-LD for products, articles, FAQs, organizations +- **Canonical, stable URLs** — so AI systems can reference the correct source +- **Fast, accessible HTML** — important content available without heavy client-only rendering + +Optional: some teams add an `llms.txt` file (similar in idea to `robots.txt`) to describe which pages are most useful for AI systems to read. This is emerging practice, not a guaranteed ranking factor. + +> **Important:** Good traditional SEO still helps AI search. If Google cannot crawl and understand your page, AI systems usually struggle too. + +--- + +## How Search Engines Work + +A simplified model: + +```text +Crawling → Indexing → Ranking +``` + +1. **Crawling** — Bots discover URLs and fetch page content +2. **Indexing** — The search engine stores and analyzes page information +3. **Ranking** — Relevant pages are ordered for a search query + +Next.js helps by delivering **server-rendered or static HTML**, but: + +> **Next.js does not automatically guarantee good SEO.** Content, metadata, links, performance, and accessibility still matter. + +--- + +## Metadata API (App Router) + +In the App Router, metadata is defined in `layout.tsx` or `page.tsx` using the **Metadata API**. + +### Static metadata + +Use when page metadata is fixed. + +```tsx +// app/layout.tsx +import type { Metadata } from "next"; + +export const metadata: Metadata = { + metadataBase: new URL("https://codinggita.com"), + title: { + default: "CodingGita", + template: "%s | CodingGita", + }, + description: "Learn full stack development with practical projects.", + openGraph: { + title: "CodingGita", + description: "Learn full stack development with practical projects.", + url: "https://codinggita.com", + siteName: "CodingGita", + images: ["/og-default.jpg"], + type: "website", + }, + twitter: { + card: "summary_large_image", + title: "CodingGita", + description: "Learn full stack development with practical projects.", + images: ["/og-default.jpg"], + }, +}; + +export default function RootLayout({ + children, +}: { + children: React.ReactNode; +}) { + return ( + + {children} + + ); +} +``` + +Set `metadataBase` in the root layout so relative image and canonical URLs resolve correctly. + +### Dynamic metadata with `generateMetadata` + +Use when metadata depends on route params or fetched data (product pages, blog posts, restaurant pages). + +```tsx +// app/restaurants/[slug]/page.tsx +import type { Metadata } from "next"; + +type Props = { + params: Promise<{ slug: string }>; +}; + +async function getRestaurant(slug: string) { + const response = await fetch( + `https://api.example.com/restaurants/${slug}`, + { + next: { revalidate: 3600 }, + }, + ); + + return response.json(); +} + +export async function generateMetadata({ params }: Props): Promise { + const { slug } = await params; + const restaurant = await getRestaurant(slug); + + return { + title: `${restaurant.name} - ${restaurant.city}`, + description: restaurant.description, + alternates: { + canonical: `/restaurants/${slug}`, + }, + openGraph: { + title: `${restaurant.name} - Order Online`, + description: restaurant.description, + images: [restaurant.image], + url: `/restaurants/${slug}`, + type: "website", + }, + twitter: { + card: "summary_large_image", + title: restaurant.name, + description: restaurant.description, + images: [restaurant.image], + }, + }; +} + +export default async function RestaurantPage({ params }: Props) { + const { slug } = await params; + const restaurant = await getRestaurant(slug); + + return

{restaurant.name}

; +} +``` + +### Important Metadata API rules (Next.js 15+) + +- `metadata` and `generateMetadata` work only in **Server Components** +- Do **not** export both `metadata` and `generateMetadata` from the same route segment +- In **Next.js 15+**, `params` and `searchParams` are **Promises** — always `await` them +- Use `alternates.canonical` on dynamic routes to avoid duplicate URL issues +- `fetch` **inside** `generateMetadata` **is memoized** — the same request can be reused in the page component +- **File-based metadata** (`opengraph-image.tsx`, `icon.tsx`, `robots.ts`, `sitemap.ts`) can override config-based metadata + +--- + +## Pages Router (Legacy) + +Older Next.js projects use `next/head` in the Pages Router. + +```jsx +// pages/restaurants/paradise-biryani.js +import Head from "next/head"; + +export default function RestaurantPage() { + return ( + <> + + {/* Basic SEO */} + + Paradise Biryani - Hyderabad | Order Online on CodingGita + + + + + {/* OpenGraph for social media */} + + + + + + + {/* Twitter Card */} + + + + + + {/* Canonical URL */} + + + +

Paradise Biryani - Hyderabad

+ + ); +} +``` + +For new App Router projects, prefer `metadata` / `generateMetadata` instead of `next/head`. + +--- + +## `robots.txt` & Its Limitations + +- The `robots.txt` file lives at the **root** (e.g. `https://swiggy-clone.com/robots.txt`) and guides crawlers like Googlebot on _which parts of your site they may or may not crawl_ ([Google for Developers][1], [Yoast][2]). +- It’s **advisory only**—respecting crawlers obey it; malicious bots often ignore it ([Wikipedia][3]). +- Blocking via `robots.txt` doesn’t guarantee de-indexing; URLs may still appear in search results without descriptions if linked elsewhere ([Google for Developers][1]). + +--- + +## Example — What Should Be in `robots.txt` + +Let’s imagine a Swiggy-like food delivery app. Here’s how you might structure your `robots.txt`, by features and rationale. + +``` +User-agent: * +Allow: / +``` + +- **`User-agent: *`** → applies to all crawlers. +- **`Allow: /`** → indicates general access is fine. + +### 1. Block Non-Public / Functional Paths + +These include APIs, admin, login, and order flows—none are meaningful for public indexing and may leak private data. + +``` +Disallow: /api/ +Disallow: /admin/ +Disallow: /auth/ +Disallow: /login +Disallow: /logout +``` + +### 2. Prevent Duplication from Filters or Parameters + +A food delivery app often has filter queries (e.g., `?cuisine=italian`) and category views. These create tons of similar URLs. + +``` +Disallow: /*?filter= +Disallow: /*?sort= +``` + +- Use wildcards (`*`) to block parameter-caused URL variants ([Prerender][4]). + +### 3. Exclude Sensitive or Transactional Pages + +Pages like the shopping cart, checkout, order tracking, and payment gateway aren’t useful for SEO and could expose sensitive flows. + +``` +Disallow: /cart +Disallow: /checkout +Disallow: /order-track +Disallow: /payment +``` + +### 4. E-commerce Best Practice Reminder + +Do **not** use broad or “blanket” disallows that accidentally block important content — target only pages that should remain private or are low-value for search ([Prerender][4]). + +### 5. Respect Crawlers’ Budget & Sitemap Tracking + +Be explicit, add your sitemap(s) so crawlers can discover pages efficiently: + +``` +Sitemap: https://swiggy-clone.com/sitemap.xml +Sitemap: https://swiggy-clone.com/instamart/sitemap.xml.gz +``` + +Swiggy itself references multiple sitemaps; useful for segmented site areas (e.g., Instamart) ([Swiggy.com][5]). + +--- + +## Swiggy’s Real `robots.txt` Example + +Swiggy's actual `robots.txt` (as of now) looks like: + +``` +User-agent: * +Allow: / +Disallow: /product +Disallow: /product-category +Disallow: /api +Disallow: /dapi +Disallow: /mapi +Disallow: /?attachment_id=* +Disallow: /wp-admin +Disallow: /wp-includes +Disallow: /wp-content/plugins/ +Disallow: /category/* +Disallow: /track-order/* +Disallow: /order-track/* +Disallow: /auth* +Disallow: /web-payments +Disallow: /invoice/* +Disallow: /home +Disallow: /cart +Disallow: /payment +Disallow: /checkout +Disallow: /my-account +Disallow: /rate +Sitemap: https://www.swiggy.com/sitemap.xml.gz +Sitemap: https://www.swiggy.com/instamart/sitemap/sitemap.xml.gz +``` + +Notice how they've blocked legacy WordPress paths (`/wp-admin` etc.), their APIs (`/api`, `/dapi`, `/mapi`), filters (`?attachment_id=*`), and private user flows like cart, checkout, order tracking, etc. They also provide multiple sitemaps ([Swiggy.com][5]). + +--- + +## Advanced Features & Tips + +| Directive | Purpose & Example | +| ------------------------- | ---------------------------------------------------------------------------------------------------------- | +| `Crawl-delay` | Throttle crawlers (supported by some like Bing/Yandex, ignored by Google) ([Wikipedia][6], [Wikipedia][3]) | +| `$` at end | Match end-of-URL, e.g. `Disallow: /*.php$` blocks `.php` files only ([Wikipedia][6]) | +| `Allow:` override | Allow sub-paths inside disallowed paths (useful selectively) ([Conductor][7]) | +| Comments (`#`) | Annotate why rules exist—for future clarity ([seerinteractive.com][8]) | +| Multiple Sitemaps | Helps structure large sites (e.g. separate Instamart section) ([SEOTesting.com][9]) | +| Specific User-Agent rules | e.g. restrict just `Googlebot-Image`, allow `*` ([Google for Developers][10]) | + +--- + +## Recap + +For a site like Swiggy: + +1. **Allow general crawling** but **block private or sensitive pages**—they don't add SEO value and risk exposing user data. +2. **Avoid duplicate-content trap** by blocking parameter-heavy or filter-generated URLs. +3. **Provide sitemaps** for easier indexation and efficient crawling. +4. **Add notes/comments** in your `robots.txt` for clarity as your team evolves. +5. **Test your setup** via tools like Google Search Console's Robots Tester and validate syntax (one rule per line, proper order: User-agent → Disallow → Allow → Sitemap) ([Ignite Visibility][11]). + +--- + +[1]: https://developers.google.com/search/docs/crawling-indexing/robots/intro?utm_source=codinggita.com "Robots.txt Introduction and Guide | Google Search Central" +[2]: https://yoast.com/ultimate-guide-robots-txt/?utm_source=codinggita.com "The ultimate guide to robots.txt - Yoast" +[3]: https://en.wikipedia.org/wiki/Robots.txt?utm_source=codinggita.com "Robots.txt" +[4]: https://prerender.io/blog/robots-txt-for-ecommerce-seo/?utm_source=codinggita.com "Robots.txt Best Practices for Ecommerce SEO - Prerender" +[5]: https://www.swiggy.com/robots.txt?utm_source=codinggita.com "robots.txt - Swiggy" +[6]: https://de.wikipedia.org/wiki/Robots_Exclusion_Standard?utm_source=codinggita.com "Robots Exclusion Standard" +[7]: https://www.conductor.com/academy/robotstxt/?utm_source=codinggita.com "Robots.txt for SEO: The Ultimate Guide - Conductor" +[8]: https://www.seerinteractive.com/insights/how-to-read-robots-txt?utm_source=codinggita.com "What is Robots.txt? A Guide for SEOs - Seer Interactive" +[9]: https://seotesting.com/google-search-console/robots-txt/?utm_source=codinggita.com "Robots.txt and SEO - The Ultimate Guide from the Experts" +[10]: https://developers.google.com/search/docs/crawling-indexing/robots/create-robots-txt?utm_source=codinggita.com "Create and Submit a robots.txt File | Google Search Central" +[11]: https://ignitevisibility.com/the-newbies-guide-to-blocking-content-with-robots-txt/?utm_source=codinggita.com "Robots.txt Disallow: A Complete Guide - Ignite Visibility" + +# **Sitemaps** + +## 1. **What is a Sitemap?** + +A **sitemap** is a **structured list or diagram** that outlines all the pages, content sections, and navigation flows of a website or application. + +- For **users**, it acts as a **guide** to understand where they can go. +- For **search engines**, it helps **index content efficiently** so it appears in search results. +- For **designers and developers**, it is a **blueprint** of the site’s architecture. + +Think of a sitemap like the **floor plan of a mall** — it shows you all the stores (pages) and how to get from one to another. + +--- + +## 2. **Why Sitemaps are Important** + +A sitemap is not just a list — it is **central to planning, SEO, and user experience**. +For a platform like **JioHotstar**, which has millions of content pieces, a well-structured sitemap ensures: + +- **Better Content Organization**: Movies, series, sports, news — all neatly categorized. +- **Improved User Experience**: Users can find what they want without confusion. +- **Search Engine Optimization (SEO)**: Google, Bing, etc., can quickly discover and index new shows or matches. +- **Reduced Development Confusion**: Teams know exactly which pages to build and how they connect. + +--- + +## 3. **Types of Sitemaps** + +JioHotstar (and similar OTT platforms) generally uses **two main types** of sitemaps: + +### **A. Visual Sitemap (Planning Stage)** + +- Shows **hierarchical structure** of pages (parent–child relationships). +- Used internally during the **design and UX planning phase**. +- Example: + +``` +Home +│ +├── Movies +│ ├── Bollywood +│ ├── Hollywood +│ ├── Regional +│ +├── TV Shows +│ ├── Drama +│ ├── Comedy +│ ├── Reality +│ +├── Sports +│ ├── Cricket +│ ├── Football +│ ├── Hockey +│ +├── My Account +│ ├── Login / Sign Up +│ ├── Subscriptions +│ ├── Watchlist +``` + +--- + +### **B. XML Sitemap (For Search Engines)** + +- A **machine-readable file** (in XML format) submitted to search engines. +- Lists **URLs**, last modified date, priority, and update frequency. +- Helps **Google** and other crawlers index pages faster. + +Example of JioHotstar XML Sitemap (simplified): + +```xml + + + + https://www.jiohotstar.com/ + 2025-08-01 + 1.0 + + + https://www.jiohotstar.com/movies/bollywood + 2025-08-05 + 0.9 + + + https://www.jiohotstar.com/sports/cricket + 2025-08-07 + 0.8 + + +``` + +--- + +## 4. **How JioHotstar is using a Sitemap** + +JioHotstar’s sitemap must account for **different user journeys** and **content categories**. + +- **Movies Section** + - Genre Pages (Action, Romance, Comedy, Thriller) + - Language Pages (Hindi, Tamil, Telugu, Bengali) + - Individual Movie Pages (e.g., `/movies/brahmastra`) + +- **TV Shows Section** + - Categories (Drama, Comedy, Reality) + - Language-specific TV shows + - Show Detail Pages (with season/episode listings) + +- **Sports Section** + - Live Matches + - Upcoming Matches + - Highlights + - Specific Tournaments (e.g., IPL, Pro Kabaddi) + +- **Account Management** + - Login & Sign Up + - Subscription Management + - Profile Settings + - Watchlist + +- **Support Pages** + - FAQ + - Terms & Conditions + - Privacy Policy + +--- + +## 5. **Key Sitemap Best Practices for JioHotstar** + +To make the sitemap **effective**, JioHotstar would follow: + +- **Keep URLs clean**: + Instead of + `https://www.jiohotstar.com/?content_id=12345` + Use + `https://www.jiohotstar.com/movies/brahmastra` + +- **Update regularly**: + New content like cricket match highlights or latest Bollywood films should be added instantly. + +- **Use Priority Levels**: + Give **Home Page** a higher priority than a single episode page. + +- **Include Canonical URLs**: + Avoid duplicate content indexing. + +- **Separate Mobile & Web Sitemaps** (if needed): + Since OTT apps have mobile-first audiences, mobile-specific sitemaps can help. + +--- + +## 6. **Benefits JioHotstar Gets from an Optimized Sitemap** + +- **Fast Discovery of New Content**: + A new cricket match highlight is indexed within hours, appearing in Google search quickly. +- **Improved SEO Rankings**: + Search engines can categorize content better. +- **Better Internal Linking**: + Helps users and crawlers navigate deeper into the site. +- **Scalability**: + Even with millions of shows, the sitemap can handle growth. + +--- + +## 7. **Challenges in Maintaining JioHotstar’s Sitemap** + +Since OTT platforms like JioHotstar are **dynamic**, challenges include: + +- Thousands of **new videos** each month. +- Live sports with **short shelf-life**. +- Regional content with **language variations**. +- Avoiding **broken links** for removed shows. +- Managing **multiple subdomains** (e.g., for sports, kids, movies). + +--- + +## 8. **How This Would Look Visually** + +If we map JioHotstar’s sitemap into a **flow diagram**, it might start with: + +``` +Home +│ +├── Movies +│ ├── Bollywood +│ │ ├── Brahmastra +│ │ ├── Pathaan +│ ├── Hollywood +│ │ ├── Avengers: Endgame +│ │ ├── Avatar +│ +├── Sports +│ ├── Cricket +│ │ ├── IPL 2025 +│ │ │ ├── Match 1 Highlights +│ │ │ ├── Match 2 Highlights +``` + +--- + +## 9. **Conclusion** + +A **sitemap** for a massive content hub like JioHotstar is **not optional — it’s critical**. +It ensures: + +- Viewers can find content quickly. +- Search engines can index content efficiently. +- The platform remains organized even as it scales. + +If JioHotstar didn’t maintain a proper sitemap, the result would be **chaos** — users might not find their favorite show, and Google might miss indexing new releases. + +--- + +## 1. What is a Canonical URL? + +A **canonical URL** is the _preferred_ version of a webpage that search engines should index and rank when multiple versions of the same content exist. + +Think of it as telling Google: + +> "Hey, if you find similar or duplicate pages, THIS is the one I want you to show in search results." + +--- + +## 2. Why Canonical URLs Matter + +Without canonical tags, search engines might: + +- **Index duplicates** of the same page +- **Split ranking power** between versions +- Cause **SEO dilution** (traffic spread across multiple URLs) + +For big platforms like **Groww**, where many URLs can display the _same or very similar content_, canonical tags are crucial. + +--- + +## 3. How This Applies to Groww + +### Example Scenario + +Imagine **Groww** has a mutual fund details page for **"Axis Bluechip Fund"**. + +Because of tracking parameters, filters, or sorting, this _same page content_ might be accessible from multiple URLs: + +1. [https://groww.in/mutual-funds/axis-bluechip-fund](https://groww.in/mutual-funds/axis-bluechip-fund) +2. [https://groww.in/mutual-funds/axis-bluechip-fund?ref=home](https://groww.in/mutual-funds/axis-bluechip-fund?ref=home) +3. [https://groww.in/mutual-funds/axis-bluechip-fund?utm_source=google](https://groww.in/mutual-funds/axis-bluechip-fund?utm_source=google) +4. [https://groww.in/mutual-funds/axis-bluechip-fund?sort=nav](https://groww.in/mutual-funds/axis-bluechip-fund?sort=nav) + +All these URLs lead to **the same main content** — but Google sees them as _different pages_ unless we tell it otherwise. + +--- + +## 4. The Canonical Tag Solution + +On all duplicate/variant URLs, Groww can add a canonical tag in the `` section: + +```html + +``` + +**This says to search engines:** + +> “Even if the user came via tracking links, always consider `https://groww.in/mutual-funds/axis-bluechip-fund` as the main page.” + +--- + +## 5. Benefits for Groww + +- **Avoids duplicate content issues** → Google only indexes the preferred URL. +- **Consolidates ranking signals** → All backlinks and authority point to the canonical page. +- **Better analytics tracking** → Traffic isn’t split between different URL versions. +- **Cleaner search results** → Users see only one URL in Google. + +--- + +## 6. Practical Groww Examples + +### Stocks Page + +A stock like **Tata Consultancy Services (TCS)** might have: + +- `/stocks/tcs` +- `/stocks/tcs?ref=watchlist` +- `/stocks/tcs?from=portfolio` + +**Canonical URL should be:** + +```html + +``` + +### Learning Section + +A blog article like **"What is SIP?"** might be accessible as: + +- `/p/what-is-sip` +- `/p/what-is-sip?utm_campaign=summer-offer` + +Canonical points to: + +```html + +``` + +--- + +## 7. Common Mistakes to Avoid + +- **Pointing all pages to homepage** (wrong practice — each page should point to its own main version unless it’s truly a duplicate). +- **Forgetting self-canonical** → Even the main page should have a canonical tag pointing to itself. +- **Using relative URLs** in canonical tags — Always use absolute URLs (`https://groww.in/...`). +- **Not updating when URL changes** — If Groww updates its fund page structure, canonical URLs must be updated too. + +--- + +## Structured Data (JSON-LD) + +Structured data helps search engines and AI systems understand page content more clearly. It can enable **rich results** (ratings, FAQs, product details) when eligible. + +Use **Schema.org** vocabulary with **JSON-LD** in Next.js: + +```tsx +// app/products/[id]/page.tsx +export default async function ProductPage() { + const product = { + name: "Wireless Headphones", + price: 2999, + currency: "INR", + availability: "InStock", + rating: 4.5, + reviewCount: 128, + }; + + const jsonLd = { + "@context": "https://schema.org", + "@type": "Product", + name: product.name, + offers: { + "@type": "Offer", + price: product.price, + priceCurrency: product.currency, + availability: `https://schema.org/${product.availability}`, + }, + aggregateRating: { + "@type": "AggregateRating", + ratingValue: product.rating, + reviewCount: product.reviewCount, + }, + }; + + return ( + <> + ` string — confirm React renders it safely as text +- Add a second version of the same page that uses `dangerouslySetInnerHTML` with the same data — observe the difference — then install `dompurify` or `isomorphic-dompurify`, sanitize the content before rendering, and confirm the script no longer executes + +**CSRF** +- Create a form that submits to a Server Action — confirm it includes a CSRF token by logging `request.headers` in a Route Handler and observing the `Next-Action` header Next.js adds automatically +- Create a Route Handler that accepts `POST` and verify that cross-origin requests without credentials are rejected by checking the `origin` header against your application's domain — return `403` when the origin does not match + +**CORS** +- Create `app/api/public/route.ts` for a public read-only endpoint — add a `GET` handler that returns data and sets `Access-Control-Allow-Origin: *` +- Create `app/api/private/route.ts` for a credentialed endpoint — add a `GET` handler that verifies the origin header matches your domain and returns `403` for mismatched origins — confirm the response never includes `Access-Control-Allow-Origin: *` + +**Rate Limiting** +- Create `lib/rate-limit.ts` that implements an in-memory rate limiter using a `Map` keyed by client IP — export a `rateLimit` function that accepts a key, limit, and window in milliseconds, and returns whether the request is allowed and when the window resets +- Apply the rate limiter to `app/api/auth/login/route.ts` — allow a maximum of 10 requests per minute per IP — return `429` with a `Retry-After` header when the limit is exceeded +- Apply a separate rate limiter to `app/api/auth/register/route.ts` with a limit of 5 requests per hour per IP +- Confirm the rate limiter works by sending more than the allowed number of requests in quick succession and observing the `429` response + +**HTTP Security Headers** +- Add the following headers to `next.config.ts` for all routes: `X-Content-Type-Options: nosniff`, `Referrer-Policy: strict-origin-when-cross-origin`, and `Strict-Transport-Security: max-age=31536000; includeSubDomains` +- Add a `Permissions-Policy` header that disables `camera`, `microphone`, and `geolocation` +- Open the browser developer tools and confirm all headers are present in the response + +**File Upload Security** +- Create `app/api/upload/route.ts` with a `POST` handler that reads a file from `FormData` +- Reject the upload and return `401` if the request has no valid session cookie +- Reject the upload and return `400` if the file size exceeds 5MB +- Reject the upload and return `400` if the MIME type is not `image/jpeg`, `image/png`, or `image/webp` +- Generate a server-side filename using `crypto.randomUUID()` — never use the original filename in storage or response +- Return `400` if the original filename contains `../` or any path traversal pattern +- Log the upload attempt with the user id, file size, and MIME type — confirm no secret values are logged + +**Secure API End to End** +- Create `app/api/orders/[id]/route.ts` with a `GET` handler that applies the full security pipeline in this order: authenticate the user with `requireApiUser`, validate the `id` route parameter is a positive integer, fetch the order from the database, return `404` if not found, return `403` if `order.userId !== user.id` and `user.role !== "ADMIN"`, and return the order with `200` +- Confirm each failure case returns the correct status code with no internal error details in the response body +- Confirm the success case returns the full order only to the owner or an admin diff --git a/s3_full_stack_using_nextjs/assignments/18.state_management.md b/s3_full_stack_using_nextjs/assignments/18.state_management.md new file mode 100644 index 00000000..5f223450 --- /dev/null +++ b/s3_full_stack_using_nextjs/assignments/18.state_management.md @@ -0,0 +1,37 @@ +# State Management — Assignments + +## Assignment — TanStack Query and Zustand + +**Title:** Build a Product Store With TanStack Query and Zustand + +**Implementation:** + +**Setup** +- Create a new Next.js project with App Router and `src/` directory enabled +- Install TanStack Query and Zustand +- Create `app/providers.tsx` as a Client Component that wraps children in `QueryClientProvider` +- Import `Providers` in `app/layout.tsx` and confirm the layout file remains a Server Component + +**TanStack Query — Fetching** +- Create `/shop/page.tsx` as a Client Component that uses `useQuery` with `queryKey: ["products"]` to fetch all products from `https://fakestoreapi.com/products` — render a loading state, an error state, and the product list +- Create `/shop/[id]/page.tsx` as a Client Component that uses `useQuery` with `queryKey: ["products", id]` to fetch a single product from `https://fakestoreapi.com/products/{id}` — render a loading state, an error state, and the full product details +- Set `staleTime: 60_000` on the products list query and write a comment explaining what this means +- Set `gcTime: 5 * 60_000` on the same query and write a comment explaining the difference between `staleTime` and `gcTime` + +**TanStack Query — Mutations and Invalidation** +- On `/shop/page.tsx`, add a delete button next to each product that calls `useMutation` to send `DELETE https://fakestoreapi.com/products/{id}` and calls `queryClient.invalidateQueries({ queryKey: ["products"] })` on success +- Add a create product form below the list with name and price fields that calls `useMutation` to send `POST https://fakestoreapi.com/products` with the form data and invalidates `["products"]` on success +- Show a loading indicator on the submit button while each mutation is pending +- Write a comment explaining what query invalidation does and why it is needed after a mutation + +**Zustand — Cart Store** +- Create `lib/stores/cart.store.ts` with a store containing: `items` (array of `{ productId, name, price, quantity }`), `addItem`, `removeItem`, `updateQuantity`, `clearCart`, and a derived `totalPrice` +- On `/shop/[id]/page.tsx`, add an "Add to Cart" button that calls `addItem` from the store +- Create a `/cart` page as a Client Component that reads from the store and renders each cart item with its name, quantity, and price, a remove button, quantity increment and decrement buttons, the running total, and a clear cart button +- Create a `CartIcon` component in the navbar that reads the item count from the store and displays it as a badge — confirm the badge updates when items are added or removed +- Write a comment in `lib/stores/cart.store.ts` explaining why no Provider wrapper is needed for Zustand + +**Zustand — Wishlist Store** +- Create `lib/stores/wishlist.store.ts` with a store containing: `items` (array of product ids), `addItem`, `removeItem`, and `isWishlisted` (returns true if a product id is in the list) +- On `/shop/[id]/page.tsx`, add an "Add to Wishlist" button that toggles based on `isWishlisted` — add when not wishlisted, remove when already wishlisted +- Create a `/wishlist` page as a Client Component that reads the wishlisted product ids from the store, fetches each product's details using `useQuery`, and renders the full product list diff --git a/s3_full_stack_using_nextjs/assignments/19.advanced_routing.md b/s3_full_stack_using_nextjs/assignments/19.advanced_routing.md new file mode 100644 index 00000000..f7e86703 --- /dev/null +++ b/s3_full_stack_using_nextjs/assignments/19.advanced_routing.md @@ -0,0 +1,34 @@ +# Advanced Routing — Assignments + +## Assignment — Advanced Routing + +**Title:** Build a Dashboard With Parallel Routes and a Product Gallery With Modal Routing + +**Implementation:** + +**Parallel Routes — Admin Dashboard** +- Create a new Next.js project with App Router and `src/` directory enabled +- Create `app/dashboard/layout.tsx` that accepts `children`, `analytics`, and `notifications` as props and renders them in three distinct areas +- Create `app/dashboard/page.tsx` with a heading and a list of three hardcoded recent activity items +- Create `app/dashboard/@analytics/page.tsx` with a hardcoded analytics summary showing total users, total orders, and total revenue +- Create `app/dashboard/@analytics/loading.tsx` with a loading skeleton +- Create `app/dashboard/@analytics/default.tsx` with a fallback message +- Create `app/dashboard/@analytics/error.tsx` with an error message and retry button — temporarily throw an error inside `@analytics/page.tsx` to confirm only that slot shows the error while notifications continue rendering, then remove the thrown error +- Create `app/dashboard/@notifications/page.tsx` with a hardcoded list of five notifications +- Create `app/dashboard/@notifications/loading.tsx` with a loading skeleton +- Create `app/dashboard/settings/page.tsx` with a heading and two hardcoded form fields for name and email +- Navigate to `/dashboard` and confirm all three slots render simultaneously +- Navigate to `/dashboard/settings` and confirm the settings page renders in `children` while both slots remain visible +- Write a comment in `layout.tsx` explaining why `@analytics` does not create a `/dashboard/analytics` URL + +**Modal Routing — Product Gallery** +- Create `app/products/page.tsx` with a grid of ten hardcoded products each linking to `/products/[id]` +- Create `app/products/[id]/page.tsx` with a full product details page including a back link to `/products` +- Update `app/layout.tsx` to accept and render a `modal` prop alongside `children` +- Create `app/@modal/default.tsx` that returns `null` +- Create `app/@modal/(.)products/[id]/page.tsx` that renders a modal overlay with the product name and a close link to `/products` +- Click a product from the list and confirm the modal appears while the product list stays visible in the background +- Open `/products/1` directly in the address bar and confirm the full product page renders instead of the modal +- While the modal is open, press the browser back button and confirm it closes and returns to the product list +- While the modal is open, refresh the page and confirm the full product page renders +- Write a comment in `app/@modal/(.)products/[id]/page.tsx` explaining the difference between client navigation and direct URL access for this route diff --git a/s3_full_stack_using_nextjs/assignments/20.seo_and_metadata.md b/s3_full_stack_using_nextjs/assignments/20.seo_and_metadata.md new file mode 100644 index 00000000..83dc3665 --- /dev/null +++ b/s3_full_stack_using_nextjs/assignments/20.seo_and_metadata.md @@ -0,0 +1,66 @@ +# SEO & Metadata — Assignments + +## Assignment — SEO and Metadata + +**Title:** Implement Complete SEO Across a Store Application Covering All Rendering Strategies + +**Implementation:** + +**Static Metadata and Title Templates** +- Create a new Next.js project with App Router and `src/` directory enabled +- In `app/layout.tsx`, export a `metadata` object with `title.default` set to the store name, `title.template` set to `"%s | Store Name"`, and a site-level description +- Create `/about/page.tsx` with a static `metadata` export containing a unique title and description — confirm the rendered title follows the template format +- Create `/pricing/page.tsx` with its own static `metadata` — confirm each page has a distinct title in the browser tab + +**Dynamic Metadata — SSR** +- Create `/products/[id]/page.tsx` as a Server Component that fetches a product from `https://fakestoreapi.com/products/{id}` on every request +- Export `generateMetadata` from the same file that fetches the same product and returns a unique title, description, canonical URL, Open Graph title, Open Graph description, Open Graph image, Twitter card type, Twitter title, Twitter description, and Twitter image +- Confirm the `` tag in the page source matches the fetched product name +- Confirm the `og:title` and `twitter:title` meta tags appear in the page source + +**Dynamic Metadata — SSG** +- Create `/blog/[slug]/page.tsx` with a hardcoded array of three blog posts (slug, title, description, image) +- Add `generateStaticParams` that returns all three slugs for pre-rendering at build time +- Export `generateMetadata` that reads the slug, finds the matching post from the array, and returns title, description, canonical URL, and Open Graph metadata +- Confirm all three blog pages are pre-rendered and each has unique metadata in the page source + +**Dynamic Metadata — ISR** +- Create `/categories/[id]/page.tsx` that fetches a category from `https://fakestoreapi.com/products/category/electronics` with `next: { revalidate: 60 }` +- Export `generateMetadata` from the same file that returns a title and description based on the category name +- Add a canonical URL to the metadata + +**CSR Page — No SEO Required** +- Create `/dashboard/page.tsx` as a Client Component that fetches user data using `useEffect` after the component loads +- Do not add any metadata to this page +- Write a comment at the top explaining why this page does not need SEO metadata and why client-side fetching is acceptable here + +**Canonical URLs** +- On `/products/page.tsx`, add a static canonical URL pointing to the products listing page +- On `/products/[id]/page.tsx`, add a dynamic canonical URL that includes the product id +- On `/blog/[slug]/page.tsx`, add a dynamic canonical URL that includes the slug +- Write a comment on `/products/page.tsx` explaining why canonical URLs matter when query parameters like `?sort=` or `?filter=` are present + +**Open Graph and Twitter** +- On `/about/page.tsx`, add static Open Graph metadata with title, description, type `"website"`, site name, and a hardcoded image URL with width 1200 and height 630 +- On `/products/[id]/page.tsx`, confirm the dynamic Open Graph and Twitter metadata already added uses the product image with width 1200 and height 630 + +**Sitemap** +- Create `app/sitemap.ts` that fetches all products from `https://fakestoreapi.com/products` and returns a sitemap including: the home page, the products listing page, and one entry per product using its id in the URL with its last modified date set to the current date +- Navigate to `/sitemap.xml` and confirm all URLs appear + +**Robots** +- Create `app/robots.ts` that allows all crawlers to access `/`, `/products`, `/blog`, `/about`, and `/pricing`, and disallows `/dashboard` and `/admin` +- Include the sitemap URL in the robots output +- Navigate to `/robots.txt` and confirm the rules appear +- Write a comment in `robots.ts` explaining why disallowing `/dashboard` in robots.txt is not a security measure + +**Structured Data — JSON-LD** +- On `/products/[id]/page.tsx`, add a `<script type="application/ld+json">` tag inside the returned JSX containing a Schema.org `Product` object with name, description, image, and an `Offer` object containing price, currency, and availability +- Confirm the JSON-LD script tag appears in the page source and the data matches what is visible on the page + +**Pages Router SEO** +- Create a separate Next.js project with Pages Router enabled +- Create `pages/products/index.tsx` that uses `next/head` to set a title, description, and canonical URL +- Create `pages/products/[id].tsx` that uses `getServerSideProps` to fetch a product, passes it as a prop, and uses `next/head` to set a dynamic title, description, and canonical URL based on the fetched product +- Create `pages/blog/index.tsx` that uses `getStaticProps` to return a hardcoded list of blog posts and uses `next/head` to set a static title and description +- Write a comment in each Pages Router file noting the equivalent App Router approach for the same metadata