Mastering Next.js 13/14 - Fundamentals
Tags: nextjs, react, javascript, beginners
Published: 2024-04-18 23:57:56

Welcome to the "Mastering Next.js 13/14: Building Dynamic Web Applications" course! 

In this comprehensive guide, we'll dive deep into the world of Next.js, a powerful React framework that enables developers to create high-performance, feature-rich web applications with ease. Whether you're a beginner or an experienced developer looking to expand your skillset, this course will provide you with the knowledge and practical examples to master Next.js and build dynamic, scalable applications.

Throughout this course, we'll cover the latest features and enhancements introduced in Next.js 13 and Next.js 14, with a particular focus on the App Router. You'll learn how to leverage the power of the App Router to create complex routing structures, handle data fetching efficiently, and build interactive user interfaces.

We'll start by setting up a Next.js development environment and exploring the basic concepts of Next.js, such as pages, components, and routing. From there, we'll dive into more advanced topics, including server-side rendering, static site generation, API routes, and more.

By the end of this course, you'll have a solid understanding of Next.js and the skills to build production-ready web applications. Let's get started!

## Prerequisites

Before diving into this course, it's recommended to have a basic understanding of the following technologies:

- HTML, CSS, and JavaScript
- React fundamentals
- Node.js and npm (Node Package Manager)

If you're new to React or need a refresher, it's recommended to complete a beginner-level React course before starting this Next.js course.

## Course Outline

1. Introduction to Next.js
   - What is Next.js?
   - Benefits of using Next.js
   - Setting up a Next.js development environment

2. Next.js Fundamentals
   - Pages and Components
   - Routing in Next.js
   - Linking Between Pages
   - Dynamic Routes

3. Styling in Next.js
   - CSS Modules
   - Styled JSX
   - CSS-in-JS Libraries (e.g., styled-components)

4. Data Fetching
   - getStaticProps
   - getStaticPaths
   - getServerSideProps
   - Client-side Data Fetching

5. App Router in Next.js 13/14
   - Introduction to the App Router
   - Migrating from Pages Router to App Router
   - File-based Routing
   - Layouts and Nesting
   - Data Fetching with the App Router

6. API Routes
   - Creating API Routes
   - Handling HTTP Methods
   - Connecting to Databases
   - Authentication and Authorization

7. Deployment and Optimization
   - Deploying Next.js Applications
   - Static Site Generation (SSG)
   - Incremental Static Regeneration (ISR)
   - Performance Optimization Techniques

8. Advanced Topics
   - Custom Server Configuration
   - Authentication Strategies
   - Internationalization (i18n)
   - Testing Next.js Applications

9. Real-World Projects
   - Building a Blog Application
   - Creating an E-commerce Store
   - Developing a Social Media Dashboard

10. Conclusion
    - Course Recap
    - Next Steps and Resources

## Detailed Explanations and Examples

### 1. Introduction to Next.js

Next.js is a popular React framework that simplifies the process of building server-rendered React applications. It provides a powerful set of features and abstractions that enhance the developer experience and enable the creation of high-performance web applications.

One of the key benefits of using Next.js is its built-in server-side rendering (SSR) capabilities. SSR allows your application to render on the server and send fully populated HTML pages to the client, resulting in faster initial load times and improved search engine optimization (SEO).

Next.js also offers automatic code splitting, which means that your application is divided into smaller chunks, and only the necessary code is loaded for each page. This optimization technique significantly improves the performance of your application by reducing the amount of JavaScript that needs to be downloaded and parsed by the browser.

To get started with Next.js, you'll need to set up a development environment. First, make sure you have Node.js and npm installed on your machine. Then, you can create a new Next.js project by running the following command:

```bash
npx create-next-app@latest my-app
```

This command will create a new Next.js project in a directory named `my-app`. Once the project is created, navigate to the project directory and start the development server:

```bash
cd my-app
npm run dev
```

Now, you can access your Next.js application by opening a web browser and navigating to `http://localhost:3000`.

### 2. Next.js Fundamentals

#### Pages and Components

In Next.js, a page is a React component that is associated with a route based on its file name. For example, if you create a file named `pages/about.js`, it will automatically be accessible at the `/about` route.

Here's an example of a simple Next.js page component:

```jsx
function AboutPage() {
  return <h1>About Us</h1>;
}

export default AboutPage;
```

Components, on the other hand, are reusable building blocks that can be used across multiple pages. They encapsulate specific functionality or UI elements and can be imported into pages or other components.

Here's an example of a reusable button component:

```jsx
function Button({ label, onClick }) {
  return <button onClick={onClick}>{label}</button>;
}

export default Button;
```

#### Routing in Next.js

Next.js provides a file-based routing system, which means that the routes of your application are automatically determined by the structure of the `pages` directory.

For example, if you have the following file structure:

```
pages/
  index.js
  about.js
  contact.js
```

Next.js will generate the following routes:

- `/`: Corresponds to `pages/index.js`
- `/about`: Corresponds to `pages/about.js`
- `/contact`: Corresponds to `pages/contact.js`

You can create nested routes by adding subdirectories inside the `pages` directory. For example:

```
pages/
  index.js
  about/
    index.js
    team.js
```

In this case, Next.js will generate the following routes:

- `/`: Corresponds to `pages/index.js`
- `/about`: Corresponds to `pages/about/index.js`
- `/about/team`: Corresponds to `pages/about/team.js`

#### Linking Between Pages

To create links between pages in Next.js, you can use the `Link` component provided by the `next/link` module. The `Link` component ensures that the navigation is handled client-side, resulting in faster page transitions.

Here's an example of using the `Link` component:

```jsx
import Link from 'next/link';

function Navigation() {
  return (
    <nav>
      <ul>
        <li>
          <Link href="/">
            <a>Home</a>
          </Link>
        </li>
        <li>
          <Link href="/about">
            <a>About</a>
          </Link>
        </li>
        <li>
          <Link href="/contact">
            <a>Contact</a>
          </Link>
        </li>
      </ul>
    </nav>
  );
}

export default Navigation;
```

#### Dynamic Routes

Next.js allows you to create dynamic routes that can accept parameters. To create a dynamic route, you need to use square brackets `[]` in the file name.

For example, if you have a file named `pages/posts/[id].js`, it will match any route that starts with `/posts/` followed by a parameter. The parameter can be accessed using the `useRouter` hook from the `next/router` module.

Here's an example of a dynamic route component:

```jsx
import { useRouter } from 'next/router';

function PostPage() {
  const router = useRouter();
  const { id } = router.query;

  return <h1>Post #{id}</h1>;
}

export default PostPage;
```

In this example, if you navigate to `/posts/123`, the `id` parameter will be `123`, and the page will render `<h1>Post #123</h1>`.

### 3. Styling in Next.js

Next.js provides several options for styling your components, giving you the flexibility to choose the approach that best suits your project's needs.

#### CSS Modules

CSS Modules allow you to write scoped CSS that is automatically generated with unique class names. This ensures that your styles are encapsulated and don't leak to other components.

To use CSS Modules in Next.js, you need to create a CSS file with the `.module.css` extension and import it into your component.

Here's an example:

```css
/* styles.module.css */
.button {
  background-color: blue;
  color: white;
  padding: 10px 20px;
}
```

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

function Button({ label }) {
  return <button className={styles.button}>{label}</button>;
}

export default Button;
```

In this example, the generated class name for the `.button` class will be unique, preventing style conflicts with other components.

#### Styled JSX

Next.js also supports Styled JSX, which allows you to write CSS directly in your components using a `<style jsx>` tag.

Here's an example:

```jsx
function Button({ label }) {
  return (
    <>
      <button>{label}</button>
      <style jsx>{`
        button {
          background-color: blue;
          color: white;
          padding: 10px 20px;
        }
      `}</style>
    </>
  );
}

export default Button;
```

Styled JSX scopes the styles to the component automatically, so you don't need to worry about class name collisions.

#### CSS-in-JS Libraries

Next.js is compatible with popular CSS-in-JS libraries like styled-components and Emotion. These libraries allow you to write CSS directly in your JavaScript files and provide additional features like dynamic styling and theming.

Here's an example using styled-components:

```jsx
import styled from 'styled-components';

const Button = styled.button`
  background-color: blue;
  color: white;
  padding: 10px 20px;
`;

function MyComponent() {
  return <Button>Click me</Button>;
}

export default MyComponent;
```

### 4. Data Fetching

Next.js provides several data fetching methods that allow you to fetch data from various sources and render it in your components.

#### getStaticProps

`getStaticProps` is used to fetch data at build time. It runs on the server-side and generates static HTML pages with the fetched data. This method is ideal for pages that don't require frequently updated data.

Here's an example of using `getStaticProps`:

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

export async function getStaticProps() {
  const response = await fetch('https://api.example.com/posts/1');
  const post = await response.json();

  return {
    props: {
      post,
    },
  };
}

export default BlogPostPage;
```

In this example, `getStaticProps` fetches a blog post from an API and passes it as a prop to the `BlogPostPage` component. The fetched data is used to generate a static HTML page at build time.

#### getStaticPaths

`getStaticPaths` is used in combination with `getStaticProps` to generate static pages for dynamic routes. It specifies the paths that should be pre-rendered at build time.

Here's an example:

```jsx
function ProductPage({ product }) {
  return (
    <div>
      <h1>{product.name}</h1>
      <p>{product.description}</p>
    </div>
  );
}

export async function getStaticPaths() {
  const response = await fetch('https://api.example.com/products');
  const products = await response.json();

  const paths = products.map((product) => ({
    params: { id: product.id.toString() },
  }));

  return { paths, fallback: false };
}

export async function getStaticProps({ params }) {
  const response = await fetch(`https://api.example.com/products/${params.id}`);
  const product = await response.json();

  return {
    props: {
      product,
    },
  };
}

export default ProductPage;
```

In this example, `getStaticPaths` fetches a list of product IDs from an API and generates the paths for each product page. `getStaticProps` then fetches the data for each individual product based on the `id` parameter.

#### getServerSideProps

`getServerSideProps` is used to fetch data on each request. It runs on the server-side and generates HTML pages dynamically. This method is suitable for pages that require real-time data or depend on user authentication.

Here's an example:

```jsx
function UserProfilePage({ user }) {
  return (
    <div>
      <h1>{user.name}</h1>
      <p>{user.email}</p>
    </div>
  );
}

export async function getServerSideProps({ req, res }) {
  const { userId } = req.session;
  const response = await fetch(`https://api.example.com/users/${userId}`);
  const user = await response.json();

  return {
    props: {
      user,
    },
  };
}

export default UserProfilePage;
```

In this example, `getServerSideProps` fetches user data based on the `userId` stored in the session. The fetched data is passed as a prop to the `UserProfilePage` component, and the HTML is generated dynamically on each request.

#### Client-side Data Fetching

Next.js also supports client-side data fetching using APIs like `fetch` or libraries like `axios`. You can fetch data directly in your components using React's `useEffect` hook or other lifecycle methods.

Here's an example:

```jsx
import { useState, useEffect } from 'react';

function ProductList() {
  const [products, setProducts] = useState([]);

  useEffect(() => {
    async function fetchProducts() {
      const response = await fetch('https://api.example.com/products');
      const data = await response.json();
      setProducts(data);
    }

    fetchProducts();
  }, []);

  return (
    <ul>
      {products.map((product) => (
        <li key={product.id}>{product.name}</li>
      ))}
    </ul>
  );
}

export default ProductList;
```

In this example, the `ProductList` component fetches a list of products from an API using the `useEffect` hook and updates the component's state with the fetched data.

### 5. App Router in Next.js 13/14

Next.js 13 introduced a new routing system called the App Router, which provides a more flexible and intuitive way to define routes and handle navigation in your application.

We will continue on the Part 2 of that course.

- NextJS App Router and API Routes : https://dev.to/fabrikapp/mastering-nextjs-1314-app-router-and-api-routes-fbn

Or you can skip to part 3 : 
- NextJS Advanced Techniques : https://dev.to/fabrikapp/mastering-nextjs-1314-advanced-techniques-5ba