๐ŸŒ€ ํ”„๋ก ํŠธ์—”๋“œ ๊ฐœ๋ฐœ ํ”„๋ ˆ์ž„์›Œํฌ NextJs๋ฅผ ์“ฐ๋Š” ์ด์œ  / ๊ธฐ์ดˆ ํ•™์Šต ์ •๋ฆฌ

leehyunjuยท2023๋…„ 2์›” 3์ผ
27
post-thumbnail

๐Ÿค” ์™œ NextJS๋ฅผ ์‚ฌ์šฉํ• ๊นŒ ?

  1. ๊ฐœ๋ฐœํ™˜๊ฒฝ / ์ฝ”๋“œ๋ถ„ํ•  / ํŒŒ์ผ ๊ธฐ๋ฐ˜ ๊ตฌ์กฐ ๋“ฑ ๋‹ค์–‘ํ•œ ๊ธฐ๋Šฅ๋“ค์„ ์ œ๊ณตํ•ด์ค€๋‹ค.
  2. SEO ๊ฒ€์ƒ‰ ์—”์ง„ ์ตœ์ ํ™” (์‚ฌ์šฉ์ž๋“ค์ด ํ›จ์”ฌ ๋” ์‰ฝ๊ฒŒ ์›น ์„œ๋น„์Šค๋ฅผ ์ฐพ์•„๊ฐˆ ์ˆ˜ ์žˆ๋„๋ก ์ œ๊ณต)
  3. ํ”„๋ก ํŠธ์—”๋“œ์— ํ•„์š”ํ•œ ๊ฐ„๋‹จํ•œ API ๊ตฌ์„ฑ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.
  4. ์†์‰ฌ์šด ๋ฐฐํฌ ์‹œ์Šคํ…œ - Vercel

๐Ÿ‘€ ๊ฐœ๋ฐœ ํ™˜๊ฒฝ / ์ฝ”๋“œ๋ถ„ํ•  / ํŒŒ์ผ ๊ธฐ๋ฐ˜ ๊ตฌ์กฐ ๋“ฑ์˜ ๋‹ค์–‘ํ•œ ๊ธฐ๋Šฅ ์ œ๊ณต์ด๋ž€ ?

  1. Page-based routing system (with ๋‹ค์ด๋‚˜๋ฏน ๋ผ์šฐํŠธ)
    • /pages/ ๋””๋ ‰ํ† ๋ฆฌ๊ฐ€ url ๋ฃจํŠธ์—์„œ ๋ผ์šฐํŒ… ํ•˜๋Š”๋ฐ ๊ธฐ๋ณธ์ด๋‹ค.
    • ๋‹ค์ด๋‚˜๋ฏน ๋ผ์šฐํŒ…์„ ํ•˜๋ ค๋ฉด /pages/product/[slug] ์ด๋ ‡๊ฒŒ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค. ํŒŒ์ผ๊ฒฝ๋กœ ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ๋””๋ ‰ํ† ๋ฆฌ ๊ฒฝ๋กœ๋„ ๋‹ค์ด๋‚˜๋ฏนํ•˜๊ฒŒ path๋ฅผ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๋‹ค.
  2. Pre-rendering - SSR / SSG
    • ์„œ๋ฒ„ ์‚ฌ์ด๋“œ ๋ Œ๋”๋ง์ด ๊ฐ€๋Šฅํ•˜๋‹ค.
  3. Automatic code splitting for faster page loads
    • ํŒŒ์ผ์„ ํ•˜๋‚˜๋กœ ๋งŒ๋“ค ์ˆ˜๋„ ์žˆ๊ณ  ์ชผ๊ฐœ์„œ ๋งŒ๋“ค ์ˆ˜๋„ ์žˆ๋‹ค. Next๋Š” ์•Œ์•„์„œ ํŒŒ์ผ์„ ์ชผ๊ฐœ์ค€๋‹ค. ๊ทธ๋ž˜์„œ ๐ŸŒŸ ํŽ˜์ด์ง€๋ฅผ ๋น ๋ฅด๊ฒŒ ๋กœ๋“œํ•  ์ˆ˜ ์žˆ์—ˆ๋˜ ๊ฒƒ ๐ŸŒŸ์ด๋‹ค.
  4. Client-side routing with optimized prefetching
    • prefetching์„ ํ†ตํ•ด ์„ฑ๋Šฅ์ ์œผ๋กœ ์ตœ์ ํ™” ๊ฐ€๋Šฅ.
  5. ํŽธ๋ฆฌํ•œ API Routes
  6. ์ฝ”๋“œ๋“ค์€ ๊ณ ์น˜๋Š”๋Œ€๋กœ ๋ณ€๊ฒฝ ๋œ๋‹ค. (= Fast Refrash)

์ด๋Ÿฐ ๋‹ค์–‘ํ•œ ๊ธฐ๋Šฅ ์ œ๊ณต์œผ๋กœ ์ธํ•ด NextJS๋ฅผ ์„ ํƒํ•˜๋Š” ์ด์œ ๋‹ค.


Next.js ํ”„๋กœ์ ํŠธ ์ƒ์„ฑ (Next.js + Typescript)

๋ช…๋ น์–ด

npx create-next-app "[ํ”„๋กœ์ ํŠธ๋ช…]"

// ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ ๋ฒ„์ „
$npx create-next-app --typescript

ํ„ฐ๋ฏธ๋„์— ์•„๋ž˜์™€๊ฐ™์€ ์งˆ๋ฌธ๋“ค์ด ์Ÿ์•„์ง€๋Š”๋ฐ

Would you like to use ESLint with this project? โ€ฆ No / Yes
โœ” Would you like to use Tailwind CSS with this project? โ€ฆ No / Yes
โœ” Would you like to use src/ directory with this project? โ€ฆ No / Yes
โœ” Use App Router (recommended)? โ€ฆ No / Yes
โœ” Would you like to customize the default import alias? โ€ฆ No / Yes

์ด๋ ‡๊ฒŒ ์ฒดํฌํ•˜๋ฉด ์•„๋ž˜์™€ ๊ฐ™์€ Repo ํด๋” ๊ตฌ์„ฑ์ด ์…‹ํŒ…๋œ๋‹ค.

์‹คํ–‰ํ•˜๋Š” ๋ฒ•

npm run dev === yarn dev (๋™์ผ ๋ช…๋ น์–ด)

Prettier

$yarn prettier-fix
  • yarn add -D prettier // prettier ์ถ”๊ฐ€
  • .prettierrc // ํŒŒ์ผ ์ถ”๊ฐ€
  • ํŒจํ‚ค์ง€์— prettier-fix ๋ช…๋ น ์ถ”๊ฐ€

๐ŸŒ€ Data Fetching

  • ํ™”๋ฉด์— ๋ฌด์–ธ๊ฐ€๋ฅผ ๊ทธ๋ฆฌ๋ ค๋ฉด ๊ฒฐ๊ตญ ์–ด๋””์„ ๊ฐ€ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์™€์•ผํ•œ๋‹ค. (์ด๊ฒŒ ํ”„๋ก ํŠธ์˜ ์—ญํ• ์ด๋‹ˆ ใ…Ž)
    Next์—์„œ ์ œ์‹œํ•˜๋Š” ๋ฐ์ดํ„ฐ ํŒจ์นญํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ์ด 4๊ฐ€์ง€ ์•Œ์•„๋ณด์ž.

1. SSR (์„œ๋ฒ„ ์‚ฌ์ด๋“œ ๋ Œ๋”๋ง)

  • ์„œ๋ฒ„๊ฐ€ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์™€์„œ ๊ทธ๋ ค์ค€๋‹ค.
  • getServerSideProps ๋ผ๋Š” ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์„œ๋ฒ„์ชฝ์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ทธ๋ ค์ฃผ๊ฒŒ๋” ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค.
export async function getServerSideProps() {
  console.log('server');

  return {
    props: { time: new Date().toISOString() },
  };
}

์ด์™€๊ฐ™์ด ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ณ , ์ด๋ฅผ ์‚ฌ์šฉํ•˜๊ฒŒ ๋˜๋ฉด ํ„ฐ๋ฏธ๋„์—์„œ 'server'๋ผ๋Š” ๋ฉ”์‹œ์ง€๊ฐ€ ์ฐํžˆ๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

2. CSR (ํด๋ผ์ด์–ธํŠธ ์‚ฌ์ด๋“œ ๋ Œ๋”๋ง)

  • ํด๋ผ์ด์–ธํŠธ๊ฐ€ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์™€์„œ ๊ทธ๋ ค์ค€๋‹ค.
  • ๊ธฐ์กด ๋ฆฌ์•กํŠธ ์‚ฌ์šฉ๋ฒ•๊ณผ ๋™์ผ

  • ํด๋ผ์ด์–ธํŠธ๋Š” ๋ธŒ๋ผ์šฐ์ €์—์„œ ๊ทธ๋ ค์ฃผ๊ธฐ ๋•Œ๋ฌธ์— ์›น๋ธŒ๋ผ์šฐ์ €์— ์žˆ๋Š” ์ฝ˜์†”๋กœ๊ทธ์—์„œ 'Client' ๋ผ๋Š” ๋ฉ”์‹œ์ง€๋ฅผ ํ™•์ธํ•ด๋ณผ ์ˆ˜ ์žˆ๋‹ค.

3. SSG (Static-Site Generation)

  • ์ •์ ์ธ ์‚ฌ์ดํŠธ๋ฅผ ์ƒ์„ฑ : ์ •์ ์ธ ์‚ฌ์ดํŠธ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์™€์„œ ๊ทธ๋ ค์ค€๋‹ค.
  • SSG๋ฅผ ๋‹ด๋‹นํ•˜๋Š” ํ•จ์ˆ˜๋กœ๋Š” getStaticProps ๋ผ๋Š” ํ•จ์ˆ˜๊ฐ€ ์žˆ๋‹ค.
  • ์–ธ์ œ ์“ฐ์ด๋Š”์ง€ ? ๋ธ”๋กœ๊ทธ ๊ฐ™์ด ์ •์ ์ผ ์ˆ˜ ์žˆ๋Š” ๊ฒƒ๋“ค์„ ์ด๊ฒƒ์„ ์‚ฌ์šฉํ•œ๋‹ค.

4. ISG (Incremental Static Regeneration)

  • ์ฆ๋ถ„ ์ •์  ์‚ฌ์ดํŠธ๋ฅผ ์žฌ์ƒ์„ฑ ํ•ด์ค€๋‹ค. ํŠน์ • ์ฃผ๊ธฐ๋กœ ์ •์ ์ธ ์‚ฌ์ดํŠธ์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์™€ ๋‹ค์‹œ ๊ทธ๋ ค์ค€๋‹ค. ์ด๊ฒƒ๋„ SSG์ฒ˜๋Ÿผ getStaticProps ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค.
export async function getStaticProps() {
  console.log("server");

  return {
    props: { time: new Date().toISOString() },
    revalidate: 1, // ๐Ÿ“ 1์ดˆ ๋‹จ์œ„๋กœ => ์ด ํ•จ์ˆ˜๋ฅผ ํ†ตํ•ด์„œ ๊ฐ’์„ ๋ฆฌํ„ดํ•ด์„œ ๋‹ค์‹œ ๊ทธ๋ ค์ค€๋‹ค.
  };
}

์ด์ฒ˜๋Ÿผ revalidate๋ผ๋Š” ํ•จ์ˆ˜์— ์‹œ๊ฐ„๊ฐ’์„ ๋„ฃ์–ด ๋ฆฌํ„ดํ•ด์„œ ๋‹ค์‹œ ๊ทธ๋ ค์ค€๋‹ค. ์ด ๊ธฐ๋Šฅ์€ ์˜ˆ๋ฅผ ๋“ค๋ฉด ์‡ผํ•‘๋ชฐ์—์„œ ์–ด๋–ค ์ƒํ’ˆ์„ ๊ณ„์† ํŒ๋งคํ•˜๊ณ  ๊ทธ ์ƒํ’ˆ์˜ ์ •๋ณด๋ฅผ ๊ณ„์† ์—…๋ฐ์ดํŠธ ํ•œ๋‹ค๊ณ  ํ•  ๋•Œ ์ด ํ•จ์ˆ˜๋ฅผ ์ ์ ˆํ•˜๊ฒŒ ์‚ฌ์šฉํ•ด์„œ ์ž‘์—…ํ•  ์ˆ˜ ์žˆ๋‹ค.

๐ŸŒ€ ๋ผ์šฐํ„ฐ ํ•˜๋Š”๋ฒ•

  • Next์˜ ๋ผ์šฐํ„ฐ๋Š” file-systems์˜ ๊ธฐ๋ฐ˜์ด๋‹ค.
  • /pages/ ๋˜๋Š” /src/pages ํ˜•ํƒœ๋กœ ๋Œ์•„๊ฐ„๋‹ค.
    • /pages/index.js ์™€ /src/pages/index.js ์ด ๋‘ ๊ฐ€์ง€ ๊ฒฝ์šฐ๊ฐ€ ์žˆ๋‹ค๊ณ  ํ–ˆ์„ ๋•Œ, ์šฐ์„  ์ˆœ์œ„๋Š” /pages/index.js ๊ฐ€ ๋จผ์ €๋‹ค. ํ•˜์ง€๋งŒ, ๊ฐœ๋ฐœํ•  ๋•Œ ์ต์ˆ™ํ•œ ํ™˜๊ฒฝ์œผ๋กœ๋Š” /src/pages/ ๋ฃจํŠธ๊ฐ€ ๋” ์ต์ˆ™.. ์•”ํŠผ ์ž‘์—…์ž ํŽธํ•œ๋Œ€๋กœ ํ•˜๋ฉด ๋จ ใ…Žใ…Ž

๐ŸŒ€ ๋‹ค์ด๋‚˜๋ฏน ๋ผ์šฐํŒ… = Slug

  • ๋‹ค์ด๋‚˜๋ฏนํ•˜๊ฒŒ ์œ ๋™์ ์œผ๋กœ path๋ฅผ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๋‹ค.

slug

pages/caategory/[slug].js => /category/:slug (ex. /category/food) ์ด๋Ÿฐ์‹์œผ๋กœ category ๋’ค์— ์•„๋ฌด ๋‹จ์–ด ์ง‘์–ด๋„ฃ์–ด๋„ ํ•ด๋‹น ๊ฒฝ๋กœ๋กœ ์ด๋™๋œ๋‹ค.

pages/[usename]/info.js => /:usename/info (ex. /jimmy/info) ์ด๊ฒƒ๋„ [usename] ๋ถ€๋ถ„์— ์•„๋ฌด ๋‹จ์–ด ์ง‘์–ด๋„ฃ์–ด๋„ ํ•ด๋‹น ๊ฒฝ๋กœ๋กœ ์ด๋™๋œ๋‹ค
  • ํŒŒ์ผ์—๋„ slug๊ฐ€ ๊ฐ€๋Šฅํ•˜๊ณ , ํด๋”์—๋„ ๊ฐ€๋Šฅ

...slug

pages/cart/[...slug].js => /cart/* (ex. /cart/2022/06/04)
  • ...์„ ์‚ฌ์šฉํ•˜๋ฉด depth๊ฐ€ ๋ฌดํ•œ์œผ๋กœ ์‚ฌ์šฉ์ด ๊ฐ€๋Šฅํ•˜๋‹ค. ๋ชจ๋“  ๊ฑธ ๋‹ค ๋ฐ›์•„๋‚ผ ์ˆ˜ ์žˆ๋‹ค๋Š” ๋œป์ด๋‹ค.

๋‹ค์ด๋‚˜๋ฏน ๋ผ์šฐํŠธ

import {useRouter} from 'next/router;

const router = useRouter();
const {slug} = router.query;
  • ์ด์ฒ˜๋Ÿผ router.query์˜ slug๋ฅผ ์“ฐ๋ฉด url์— /category/{slug}์— ์žˆ๋Š” {slug}์— ์ž…๋ ฅํ•œ ๊ฐ’์ด ํ™”๋ฉด์— ์ฐํžŒ๋‹ค.

๐Ÿ–๏ธ Shallow Routing ์ด๋ž€ ?

  • getServerSideProps / getStaticProps ๋“ฑ์„ ๋‹ค์‹œ ์‹คํ–‰์‹œํ‚ค์ง€ ์•Š๊ณ , ํ˜„์žฌ ์ƒํƒœ๋ฅผ ์žƒ์ง€ ์•Š๊ณ  url ๋ณ€๊ฒฝํ•˜๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค.

๐Ÿ–๏ธ Shallow Routing ์˜ˆ์ œ

  • ์‚ฌ์šฉ์ž๊ฐ€ ์–ด๋–ค ๋™์ž‘์„ ํ–ˆ๊ณ  ๊ทธ ๊ธฐ๋ก์„ ์ฟผ๋ฆฌ๋กœ ๋‚จ๊ธฐ๊ณ  ์‹ถ์„๋•Œ

    • ์žฅ์  ๐Ÿ‘‰ ์ฟผ๋ฆฌ๋กœ ๋‚จ๊ธฐ๋ฉด ์‚ฌ์šฉ์ž๊ฐ€ ์ƒˆ๋กœ๊ณ ์นจ์„ ํ•ด๋„ ์œ ์ง€๋œ๋‹ค.
  • ํŠน์ • ํŽ˜์ด์ง€์ธ 10 page์— ๊ฐ”๋‹ค๊ฐ€ ์ƒˆ๋กœ๊ณ ์นจ ํ•ด๋„ ๊ทธ๊ฒŒ ์œ ์ง€๊ฐ€ ๋œ๋‹ค.

    • ๋กœ์ปฌ ์Šคํ† ๋ฆฌ์ง€๋‚˜ ์„ธ์…˜ ์Šคํ† ๋ฆฌ์ง€๋ฅผ ํ†ตํ•ด ์ƒˆ๋กœ๊ณ ์นจ์„ ํ•ด๋„ ํŠน์ • ํŽ˜์ด์ง€์˜ ์œ„์น˜๋ฅผ ์œ ์ง€์‹œํ‚ฌ ์ˆ˜ ์žˆ์ง€๋งŒ ์ฟผ๋ฆฌ๋กœํ•ด๋„ ๊ทธ ์ƒํƒœ๊ฐ€ ์œ ์ง€๋˜๋„๋ก ๊ฐ€๋Šฅํ•˜๋‹ค.

์‚ฌ์šฉ์ž์˜ ํ–‰๋™์„ ๊ธฐ๋กํ•œ ํ–‰์œ„๋“ค์ด๋‹ค. (ํŽ˜์ด์ง€ ์œ„์น˜ ์ด๋™) ๊ทผ๋ฐ URL์„ ๋ฐ”๊ฟจ๋‹ค๊ณ ํ•ด์„œ ํŽ˜์ด์ง€๊ฐ€ ์ฒ˜์Œ๋ถ€ํ„ฐ ๋ Œ๋” ๋œ๋‹ค๊ฑฐ๋‚˜, ์›์น˜ ์•Š๋Š” ๋ฐ์ดํ„ฐ ํŒจ์นญ๊นŒ์ง€ ์ด๋ค„์ง„๋‹ค๋ฉด ๋น„ํšจ์œจ์ ์ผ ์ˆ˜๊ฐ€ ์žˆ๋‹ค. ๊ทธ๋ž˜์„œ ์ด๋ฅผ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ๐ŸŒŸShallow Routing๐ŸŒŸ์ด ํ•„์š”ํ•œ ๊ฒƒ์ด๋‹ค.

๐ŸŒ€ ๋ฆฌ์•กํŠธ์—์„œ URL์„ ๋ณ€๊ฒฝํ•˜๋Š” 3๊ฐ€์ง€ ๋ฐฉ์‹์ด ์žˆ๋‹ค.

  1. location.replace("url") : ๋กœ์ปฌ ์ƒํƒœ ์œ ์ง€ ์•ˆ๋จ (re-render)
  2. router.push(url) : ๋กœ์ปฌ ์ƒํƒœ ์œ ์ง€๋˜๋‚˜ ๋ฐ์ดํ„ฐ ํŒจ์นญ์€ ์ผ์–ด๋‚จ.
  3. router.push(url, as, {shallow: true} : ๋กœ์ปฌ ์ƒํƒœ ์œ ์ง€๋˜๊ณ  ๋ฐ์ดํ„ฐ ํŒจ์นญ๋„ ์ผ์–ด๋‚˜์ง€ ์•Š๋Š”๋‹ค.

์ด๋Ÿฐ ์ ์— ์žˆ์–ด์„œ ์ตœ์ ํ™” ์‹œํ‚ฌ ์ˆ˜ ์žˆ๋‹ค๋Š” ์žฅ์ ์— Shallow Routing ์„ ์ ์šฉํ•˜์—ฌ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค.

 <button
        onClick={() => {
          alert('edit')
          setClicked(true)
          router.push('/settings/my/info?status=editing', undefined, โบ๏ธ {
            shallow: true,
          })
        }}
      >
        shallow
      </button>

์ด๋Ÿฐ์‹์œผ๋กœ ์“ฐ์ž„

๊ฒฐ๊ณผ์ ์œผ๋กœ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด getServerSideProps๋ฅผ ์ด์šฉํ•˜์—ฌ ํ„ฐ๋ฏธ๋„ ์ฝ˜์†”์ฐฝ์— ๋ฉ”์‹œ์ง€๊ฐ€ ์ฐํžˆ๋Š”์ง€ ํ™•์ธ ํ•ด๋ดค๋‹ค. ๊ทธ๋Ÿฐ๋ฐ Shallow๋ฅผ ํ–ˆ์„ ๋•Œ๋Š” ๋ฐ์ดํ„ฐ ํŒจ์นญ์ด ์ผ์–ด๋‚˜์ง€ ์•Š์œผ๋ฉด์„œ ๋กœ์ปฌ ์ƒํƒœ๊ฐ€ ์œ ์ง€๋˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค.


๐ŸŒ€ API

  • FE <=> BE ๊ฐ„์˜ ์—ฐ๊ฒฐ
  • ํ”„๋ก ํŠธ๋Š” ์œ ์ €์™€ ๋‹ฟ์•„์žˆ๊ณ , ๋ฐฑ์—”๋“œ๋Š” DB์™€ ๋‹ฟ์•„์žˆ๋‹ค.
  • ์‹ค์ œ ์„œ๋น„์Šค๋ฅผ ํ™•์ธํ•  ๋•Œ๋Š” ์›น์‚ฌ์ดํŠธ - ๊ฐœ๋ฐœ์ž๋„๊ตฌ - ๋„คํŠธ์›Œํฌ ์—์„œ ํ™•์ธ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

Next์—์„œ api ๋ถˆ๋Ÿฌ์˜ค๊ธฐ

  • /pages/api/ํŒŒ์ผ๋ช….js

API๋„ pages ๋””๋ ‰ํ† ๋ฆฌ ์•ˆ์—๋‹ค๊ฐ€ api ํด๋”๋ฅผ ์ƒ์„ฑํ•˜์—ฌ api ๋ฅผ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค.

import { userInfo } from 'v1/user'

export default function handler(req, res) {
  res.status(200).json(userInfo)
}

์ด๋Ÿฐ์‹์œผ๋กœ api ํŒŒ์ผ์„ ๋งŒ๋“ค์–ด์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ถˆ๋Ÿฌ์˜ฌ ์ˆ˜ ์žˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  Routing ์—์„œ ๋‹ค๋ค˜๋˜ ์—ฌ๋Ÿฌ Slug ํ™œ์šฉ๋ฒ•์„ API์—์„œ๋„ ๋™์ผํ•˜๊ฒŒ ์ ์šฉ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

/api/post/create.js
/api/post/[pid].js
/api/post/[...slug].js --> ๋‹ค์ค‘ slug
/api/post/[[...slug]].js --> ์˜ต์…”๋„ํ•˜๊ฒŒ ์‚ฌ์šฉ ๊ฐ€๋Šฅ

ํ•˜๋ฌผ๋ฉฐ ์ฟ ํ‚ค ์ •๋ณด๋„ ๋‹ด์•„๋‚ผ ์ˆ˜ ์žˆ๋‹ค.

export default function handler(req, res) {
  const { uid } = req.query
  const cookies = req.cookies
  res.status(200).json({ name: `LeeHYUNJU ${uid} ${JSON.stringify(cookies)}` })
}

์ด๋Ÿฐ์‹์œผ๋กœ ์ฟ ํ‚ค ์ •๋ณด๋ฅผ ๋‹ด์•„๋‚ด์–ด ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ์Œ ! Next์—์„œ api์˜ ์ƒํƒœ ์ฝ”๋“œ๊ฐ’๊ณผ ์‚ฌ์šฉ์ž ์ฝ”๋“œ ๋“ฑ๋“ฑ์˜ Reponse ๊ทœ๊ฒฉํ™”๋ฅผ ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์ ์ด ๋˜ Next์˜ ํŠน์ง•์ด๋ผ๊ณ  ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

๐Ÿฅฐ ๋Š๋‚€์ 

Next ํ”„๋ ˆ์ž„์›Œํฌ์— ๋Œ€ํ•ด ๊ณต๋ถ€ํ•˜๋‹ค๋ณด๋‹ˆ '์—ญ์‰ฌ ๋‚จ๋“ค์ด ๋‹ค ์“ฐ๋Š” ์ด์œ ๊ฐ€ ์žˆ๋‹ค๋‹ˆ๊นŒ.....๐Ÿ˜ฒ'๋ฅผ ๋Š๋ผ๋ฉด์„œ ๋‚˜๋„ ์กฐ๋งŒ๊ฐ„ ์‚ฌ์ด๋“œ ํ”„๋กœ์ ํŠธ์— ์ ์šฉํ•ด ๋ด์•ผ๊ฒ ๋‹ค. ๊ธฐ์กด์—๋Š” Next ํ”„๋ ˆ์ž„์›Œํฌ๋กœ ๊ฐœ๋ฐœ ํ™˜๊ฒฝ ์„ธํŒ…๋งŒ ํ•ด๋‘” ์ƒํƒœ๋กœ page-based routing sytems๋งŒ ์ด์šฉํ•ด๋ดค์ง€ ๊ทธ ์™ธ์˜ ๊ธฐ๋Šฅ๋“ค์€ ์จ๋ณธ ์ ์ด ์—†์—ˆ๋‹ค.

Next์˜ ๊ฐ€์žฅ ํฐ ๋งค๋ ฅ์€ SEO(๊ฒ€์ƒ‰ ์—”์ง„ ์ตœ์ ํ™”)์™€ ์„œ๋ฒ„ ์‚ฌ์ด๋“œ ๋ Œ๋”๋ง ๊ทธ๋ฆฌ๊ณ  ์„ฑ๋Šฅ์ ์œผ๋กœ๋„ ์ตœ์ ํ™” ํ•ด์ฃผ๋Š” ๊ฒƒ์ด ์ •๋ง ํฐ ์žฅ์ ์ธ๋ฐ,,, ์ด๋ฒˆ ๊ธฐํšŒ์— ํ•™์Šตํ–ˆ๋˜ ๋‚ด์šฉ๋“ค์„ ์ž˜ ํ™œ์šฉํ•ด์„œ ๋‚ด๊ป„๋กœ ๋งŒ๋“ค์–ด์•ผ์ง€.

Next ๊ณต์‹๋ฌธ์„œ ๐Ÿ‘‰ https://nextjs.org/docs/getting-started

profile
์•„๋Š‘ํ•œ ๋‡Œ๊ณต๊ฐ„ ๐Ÿง 

4๊ฐœ์˜ ๋Œ“๊ธ€

comment-user-thumbnail
2023๋…„ 2์›” 13์ผ

ํ˜น์‹œ ์ธ๋„ฌ์›€์งค๋“ค์€ ๋ณดํ†ต ๋งŒ๋“œ์‹ ๊ฑธ๊นŒ์š”..? ์•„๋‹ˆ๋ฉด ๊ตฌํ•˜์‹ ๊ฑธ๊นŒ์š”..? ๋„ˆ๋ฌด ๋„ˆ๋ฌด ํƒ๋‚ฉ๋‹ˆ๋‹ค

1๊ฐœ์˜ ๋‹ต๊ธ€
comment-user-thumbnail
2023๋…„ 2์›” 13์ผ

์›€์งค์— ์ด๋Œ๋ ค ์™”์Šต๋‹ˆ๋‹ค..

1๊ฐœ์˜ ๋‹ต๊ธ€