> 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="https://4222757721-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FJ8enmdGTQxxu7PPuvM80%2Fuploads%2F4x4Q0i0EtPZYjE99Pdw6%2Fimage.png?alt=media&amp;token=2031109a-bd75-41a7-82e8-be4f54038c4b" 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="https://4222757721-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FJ8enmdGTQxxu7PPuvM80%2Fuploads%2FhttBOonROwduPPdDdbOP%2Fimage.png?alt=media&amp;token=fd9e38e1-9849-4faa-8666-3baf7c1b3e5c" 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.

***
