> For the complete documentation index, see [llms.txt](https://www.ankitavirani.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://www.ankitavirani.com/experience/frontend/nextjs.md).

# NextJS

## Next.js: A Comprehensive Guide 🚀

### Introduction to Next.js 📚

Next.js is a powerful React framework that enables you to build server-side rendered and statically generated web applications. It was introduced by Vercel (formerly Zeit) in 2016 to address common challenges in React development and to provide a more opinionated, yet flexible, structure for building modern web applications.

#### Why Next.js? 🤔

Next.js offers several advantages over traditional React applications:

* Server-Side Rendering (SSR) for improved performance and SEO
* Static Site Generation (SSG) for blazing-fast static websites
* Automatic code splitting for faster page loads
* Built-in CSS support
* API routes for building backend functionality
* Easy deployment and scalability

#### Next.js vs Other Frameworks 🥊

Compared to other frameworks, Next.js stands out in several ways:

| Feature                  | Next.js | Create React App | Gatsby |
| ------------------------ | ------- | ---------------- | ------ |
| Server-Side Rendering    | ✅       | ❌                | ❌      |
| Static Site Generation   | ✅       | ❌                | ✅      |
| API Routes               | ✅       | ❌                | ❌      |
| Automatic Code Splitting | ✅       | ✅                | ✅      |
| Zero Configuration       | ✅       | ✅                | ❌      |

### Next.js Architecture 🏗️

Next.js follows a hybrid architecture that combines server-side rendering, static site generation, and client-side rendering. Here's a high-level overview:

<figure><img src="/files/SoqpOJkuhLfZRnPweimz" alt=""><figcaption></figcaption></figure>

### Example Project Structure

Here is an example structure for a Next.js project with TypeScript:

```
my-next-app/
│
├── public/
│   └── image.jpg
│
├── pages/
│   ├── api/
│   │   └── hello.ts
│   ├── about.tsx
│   ├── index.tsx
│   └── posts/
│       └── [id].tsx
│
├── styles/
│   └── globals.css
│
├── tsconfig.json
└── package.json
```

### User Flow in a Next.js Application 🔄

Here's a typical user flow in a Next.js application:

<figure><img src="/files/bMCuAI4ZcAJR8vQeSatD" alt=""><figcaption></figcaption></figure>

### Core Next.js Concepts and Code Snippets 💻

#### 1. Pages and Routing

Next.js uses a file-system based routing. Each file inside the `pages` directory becomes a route.

```jsx
// pages/index.js
export default function Home() {
  return <h1>Welcome to Next.js!</h1>
}

// pages/about.js
export default function About() {
  return <h1>About Us</h1>
}
```

#### 2. Dynamic Routes

You can create dynamic routes using brackets `[]` in the filename.

```jsx
// pages/posts/[id].js
import { useRouter } from 'next/router'

export default function Post() {
  const router = useRouter()
  const { id } = router.query

  return <p>Post: {id}</p>
}
```

#### 3. API Routes

API routes allow you to build your API endpoints as Node.js serverless functions.

```jsx
// pages/api/hello.js
export default function handler(req, res) {
  res.status(200).json({ name: 'John Doe' })
}
```

#### 4. Data Fetching

Next.js provides several methods for data fetching:

#### getStaticProps (Static Generation)

```jsx
export async function getStaticProps() {
  const res = await fetch('<https://api.example.com/data>')
  const data = await res.json()

  return {
    props: { data },
  }
}

export default function Home({ data }) {
  return <div>{data.title}</div>
}
```

#### getServerSideProps (Server-side Rendering)

```jsx
export async function getServerSideProps(context) {
  const res = await fetch(`https://api.example.com/data/${context.params.id}`)
  const data = await res.json()

  return {
    props: { data },
  }
}

export default function Post({ data }) {
  return <div>{data.title}</div>
}
```

#### 5. Custom App Component

Use `_app.js` to initialize pages with custom layouts or global state.

```jsx
// pages/_app.js
import '../styles/globals.css'

function MyApp({ Component, pageProps }) {
  return (
    <Layout>
      <Component {...pageProps} />
    </Layout>
  )
}

export default MyApp
```

#### 5. Image Optimization in Next.js 🖼️

Next.js provides built-in image optimization features through the Image component:

```jsx
import Image from 'next/image'

function MyImage() {
  return (
    <Image
      src="/images/profile.jpg"
      alt="Profile picture"
      width={500}
      height={500}
    />
  )
}
```

This component automatically optimizes images for better performance and user experience.

### TypeScript Integration 🧰

Next.js has excellent TypeScript support out of the box. To use TypeScript in your Next.js project:

```bash
npx create-next-app@latest --typescript
# or
yarn create next-app --typescript
```

#### TypeScript Configuration (`tsconfig.json`)

Next.js automatically creates a `tsconfig.json` file with recommended settings:

```json
{
  "compilerOptions": {
    "target": "es5",
    "lib": ["dom", "dom.iterable", "esnext"],
    "allowJs": true,
    "skipLibCheck": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "noEmit": true,
    "esModuleInterop": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "jsx": "preserve",
    "incremental": true
  },
  "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
  "exclude": ["node_modules"]
}
```

### Built-In CSS and Sass Support 🎨

Next.js supports CSS and Sass out of the box. You can import CSS files directly in your components:

```jsx
import styles from './Button.module.css'

export function Button() {
  return (
    <button className={styles.error}>
      Delete
    </button>
  )
}
```

### Advantages of Using Next.js with TypeScript 🚀

* Enhanced developer experience with better autocomplete and type checking
* Reduced runtime errors through static type checking
* Improved code maintainability and readability
* Better integration with IDEs for refactoring and navigation

Here's an example of a TypeScript component in Next.js:

```tsx
import { NextPage } from 'next'
import { useState } from 'react'

interface Props {
  initialCount: number
}

const Counter: NextPage<Props> = ({ initialCount }) => {
  const [count, setCount] = useState(initialCount)

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>Increment</button>
    </div>
  )
}

export default Counter
```

### Component Lifecycle in Next.js 🔄

Next.js components follow the React component lifecycle with some additional hooks specific to server-side rendering:

#### 1. Mounting

* `constructor()`: Initialize state and bind methods
* `render()`: Render the component
* `componentDidMount()`: Perform side effects after component is mounted

#### 2. Updating

* `shouldComponentUpdate()`: Decide if the component should re-render
* `render()`: Re-render the component
* `componentDidUpdate()`: Perform side effects after component updates

#### 3. Unmounting

* `componentWillUnmount()`: Clean up before component is unmounted

#### 4. Next.js Specific Lifecycle Methods

* `getInitialProps()`: Fetch data on the server (deprecated in favor of getStaticProps and getServerSideProps)
* `getStaticProps()`: Fetch data at build time for static generation
* `getServerSideProps()`: Fetch data on each request for server-side rendering

#### Example: Component Lifecycle

```jsx
import React from 'react'

class LifecycleComponent extends React.Component {
  constructor(props) {
    super(props)
    this.state = { count: 0 }
    console.log('Constructor')
  }

  static async getInitialProps() {
    console.log('getInitialProps')
    return { initialCount: 5 }
  }

  componentDidMount() {
    console.log('Component Did Mount')
    this.setState({ count: this.props.initialCount })
  }

  shouldComponentUpdate(nextProps, nextState) {
    console.log('Should Component Update')
    return nextState.count !== this.state.count
  }

  componentDidUpdate() {
    console.log('Component Did Update')
  }

  componentWillUnmount() {
    console.log('Component Will Unmount')
  }

  render() {
    console.log('Render')
    return (
      <div>
        <h1>Count: {this.state.count}</h1>
        <button onClick={() => this.setState(state => ({ count: state.count + 1 }))}>
          Increment
        </button>
      </div>
    )
  }
}

export default LifecycleComponent
```

### Real-time Example: Building a Blog with Next.js 📝

Let's create a simple blog application to demonstrate Next.js features:

#### 1. Set up the project

```bash
npx create-next-app my-blog
cd my-blog
```

#### 2. Create a layout component

```jsx
// components/Layout.js
import Link from 'next/link'

export default function Layout({ children }) {
  return (
    <div>
      <nav>
        <Link href="/">Home</Link>
        <Link href="/about">About</Link>
      </nav>
      <main>{children}</main>
      <footer>© 2024 My Blog</footer>
    </div>
  )
}
```

#### 3. Update \_app.js to use the layout

```jsx
// pages/_app.js
import Layout from '../components/Layout'

function MyApp({ Component, pageProps }) {
  return (
    <Layout>
      <Component {...pageProps} />
    </Layout>
  )
}

export default MyApp
```

#### 4. Create an API route for blog posts

```jsx
// pages/api/posts.js
const posts = [
  { id: 1, title: 'Hello Next.js', content: 'This is my first post!' },
  { id: 2, title: 'Learning Next.js', content: 'Next.js is awesome!' },
]

export default function handler(req, res) {
  res.status(200).json(posts)
}
```

#### 5. Update the home page to display blog posts

```jsx
// pages/index.js
import Link from 'next/link'

export async function getServerSideProps() {
  const res = await fetch('<http://localhost:3000/api/posts>')
  const posts = await res.json()
  return { props: { posts } }
}

export default function Home({ posts }) {
  return (
    <div>
      <h1>My Blog</h1>
      <ul>
        {posts.map(post => (
          <li key={post.id}>
            <Link href={`/posts/${post.id}`}>{post.title}</Link>
          </li>
        ))}
      </ul>
    </div>
  )
}
```

#### 6. Create a dynamic route for individual blog posts

```jsx
// pages/posts/[id].js
import { useRouter } from 'next/router'

export async function getServerSideProps({ params }) {
  const res = await fetch(`http://localhost:3000/api/posts`)
  const posts = await res.json()
  const post = posts.find(p => p.id === parseInt(params.id))
  return { props: { post } }
}

export default function Post({ post }) {
  const router = useRouter()

  if (router.isFallback) {
    return <div>Loading...</div>
  }

  return (
    <div>
      <h1>{post.title}</h1>
      <p>{post.content}</p>
    </div>
  )
}
```

### FAQs🧠

1. What is the purpose of the `getStaticProps` function in Next.js?

   > Answer: `getStaticProps` is used to fetch data at build time for static generation. It allows you to pre-render pages with dynamic content by fetching data and passing it as props to the page component.
2. How does Next.js handle routing?

   > Answer: Next.js uses a file-system based routing. Each file inside the `pages` directory automatically becomes a route. For example, `pages/about.js` will be accessible at `/about`.
3. What is the difference between `getServerSideProps` and `getStaticProps`?

   > Answer: `getServerSideProps` runs on every request and is used for server-side rendering, while `getStaticProps` runs at build time and is used for static site generation.
4. How can you create dynamic routes in Next.js?

   > Answer: Dynamic routes in Next.js are created by using square brackets `[]` in the filename. For example, `pages/posts/[id].js` will match `/posts/1`, `/posts/2`, etc.
5. What is the purpose of the `_app.js` file in Next.js?

   > Answer: The `_app.js` file is used to initialize pages. It can be used to add global styles, layouts, or state management that should be applied to all pages in the application.

### Conclusion 🎉

Next.js provides a powerful and flexible framework for building modern web applications. Its server-side rendering capabilities, coupled with static site generation and API routes, make it an excellent choice for a wide range of projects. TypeScript integration further improves code quality and development efficiency, making this combination an excellent choice for both small and large-scale projects. By mastering Next.js, you'll be well-equipped to create fast, scalable, and SEO-friendly web applications.

***


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://www.ankitavirani.com/experience/frontend/nextjs.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
