Nest.js Linking and Navigation

This page is about [next.js's Linking and Navigation](https://nextjs.org/docs/app/building-your-application/routing/linking-and-navigating#how-routing-and-navigation-works).

There are 4 ways to navigate between routes in Next.js.
### Using <Link> component
これはサーバーでもクライアントコンポーネントでも両方使える。
`<Link>` is a built-in component that extends the HTML `<a>` tag to provide prefetching and client-side navigation between routes.
aタグをラップしている。

- difference between client-side navigation and server-side naviagtion
  - server-side: keep making requests to the server in order for the application to rerender
  - client-side: does not need to keep make request to the server, it just does it once when the application is being loaded into the browser. any other navigation or page change is just being rendered from the already saved application, so a client side application can still function without the internet.

next.jsは、最初に全部loadするわけじゃないけど、prefetchしてるからnavigateするときは、サーバにリクエストを送る必要ない。

```
import Link from 'next/link'
 
export default function PostList({ posts }) {
  return (
    <ul>
      {posts.map((post) => (
        <li key={post.id}>
          <Link href={`/blog/${post.slug}`}>{post.title}</Link>
        </li>
      ))}
    </ul>
  )
}
```

### `UseRouter()` hook

The `useRouter` hook allows you to programmatically change routes from Client Components.
ブラウザのAPI(history API)とかを使っているからクライアントサイドでしか動かない。
別に遷移先はサーバーでもクライアントでもいい。

```
'use client'
 
import { useRouter } from 'next/navigation'
 
export default function Page() {
  const router = useRouter()
 
  return (
    <button type="button" onClick={() => router.push('/dashboard')}>
      Dashboard
    </button>
  )
}
```

Recommendation: Use the <Link> component to navigate between routes unless you have a specific requirement for using useRouter.

多分定義は[ここ](https://github.com/vercel/next.js/blob/canary/packages/next/src/shared/lib/router/router.ts#L989)かな



### `redirect` function
For Server Components, use the redirect function instead.
レスポンスを生成するときにHTMLにmeta tagを生成して返すことで、ブラウザに対してリダイレクトを強制させることができる。

レスポンスの際にmeta tag生成したHTML返す
→ブラウザがmeta tagを見てリダイレクトする。

```
import { redirect } from 'next/navigation'
 
async function fetchTeam(id: string) {
  const res = await fetch('https://...')
  if (!res.ok) return undefined
  return res.json()
}
 
export default async function Profile({ params }: { params: { id: string } }) {
  const team = await fetchTeam(params.id)
  if (!team) {
    redirect('/login')
  }
 
  // ...
}
```

定義は[これ](https://github.com/vercel/next.js/blob/aa90fe9bb779f0a01b663c19ce3bc5e29dc2c80d/packages/next/src/client/components/redirect.ts#L41)かな

```
export function redirect(
  /** The URL to redirect to */
  url: string,
  type: RedirectType = RedirectType.replace
): never {
  const actionStore = actionAsyncStorage.getStore()
  throw getRedirectError(
    url,
    type,
    // If we're in an action, we want to use a 303 redirect
    // as we don't want the POST request to follow the redirect,
    // as it could result in erroneous re-submissions.
    actionStore?.isAction
      ? RedirectStatusCode.SeeOther
      : RedirectStatusCode.TemporaryRedirect
  )
}
```

サーバーサイドでHTMLを操作して、HTTPレスポンスの段階でリダイレクトを行うぽい。メタタグが挿入されて、ブラウザがページの自動リフレッシュとリダイレクトを実行し、ユーザーを指定されたURLに遷移させることができるらしい。

### Using the native History API
- `window.history.pushState`
Use it to add a new entry to the browser's history stack. The user can navigate back to the previous state. For example, to sort a list of products:

```
'use client'
 
import { useSearchParams } from 'next/navigation'
 
export default function SortProducts() {
  const searchParams = useSearchParams()
 
  function updateSorting(sortOrder: string) {
    const params = new URLSearchParams(searchParams.toString())
    params.set('sort', sortOrder)
    window.history.pushState(null, '', `?${params.toString()}`)
  }
 
  return (
    <>
      <button onClick={() => updateSorting('asc')}>Sort Ascending</button>
      <button onClick={() => updateSorting('desc')}>Sort Descending</button>
    </>
  )
}
```

ブラウザのurlが変わるだけで、ページのロードは行われないぽい。