Learn Nextjs Part 1: Installation, Pages, Layout, Links, Routes, Loading, Error & Route handler
===

---
###### tags: `Nextjs`, `react`
## Installation
Open terminal and enter this command :`npx create-next-app@latest --experimental-app`
It will ask several questions for installing relevant packages.

After that, it will start installing.

Here is the basic file structure.
```json
├── .eslintrc.json
├── .gitignore
├── app
│ ├── api
│ │ └── hello
│ │ └── route.ts
│ ├── favicon.ico
│ ├── globals.css
│ ├── layout.tsx
│ ├── page.module.css
│ └── page.tsx
├── next-env.d.ts
├── next.config.js
├── package-lock.json
├── package.json
├── public
│ ├── next.svg
│ ├── thirteen.svg
│ └── vercel.svg
├── README.md
└── tsconfig.json
```
- `app` folder is where all the routes and pages located
- `api` folder is where all api calls located.
- `public` is where all static files, such as svg, png .etc located.
Run `npm run dev` to start next server.


## Routing Fundamentals
> Reference:
> [Nextjs-Routing Fundamentals](https://beta.nextjs.org/docs/routing/fundamentals)

- Tree: A component tree with parent and children components, a folder structure, etc.
- Subtree: Part of a tree, starting at a new root (first) and ending at the leaves (last).
- Root: First node in a tree or subtree.
- Leaf: Nodes in a subtree that have no children.

- URL Segment: Part of the URL path delimited by slashes.
- URL Path: Part of the URL that comes after the domain (composed of segments)
> Reference
> [Project Setup](https://nextjs.org/docs#automatic-setup)
## Creating Routes
We can define routes inside `app` directory, here's the steps:
1. Go inside `app` directory.
2. Create a folder, folder refers to a route, i.e. `about` folder, `product` folder, each of them represent a **route segment**.
3. Create a subfolder inside the `about` folder as this would be **nested route**.
```json
app/
┣ about/ (about route)
┃ ┗ team/ (nested route)
┣ api/
┃ ┗ hello/
┃ ┗ route.ts
┣ product/ (product route)
┣ favicon.ico
┣ globals.css
┣ layout.tsx
┣ page.module.css
┗ page.tsx
```
### page
Inside each route folder, it would have a `page.js`(or `ts`, `jsx`, `tsx`), this makes route segment publicly accessible.
```json
app/
┣ about/
┃ ┣ team/
┃ ┃ ┗ page.tsx (this page contains team content)
┃ ┗ page.tsx (this page contains about content)
┣ api/
┃ ┗ hello/
┃ ┗ route.ts
┣ product/
┃ ┗ page.tsx (this page contains product content)
┣ favicon.ico
┣ globals.css
┣ layout.tsx
┣ page.module.css
┗ page.tsx (this page is the root)
```
### Route Groups
Sometimes we might need to break out of the routes without affetcing it, we can create a **route group**, it is used:
- Organize routes without affecting the URL structure.
- Opting-in specific route segments into a layout.
- Create multiple root layouts by splitting your application.
Using parenthesis as a naming convention, e.g. `(marketing)`
```json
app/
┣ (blog)/
┃ ┗ layout.tsx
┣ (marketing)/
┃ ┗ layout.tsx
┣ about/
┃ ┣ team/
┃ ┃ ┗ page.tsx
┃ ┗ page.tsx
┣ api/
┃ ┗ hello/
┃ ┗ route.ts
┣ product/
┃ ┗ page.tsx
```
Even though `(marketing)` and `(blog)` share the same URL hierarchy, we can create a different layout by adding `layout.tsx` inside of it.
We can move route inside a route group, in this way, they can share the same layout, any routes that outside of the group will not share the layout.
```json
app/
┣ (blog)/
┃ ┗ layout.tsx
┣ (marketing)/
┃ ┗ layout.tsx
┣ about/
┃ ┣ team/
┃ ┃ ┗ page.tsx (it's inside of marketing folder, it can have same layout )
┃ ┗ page.tsx (it's inside of marketing folder, it can have same layout )
┣ api/
┃ ┗ hello/
┃ ┗ route.ts
┣ product/
┃ ┗ page.tsx
```
### Dynamic Segments
Using square brackets for refering dynamic segments, e.g. `[slug]`. They are passed as the `params` props. Let's say we have a `blog` route, usually it will have ids or identifiers for each post, e.g. `/blog/1`, `/blog/2`,
we can create a `[slug]` folder inside the `blog` folder.
#### Catch-all segments
Using ellipsis inside the brackets, e.g. `[...slug]`, `[...folderName
#### Optional catch-all segments
Using double square brackets, e.g.`[[...folderName]]`
## Root layout & Multiple Root layouts
**Layouts** preserve state, interactivity and do not re-render, some important points we need to know:
- Must contains `<html>` and `<body>` tag.
- They are **Server Component** by default.
- They can fetch data.
- It's impossible to pass data between a parent layout to its children.
- `layout.tsx` will wrap the `page.tsx`
Root layout refers to some components that can be apply multiple route, e.g. `navbar` or `footer`, below you can see the navbar is at a nested route `about/team`, some important points we need to know:
- `app` directory **MUST** include a root layout.
- Can use the built-in SEO support to manage `<head>` HTML element.

```json
app/
┣ (blog)/
┃ ┗ layout.tsx
┣ (marketing)/
┃ ┗ layout.tsx
┣ about/
┃ ┣ team/
┃ ┃ ┗ page.tsx
┃ ┗ page.tsx
┣ api/
┃ ┗ hello/
┃ ┗ route.ts
┣ product/
┃ ┗ page.tsx
┣ favicon.ico
┣ globals.css
┣ layout.tsx (root layout that applies to every route)
┣ page.module.css
┗ page.tsx
```
We can create **Multiple Root layouts** by removing the top-level `layout.tsx`, and adding `layout.tsx` file inside each route groups, this allows us to have a completely different UI, but it needs to have `<html>` and `<body>` tag.
> Reference
> [Defining Routes](https://beta.nextjs.org/docs/routing/defining-routes)
### Component Hierarchy
- `layout.js`
- `template.js`
- `error.js` (React error boundary)
- `loading.js` (React suspense boundary)
- `not-found.js` (React error boundary)
- `page.js` or nested `layout.js`

### Nestd Component Hierarchy

## Linking & Navigating
In nextjs, router uses **server-centric** routing with **client-side navigation.
Two ways to navigate between routes:
1. `<Link>` component.
2. `useRouter` hook.
### `<Link>` Component
It provides prefetching and client-side navigation, it's the primary way to navigate between routes.
```typescript=
// In React, <Link> is from react-router-dom
import { Link } from 'react-router-dom';
export default function Nav() {
return (
<nav>
<Link to="/">Logo</Link>
</nav>
)
}
```
```typescript=
// In Nextjs
export default function Page() {
return <Link href="/dashboard">Dashboard</Link>;
}
```
## Loading
To show an instant loading state, this would help to create loading UI with `React Suspense`.
```typescript=
// loading.tsx
export default function Loading() {
return <LoadingSkeleton />
}
```
In the same folder, `loading.tsx` will be nested inside `layout.tsx`, it will wrap the `page.tsx` and any children below in a `<Suspense>`.

1. Navigation is immediate, even with **server-centric routing**.
2. Navigation does not need to wait for the content of the route to fully load before navigating to another route.
3. Shared layouts remain interactive.
### Manually Defining Suspense Boundaries
We can still manually create Suspense bundaries, but it's recommended to use `loading.tsx` convention as Nextjs optimizes.
> Reference:
> [Linking & Navigating](https://beta.nextjs.org/docs/routing/linking-and-navigating)
> [Loading UI](https://beta.nextjs.org/docs/routing/loading-ui)
## Error
```typescript=
// error.tsx
'use client';
export default function Error({
error,
reset,
}: {
error: Error;
reset: () => void;
}) {
return (
<div>
<h2>Something went wrong!</h2>
<button onClick={() => reset()}>Try again</button>
</div>
);
}
```
`error.tsx` allows to handle runtime errors in nested routes. Same as [React Error Boundary](https://react.dev/reference/react/Component#catching-rendering-errors-with-an-error-boundary), it will:
- Automatically wrap a route segment and its nested children.
- Isolate errors to protect the whole app being crushed when there's an error.
- Attempt to recover from an error without a full page reload.
**Error components must be Client components**

- Export `error.tsx` file, as it's used as the fallback component.
- If the error is thrown within the boundary, the error is contained and the fallback component is rendered.
- When the error component is active, **layouts above it maintain their state and remain interactive**.
### `reset()`
Use the `reset()` to prompt the user to attemp to reocver from the error, when it executes, it will try to re-render the error boundary's content.