๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

Next.js

[๋‚ด๋ณด๋‚ด๋ฒˆ] Next.js docs - Routing

๋‚ด๋ณด๋‚ด๋ฒˆ(๋‚ด๊ฐ€ ๋ณด๋ ค๊ณ  ๋‚ด๊ฐ€ ๋ฒˆ์—ญํ•œ...) Next.js docs

2021๋…„ 3์›” 30์ผ ๊ธฐ์ค€ Next.js ๊ณต์‹ ๋ฌธ์„œ๋ฅผ ๋ฒˆ์—ญํ–ˆ๋‹ค.

โ€ป ์˜์–ด ์ „๊ณต์ž๋„ ํ•ด์™ธ ์œ ํ•™ํŒŒ๋„ ์•„๋‹ˆ๊ธฐ์— ๋ฒˆ์—ญ์—๋Š” ์˜์—ญ, ์˜ค์—ญ, ๊ตฌ๊ธ€ ๋ฒˆ์—ญ์ด ๋ฌด์ˆ˜ํžˆ ๋งŽ์„ ์ˆ˜ ์žˆ์œผ๋ฉฐ, ํ˜ผ์ž ๊ณต์‹๋ฌธ์„œ๋ฅผ ์ฐธ์กฐํ•ด๊ฐ€๋ฉฐ ๋ฒˆ์—ญํ•˜๋‹ค ๋ณด๋‹ˆ ์˜คํƒ€๋„ ๋งŽ์„ ์ˆ˜ ์žˆ๋‹ค. ์ •ํ™•ํ•œ ๋‚ด์šฉ์€ ๊ณต์‹๋ฌธ์„œ๋ฅผ ์ง์ ‘ ์‚ดํŽด๋ณด๊ฑฐ๋‚˜ ๋‹ค๋ฅธ ์ •๋ณด๋“ค์„ ๋” ์ฐพ์•„๋ณด๋Š” ๊ฒƒ์„ ์ถ”์ฒœํ•œ๋‹ค.

(ํ•˜์ง€๋งŒ ๋Œ“๊ธ€ ํ”ผ๋“œ๋ฐฑ๋„ ํ™˜์˜ํ•ฉ๋‹ˆ๋‹ค๐Ÿ˜ƒ )

Next.js ๊ณต์‹๋ฌธ์„œ ํ™•์ธํ•˜๊ธฐ>>


Introduction

Next.js has a file-system based router built on the concept of pages.

When a file is added to the pages directory it's automatically available as a route.

The files inside the pages directory can be used to define most common patterns.

Next.js์—๋Š” ํŽ˜์ด์ง€ ๊ฐœ๋…์„ ๊ธฐ๋ฐ˜์œผ๋กœ ๊ตฌ์ถ• ๋œ ํŒŒ์ผ ์‹œ์Šคํ…œ ๊ธฐ๋ฐ˜ ๋ผ์šฐํ„ฐ๊ฐ€ ์žˆ๋‹ค. 

ํŒŒ์ผ์ด pages ๋””๋ ‰ํ„ฐ๋ฆฌ์— ์ถ”๊ฐ€๋˜๋ฉด ์ž๋™์œผ๋กœ ๊ฒฝ๋กœ ์ ‘๊ทผ์ด ๊ฐ€๋Šฅํ•ด์ง„๋‹ค.

ํŒŒ์ผ ๋””๋ ‰ํ„ฐ๋ฆฌ ๋‚ด๋ถ€์˜ ํŒŒ์ผ๋“ค์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ€์žฅ ์ผ๋ฐ˜์ ์ธ ํŒจํ„ด์„ ์ •์˜ํ•  ์ˆ˜ ์žˆ๋‹ค. 

Index routes

The router will automatically route files named index to the root of the directory.
๋ผ์šฐํ„ฐ๋Š” index๋ผ๋Š” ํŒŒ์ผ์„ ๋””๋ ‰ํ„ฐ๋ฆฌ์˜ ๋ฃจํŠธ๋กœ ์ž๋™ ๋ผ์šฐํŒ…ํ•ด์ค€๋‹ค.

  • pages/index.js → /
  • pages/blog/index.js → /blog

Nested routes

The router supports nested files. If you create a nested folder structure files will be automatically routed in the same way still. ๋ผ์šฐํ„ฐ๋Š” ์ค‘์ฒฉ๋œ ํŒŒ์ผ๋“ค์— ๋Œ€ํ•ด์„œ๋„ ์ง€์›ํ•œ๋‹ค. ์ค‘์ฒฉ๋œ ํด๋” ๊ตฌ์กฐ๋ฅผ ๋งŒ๋“ค์–ด๋„ ํŒŒ์ผ๋“ค์€ ๊ฐ™์€ ๋ฐฉ๋ฒ•์œผ๋กœ ์ž๋™ ๋ผ์šฐํŒ… ๋  ๊ฒƒ์ด๋‹ค.

  • pages/blog/first-post.js → /blog/first-post
  • pages/dashboard/settings/username.js → /dashboard/settings/username

Dynamic route segments

To match a dynamic segment you can use the bracket syntax. This allows you to match named parameters.
๋™์ ์ธ ์„ธ๊ทธ๋จผํŠธ๋ฅผ ์ผ์น˜์‹œํ‚ค๊ธฐ ์œ„ํ•ด์„œ ๋Œ€๊ด„ํ˜ธ ๊ตฌ๋ฌธ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๋ช…๋ช…๋œ ํŒŒ๋ผ๋ฏธํ„ฐ๋“ค๊ณผ ์ผ์น˜์‹œํ‚ฌ ์ˆ˜ ์žˆ๋‹ค.

  • pages/blog/[slug].js → /blog/:slug (/blog/hello-world)
  • pages/[username]/settings.js → /:username/settings (/foo/settings)
  • pages/post/[...all].js → /post/* (/post/2020/id/title)

Check out the Dynamic Routes documentation to learn more about how they work.
์–ด๋–ป๊ฒŒ ๋™์ž‘ํ•˜๋Š”์ง€ ํ™•์ธํ•˜๋ ค๋ฉด Dynamic Routes ๋ฌธ์„œ๋ฅผ ํ™•์ธํ•˜๋ผ.

Linking between pages

The Next.js router allows you to do client-side route transitions between pages, similar to a single-page application.

A React component called Link is provided to do this client-side route transition.

Next.js ๋ผ์šฐํ„ฐ๋Š” ํŽ˜์ด์ง€ ๊ฐ„์˜ ํด๋ผ์ด์–ธํŠธ ์ธก ๊ฒฝ๋กœ ์ „ํ™˜์ด ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•ด์ค€๋‹ค. ์‹ฑ๊ธ€ ํŽ˜์ด์ง€ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜๊ณผ ๋น„์Šทํ•˜๋‹ค.

Link๋ผ๋Š” ๋ฆฌ์•กํŠธ ์ปดํฌ๋„ŒํŠธ๋Š” ์ด๋Ÿฌํ•œ ํด๋ผ์ด์–ธํŠธ ์ธก ๊ฒฝ๋กœ ์ „ํ™˜์„ ์ œ๊ณตํ•ด์ค€๋‹ค.

 

In the example above we have multiple links, each one maps a path (href) to a known page:
์œ„์˜ ์˜ˆ์ œ์—์„œ ๋‹ค์ˆ˜์˜ ๋งํฌ๋“ค์ด ์žˆ๊ณ  ๊ฐ ๋งํฌ๋Š” ์•Œ๋ ค์ ธ ์žˆ๋Š” ํŽ˜์ด์ง€๋กœ ๋งคํ•‘๋˜์–ด์žˆ๋‹ค.

  • / → pages/index.js
  • /about → pages/about.js
  • /blog/hello-world → pages/blog/[slug].js

Any <Link /> in the viewport (initially or through scroll) will be prefetched by default (including the corresponding data) for pages using Static Generation. The corresponding data for server-rendered routes is not prefetched.

๋ทฐํฌํŠธ(์ดˆ๊ธฐ์ด๊ฑฐ๋‚˜ ์Šคํฌ๋กค์„ ํ†ตํ•ด์„œ ์ด๊ฑฐ๋‚˜) ๋‚ด๋ถ€์— ์žˆ๋Š” ์–ด๋– ํ•œ <Link />์ด๋“  ์ •์  ์ƒ์„ฑ์„ ์‚ฌ์šฉํ•˜์—ฌ ํŽ˜์ด์ง€๋ฅผ ์œ„ํ•ด ๊ธฐ๋ณธ์ ์œผ๋กœ (ํ•ด๋‹นํ•˜๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ํฌํ•จํ•˜์—ฌ) ๋จผ์ € ํŒจ์น˜๋  ๊ฒƒ์ด๋‹ค. ์„œ๋ฒ„ ๋ Œ๋”๋ง ๊ฒฝ๋กœ์— ํ•ด๋‹นํ•˜๋Š” ๋ฐ์ดํ„ฐ๋Š” ๋จผ์ € ํŒจ์น˜๋˜์ง€ ์•Š๋Š”๋‹ค.

Linking to dynamic paths

You can also use interpolation to create the path, which comes in handy for dynamic route segments. For example, to show a list of posts which have been passed to the component as a prop:

๊ฒฝ๋กœ๋ฅผ ์ƒ์„ฑํ•˜๊ธฐ ์œ„ํ•ด์„œ interpolation(${link}์ด๋Ÿฌํ•œ ํ˜•ํƒœ)์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ ์ด๋ ‡๊ฒŒ ํ•˜๋Š” ๊ฒƒ์€ ๋™์  ๊ฒฝ๋กœ ์„ธ๊ทธ๋จผํŠธ๋“ค์— ์œ ์šฉํ•˜๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ์ปดํฌ๋„ŒํŠธ์— prop์œผ๋กœ ์ „๋‹ฌ๋˜์–ด์ง„ ํฌ์ŠคํŠธ ๋ฆฌ์ŠคํŠธ๋“ค์„ ๋ณด์—ฌ์ฃผ๋Š” ๊ฒƒ๊ณผ ๊ฐ™์€ ๊ฒฝ์šฐ.

encodeURIComponent is used in the example to keep the path utf-8 compatible.

์ด ์˜ˆ์ œ์— ์‚ฌ์šฉ๋œ encodeURIComponent๋Š” ๊ฒฝ๋กœ๋ฅผ utf-8 ํ˜ธํ™˜๊ฐ€๋Šฅํ•˜๊ฒŒ ์œ ์ง€ํ•ด์ค€๋‹ค.

Alternatively, using a URL Object:

๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด URL ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ๋‹ค.

Now, instead of using interpolation to create the path, we use a URL object in href where:

  • pathname is the name of the page in the pages directory. /blog/[slug] in this case.
  • query is an object with the dynamic segment. slug in this case.

๊ฒฝ๋กœ๋ฅผ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด์„œ interpolation์„ ์‚ฌ์šฉํ•˜๋Š” ๋Œ€์‹  href์— URL ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•˜์˜€๋‹ค.

  • pathname์€ pages ๋””๋ ‰ํ„ฐ๋ฆฌ์— ์žˆ๋Š” ํŽ˜์ด์ง€์˜ ์ด๋ฆ„์ด๋‹ค. ์ด ๊ฒฝ์šฐ์—๋Š” /blog/[slug]์ด๋‹ค.
  • query๋Š” ๋™์  ์„ธ๊ทธ๋จผํŠธ๊ฐ€ ์žˆ๋Š” ๊ฐ์ฒด์ด๋‹ค. ์ด ๊ฒฝ์šฐ์—๋Š” slug์ด๋‹ค.

Injecting the router

To access the [router object](https://nextjs.org/docs/api-reference/next/router#router-object) in a React component you can use [useRouter](<https://nextjs.org/docs/api-reference/next/router#userouter>) or [withRouter](<https://nextjs.org/docs/api-reference/next/router#withrouter>).

In general we recommend using [useRouter](<https://nextjs.org/docs/api-reference/next/router#userouter>).

๋ฆฌ์•กํŠธ ์ปดํฌ๋„ŒํŠธ์˜ router ๊ฐ์ฒด์— ์ ‘๊ทผํ•˜๊ธฐ ํ•˜๋ ค๋ฉด useRouter ํ˜น์€ withRouter๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

๋ณดํ†ต์€ useRouter๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์„ ์ถ”์ฒœํ•œ๋‹ค.

Dynamic Routes

Defining routes by using predefined paths is not always enough for complex applications. In Next.js you can add brackets to a page ([param]) to create a dynamic route (a.k.a. url slugs, pretty urls, and others).

๋จผ์ € ์ •์˜๋œ ๊ฒฝ๋กœ๋งŒ ์‚ฌ์šฉํ•ด์„œ ๋ผ์šฐํŠธ๋ฅผ ์ •์˜ํ•˜๋Š” ๊ฒƒ์€ ๋ณต์žกํ•œ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์—๋„ ํ•ญ์ƒ ์ถฉ๋ถ„ํ•œ ๊ฒƒ์€ ์•„๋‹ˆ๋‹ค. Next.js์—์„œ๋Š” ๋™์  ๋ผ์šฐํŠธ๋ฅผ ์ƒ์„ฑํ•˜๋ ค๋ฉด ํŽ˜์ด์ง€์— ๋Œ€๊ด„ํ˜ธ๋ฅผ ๋”ํ•ด์ฃผ๋ฉด ๋œ๋‹ค.

Consider the following page pages/post/[pid].js:

์•„๋ž˜์˜ pages/post/[pid].js๋ผ๋Š” ํŽ˜์ด์ง€๋ฅผ ์‚ดํŽด๋ณด์ž:

Any route like /post/1, /post/abc, etc. will be matched by pages/post/[pid].js. The matched path parameter will be sent as a query parameter to the page, and it will be merged with the other query parameters.

/post/1, /post/abc์™€ ๊ฐ™์€ ์–ด๋–ค ๋ผ์šฐํŠธ๋กœ pages/post/[pid].js์™€ ๋งค์น˜๋  ๊ฒƒ์ด๋‹ค. ๋งค์น˜๋œ ๊ฒฝ๋กœ ํŒŒ๋ผ๋ฏธํ„ฐ๋Š” ์ฟผ๋ฆฌ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ํŽ˜์ด์ง€์— ์ „์†ก๋  ๊ฒƒ์ด๊ณ  ๋‹ค๋ฅธ ์ฟผ๋ฆฌ ํŒŒ๋ผ๋ฏธํ„ฐ์™€ ํ•จ๊ป˜ ํ•ฉ์ณ์งˆ ๊ฒƒ์ด๋‹ค.

For example, the route /post/abc will have the following query object:

์˜ˆ๋ฅผ ๋“ค์–ด /post/abc/ ๋ผ์šฐํŠธ๋Š” ์•„๋ž˜์™€ ๊ฐ™์€ ์ฟผ๋ฆฌ ๊ฐ์ฒด๋ฅผ ๊ฐ–๋Š”๋‹ค:

Similarly, the route /post/abc?foo=bar will have the following query object:

๋น„์Šทํ•˜๊ฒŒ /post/abc?foo=bar ๋ผ์šฐํŠธ๋Š” ์•„๋ž˜์™€ ๊ฐ™์€ ์ฟผ๋ฆฌ ๊ฐ์ฒด๋ฅผ ๊ฐ–๋Š”๋‹ค:

However, route parameters will override query parameters with the same name. For example, the route /post/abc?pid=123 will have the following query object:

ํ•˜์ง€๋งŒ ๊ฐ™์€ ์ด๋ฆ„์„ ๊ฐ€์ง„ ์ฟผ๋ฆฌ ํŒŒ๋ผ๋ฏธํ„ฐ๋Š” ๋ผ์šฐํŠธ ํŒŒ๋ผ๋ฏธํ„ฐ๊ฐ€ ๋ฎ์–ด์“ธ ๊ฒƒ์ด๋‹ค. ์˜ˆ๋ฅผ ๋“ค๋ฉด /post/abc/abc?pid=123๋ผ๋Š” ๋ผ์šฐํŠธ๋Š” ์•„๋ž˜์™€ ๊ฐ™์€ ์ฟผ๋ฆฌ ๊ฐ์ฒด๋ฅผ ๊ฐ–๋Š”๋‹ค.

Multiple dynamic route segments work the same way. The page pages/post/[pid]/[comment].js will match the route /post/abc/a-comment and its query object will be:

๋‹ค์ค‘ ๋™์  ๋ผ์šฐํŠธ ์„ธ๊ทธ๋จผํŠธ๋„ ๊ฐ™์€ ๋ฐฉ๋ฒ•์œผ๋กœ ๋™์ž‘ํ•œ๋‹ค. pages/post/[pid]/[comment].js ํŽ˜์ด์ง€๋Š” /post/abc/a-comment์™€ ๋งค์น˜๋  ๊ฒƒ์ด๊ณ  ์ฟผ๋ฆฌ ๊ฐ์ฒด๋Š” ์•„๋ž˜์™€ ๊ฐ™๋‹ค:

Client-side navigations to dynamic routes are handled with next/link. If we wanted to have links to the routes used above it will look like this:

๋™์  ๊ฒฝ๋กœ์— ๋Œ€ํ•œ ํด๋ผ์ด์–ธํŠธ ์ธก ๋„ค๋น„๊ฒŒ์ด์…˜์€ next/link๋กœ ์ฒ˜๋ฆฌ๋œ๋‹ค. ์œ„์— ๋‚˜์˜จ ๊ฒฝ๋กœ๋“ค์— ๋Œ€ํ•œ ๋งํฌ๋“ค์„ ์›ํ•  ๋•Œ ์•„๋ž˜์™€ ๊ฐ™์ด ๋ณด์—ฌ์งˆ ๊ฒƒ์ด๋‹ค:

Read our docs for Linking between pages to learn more.

๋” ์•Œ์•„๋ณด๋ ค๋ฉด Linking between pages๋ฅผ ์œ„ํ•œ ํŽ˜์ด์ง€๋ฅผ ์ฝ์–ด๋ณด๋ผ.

Catch all routes

Dynamic routes can be extended to catch all paths by adding three dots (...) inside the brackets. For example:

  • pages/post/[...slug].js matches /post/a, but also /post/a/b, /post/a/b/c and so on.

๋™์  ๊ฒฝ๋กœ๋Š” ์  3๊ฐœ๋ฅผ (...) ๋Œ€๊ด„ํ˜ธ ์•ˆ์— ์ถ”๊ฐ€ํ•˜์—ฌ ๋ชจ๋“  ๊ฒฝ๋กœ๋ฅผ ๋‹ค ํฌํ•จํ•˜๋„๋ก ํ™•์žฅ๋  ์ˆ˜ ์žˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค๋ฉด:

  • pages/post/[...slug].js ๋Š”  /post/a ์— ๋งค์นญ๋˜์ง€๋งŒ,  /post/a/b, /post/a/b/c ๋„ ๋ชจ๋‘ ๋งค์นญ๋œ๋‹ค.

Note: You can use names other than slug, such as: [...param]

๋…ธํŠธ: slug๋ง๊ณ ๋„ [...param]๊ณผ ๊ฐ™์€ ๋‹ค๋ฅธ ์ด๋ฆ„์„ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ๋‹ค.

 

Matched parameters will be sent as a query parameter (slug in the example) to the page, and it will always be an array, so, the path /post/a will have the following query object:

๋งค์น˜๋˜๋Š” ํŒŒ๋ผ๋ฏธํ„ฐ๋“ค์€ ์ฟผ๋ฆฌ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ํŽ˜์ด์ง€๋กœ ๋ณด๋‚ด์งˆ ๊ฒƒ์ด๋‹ค. (์˜ˆ์‹œ์— ๋‚˜์˜ค๋Š” slug) ํŒŒ๋ผ๋ฏธํ„ฐ๋Š” ํ•ญ์ƒ ๋ฐฐ์—ด์ด๋‹ค. /post/a ๋Š” ์•„๋ž˜์™€ ๊ฐ™์€ ์ฟผ๋ฆฌ ๊ฐ์ฒด๋ฅผ ๊ฐ–๋Š”๋‹ค.

And in the case of /post/a/b, and any other matching path, new parameters will be added to the array, like so:

๊ทธ๋ฆฌ๊ณ  /post/a/b์˜ ๊ฒฝ์šฐ์—๋Š” ๋˜ ๋‹ค๋ฅธ ๋งค์น˜๋˜๋Š” ๊ฒฝ๋กœ๋กœ ์ƒˆ๋กœ์šด ํŒŒ๋ผ๋ฏธํ„ฐ๋Š” ๋ฐฐ์—ด์— ์ด์ฒ˜๋Ÿผ ์ถ”๊ฐ€๋  ๊ฒƒ์ด๋‹ค.:

Optional catch all routes

Catch all routes can be made optional by including the parameter in double brackets ([[...slug]]).

For example, pages/post/[[...slug]].js will match /post, /post/a, /post/a/b, and so on.

The main difference between catch all and optional catch all routes is that with optional, the route without the parameter is also matched (/post in the example above).

The query objects are as follows:

์ด์ค‘ ๊ด„ํ˜ธ ์•ˆ์— ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ํฌํ•จํ•˜์—ฌ ๋ชจ๋“  ๋ผ์šฐํŠธ๋ฅผ ์„ ํƒ์ ์œผ๋กœ ํฌํ•จํ•  ์ˆ˜ ์žˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค๋ฉด pages/post/[[...slug]].js ๋Š” /post, /post/a, /post/a/b ๋ชจ๋‘ ๋งค์น˜๋  ๊ฒƒ์ด๋‹ค.

๋ชจ๋“  ๊ฒฝ๋กœ๋ฅผ ํฌํ•จํ•˜๋Š” ๊ฒƒ๊ณผ ์„ ํƒ์ ์œผ๋กœ ๋ชจ๋“  ๊ฒฝ๋กœ๋ฅผ ํฌํ•จํ•˜๋Š” ๊ฒƒ์˜ ์ฃผ๋œ ์ฐจ์ด์ ์€ ํŒŒ๋ผ๋ฏธํ„ฐ๊ฐ€ ์—†๋Š” ๊ฒฝ๋กœ๋„ ๋งค์น˜๊ฐ€ ๋œ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค. (์œ„์˜ ์˜ˆ์‹œ์— ๋‚˜์˜ค๋Š” /post์™€ ๊ฐ™์€ ๊ฒƒ)

์ฟผ๋ฆฌ ๊ฐ์ฒด๋Š” ์•„๋ž˜์™€ ๊ฐ™๋‹ค:

Caveats

  • Predefined routes take precedence over dynamic routes, and dynamic routes over catch all routes. Take a look at the following examples:
    ์‚ฌ์ „ ์ •์˜๋œ ๊ฒฝ๋กœ๋Š” ๋™์  ๊ฒฝ๋กœ๋ณด๋‹ค ์šฐ์œ„์ด๋ฉฐ ๋™์  ๊ฒฝ๋กœ๋Š” ๋ชจ๋“  ๊ฒฝ๋กœ๋ฅผ ํฌ์ฐฉํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค ์šฐ์œ„์ด๋‹ค. ์•„๋ž˜์˜ ์˜ˆ์‹œ๋“ค์„ ๋ณด๋ผ:
    • pages/post/create.js - Will match /post/create
    • pages/post/[pid].js - Will match /post/1, /post/abc, etc. But not /post/create
    • pages/post/[...slug].js - Will match /post/1/2, /post/a/b/c, etc. But not /post/create, /post/abc
  • Pages that are statically optimized by Automatic Static Optimization will be hydrated without their route parameters provided, i.e query will be an empty object ({}).
    Automatic Static Optimization์— ์˜ํ•ด ์ •์ ์œผ๋กœ ์ตœ์ ํ™”๋œ ํŽ˜์ด์ง€๋Š” ์ œ๊ณต๋œ ๊ฒฝ๋กœ ํŒŒ๋ผ๋ฏธํ„ฐ์—†์ด hydrate๋  ๊ฒƒ์ด๋‹ค. query๋Š” ๋นˆ ๊ฐ์ฒด์ผ ๊ฒƒ์ด๋‹ค.
  • After hydration, Next.js will trigger an update to your application to provide the route parameters in the query object.
    hydration* ํ›„์— Next.js๋Š” ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜ ์—…๋ฐ์ดํ„ฐ๋ฅผ ํŠธ๋ฆฌ๊ฑฐํ•˜์—ฌ ์ฟผ๋ฆฌ ๊ฐ์ฒด์— ๊ฒฝ๋กœ ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ์ œ๊ณตํ•œ๋‹ค.*Hydration: Each generated HTML is associated with minimal JavaScript code necessary for that page. When a page is loaded by the browser, its JavaScript code runs and makes the page fully interactive. (This process is called hydration.)
    ๊ฐ ์ƒ์„ฑ๋œ HTML ํŽ˜์ด์ง€ (ํŽ˜์ด์ง€์— ํ•„์š”ํ•œ ์ตœ์†Œํ•œ์˜ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์ฝ”๋“œ์™€ ์—ฐ๊ฒฐ๋˜์–ด ์žˆ๋Š”)๊ฐ€ ๋ธŒ๋ผ์šฐ์ €์— ๋กœ๋“œ๋˜๋ฉด ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์ฝ”๋“œ๊ฐ€ ์‹คํ–‰๋˜๊ณ  ํŽ˜์ด์ง€๊ฐ€ ์™„์ „ํžˆ ์ธํ„ฐ๋ž™ํ‹ฐ๋ธŒํ•˜๊ฒŒ ๋˜๋Š” ๊ณผ์ •.

Imperatively

next/link should be able to cover most of your routing needs, but you can also do client-side navigations without it, take a look at the documentation for next/router.

The following example shows how to do basic page navigations with useRouter:

next/link๊ฐ€ routing์— ํ•„์š”ํ•œ ๊ฑฐ์˜ ๋Œ€๋ถ€๋ถ„์˜ ๊ฒƒ์„ ์ปค๋ฒ„ํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•˜์ง€๋งŒ next/link ์—†์ด ํด๋ผ์ด์–ธํŠธ ์ธก์—์„œ ์ด๋™ํ•˜๋Š” ๊ฒƒ๋„ ๊ฐ€๋Šฅํ•˜๋‹ค. next/router ๋ฌธ์„œ๋ฅผ ์ฐธ์กฐํ•˜๋ผ.

์•„๋ž˜์˜ ์˜ˆ์ œ๋Š” useRouter๋กœ ์–ด๋–ป๊ฒŒ ๊ธฐ๋ณธ์ ์ธ ํŽ˜์ด์ง€ ๋„ค๋น„๊ฒŒ์ด์…˜์ด ๊ฐ€๋Šฅํ•œ์ง€ ๋ณด์—ฌ์ค€๋‹ค.

Shallow Routing

Shallow routing allows you to change the URL without running data fetching methods again, that includes [getServerSideProps](<https://nextjs.org/docs/basic-features/data-fetching#getserversideprops-server-side-rendering>), [getStaticProps](<https://nextjs.org/docs/basic-features/data-fetching#getstaticprops-static-generation>), and [getInitialProps](<https://nextjs.org/docs/api-reference/data-fetching/getInitialProps>).

You'll receive the updated pathname and the query via the [router object](https://nextjs.org/docs/api-reference/next/router#router-object) (added by [useRouter](<https://nextjs.org/docs/api-reference/next/router#userouter>) or [withRouter](<https://nextjs.org/docs/api-reference/next/router#withrouter>)), without losing state.

To enable shallow routing, set the shallow option to true. Consider the following example:

Shallow routing์€ getServerSideProps, getStaticProps, getInitalProps ๊ฐ™์€ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ๋ฉ”์†Œ๋“œ๋ฅผ ๋‹ค์‹œ ๋™์ž‘์‹œํ‚ค์ง€ ์•Š๊ณ ๋„ URL ๋ณ€๊ฒฝ์„ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•ด์ค€๋‹ค.

์—…๋ฐ์ดํŠธ๋œ pathname๊ณผ query๋ฅผ ์ƒํƒœ๋ฅผ ์žƒ์ง€์•Š๊ณ  router ๊ฐ์ฒด๋ฅผ ํ†ตํ•ด์„œ(useRouter๋‚˜ withRouter์— ์˜ํ•ด ์ถ”๊ฐ€๋œ) ๋ฐ›์„ ๊ฒƒ์ด๋‹ค.

Shallow routing์„ ์‚ฌ์šฉํ•˜๋ ค๋ฉด shallow ์˜ต์…˜์„ true๋กœ ์ฃผ์–ด์•ผํ•œ๋‹ค. ์•„๋ž˜์˜ ์˜ˆ์ œ๋ฅผ ๊ณ ๋ คํ•ด๋ณด๋ผ:

The URL will get updated to /?counter=10. and the page won't get replaced, only the state of the route is changed.

You can also watch for URL changes via componentDidUpdate as shown below:

URL์€ conter=10์œผ๋กœ ์—…๋ฐ์ดํŠธ ๋  ๊ฒƒ์ด๋‹ค. ํŽ˜์ด์ง€๋Š” ๋Œ€์ฒด๋˜์ง€ ์•Š์„ ๊ฒƒ์ด๊ณ  ๋ผ์šฐํŠธ์˜ ์ƒํƒœ๋งŒ ๋ณ€๊ฒฝ๋  ๊ฒƒ์ด๋‹ค.

์•„๋ž˜์™€ ๊ฐ™์ด URL์ด ๋ณ€๊ฒฝ๋˜๋Š” ๊ฒƒ์„ componentDidUpdate๋ฅผ ํ†ตํ•ด์„œ๋„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค

Caveats

Shallow routing only works for same page URL changes. For example, let's assume we have another page called pages/about.js, and you run this:

Shallow routing์€ ๋™์ผํ•œ ํŽ˜์ด์ง€์˜ URL ๋ณ€๊ฒฝ์— ๋Œ€ํ•ด์„œ๋งŒ ๋™์ž‘ํ•œ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด pages/about.js ๋ผ๋Š” ๋‹ค๋ฅธ ํŽ˜์ด์ง€๊ฐ€ ์žˆ๋‹ค๊ณ  ํ•˜๊ณ  ์ด๊ฒƒ์„ ์‹คํ–‰ํ•˜๋ฉด:

Since that's a new page, it'll unload the current page, load the new one and wait for data fetching even though we asked to do shallow routing.

์ด๊ฒƒ์€ ์ƒˆ๋กœ์šด ํŽ˜์ด์ง€์ด๊ธฐ ๋•Œ๋ฌธ์— ํ˜„์žฌ ํŽ˜์ด์ง€๋Š” ์–ธ๋กœ๋“œ๋˜๊ณ  ์ƒˆ๋กœ์šด ํŽ˜์ด์ง€๊ฐ€ ๋กœ๋“œ๋˜๊ณ  shallow routing์„ ์š”์ฒญํ•˜๊ธด ํ–ˆ์ง€๋งŒ ๋ฐ์ดํ„ฐ๊ฐ€ ํŒจ์น˜๋˜๋Š” ๊ฒƒ์„ ๊ธฐ๋‹ค๋ฆด ๊ฒƒ์ด๋‹ค.