๋ฆฌ์กํธ์ SSR[ Server Side Rendering ]์
์ฝ๊ฒ ๊ตฌํํ ์ ์๋๋ก ๋์์ฃผ๋ ๊ฐ๋จํ ํ๋ ์์ํฌ๐ฅ
๋ฆฌ์กํธ๋ก ๊ฐ๋ฐํ ๋ SPA[ Single Page Application ] ์ด์ฉํ๋ฉฐ
CSR[ Client Side Rendering ]์ ํ๊ธฐ์ ์ข์ ์ ๋ ์์ง๋ง
๐๋จ์ : ๊ฒ์์์ง ์ต์ ํ( SEO )๐
๐ CSR์ ํ๋ฉด ์ฒซ ํ์ด์ง์์ ๋น html์ ๊ฐ์ ธ์์ JS ํ์ผ ํด์ํ์ฌ
ํ๋ฉด์ ๊ตฌ์ฑํ๊ธฐ์ ํฌํธ ๊ฒ์์ ๊ฑฐ์ ๋
ธ์ถ ๋ ์ผ ์์๐ข
Next.jsโกPre-Rendering์ ํตํด์
ํ์ด์ง๋ฅผ ๋ฏธ๋ฆฌ ๋ ๋๋งํ๋ฉฐ ์์ฑ๋ HTML์ ๊ฐ์ ธ์ค๊ธฐ์
์ฌ์ฉ์์ ๊ฒ์ ์์ง ํฌ๋กค๋ฌ์๊ฒ ๋ฐ๋ก ๋ ๋๋ง ๋ ํ์ด์ง๋ฅผ ์ ๋ฌํ ์ ์๊ฒ ๋จโจ
๐ก ์ฉ์ด ์ ๋ฆฌ ๐ก
๐ฐํฌ๋กค๋ฌ : ์ธํฐ๋ท์ ๋์๋ค๋๋ฉด์ ์นํ์ด์ง์ ์ ๋ณด ์์งํ๋ ํ๋ก๊ทธ๋จ
๊ตฌ๊ธ ๊ฐ์ ๊ฒ์ ์์ง์ ํฌ๋กค๋ฌ ์ฌ์ฉํด์ ์น์ฌ์ดํธ์ ๋ด์ฉ์ ์ฝ๊ณ , ๊ฒ์ ๊ฒฐ๊ณผ์ ๋ณด์ฌ์ค ์ ๋ณด๋ฅผ ์ ๋ฆฌํจ
๐๏ธPre-Rendering : ๋ณดํต ์นํ์ด์ง ๋ง๋ค ๋ ๋ธ๋ผ์ฐ์ ๊ฐ JS๋ฅผ ์คํํด์ ํ๋ฉด์ ๋ง๋ค์ง๋ง
๐ ํ์ด์ง๋ฅผ ๋ฏธ๋ฆฌ ์์ฑ๋ HTML ํํ๋ก ๋ง๋ค์ด๋๋ ๊ฒ๐ฅ
์ฆ, ์๋ฒ์์ ๋ฏธ๋ฆฌ ํ์ด์ง๋ฅผ ๋ง๋ค์ด ๋๊ณ ์ฌ์ฉ์๊ฐ ์์ฒญํ๋ฉด ๋ฐ๋ก ๋ณด์ฌ์ฃผ๋ ๋ฐฉ์
๐ง ๊ทธ๋ผ ์ ์ข์ โ
โ
๋ ๋น ๋ฆโ์ฌ์ฉ์๊ฐ ๋ค์ด์ค์๋ง์ ์์ฑ๋ ํ์ด์ง๋ฅผ ๋ณผ ์ ์์
โ
๊ฒ์ ์์ง ์ต์ ํ( SEO ) ๊ฐ๋ฅโํฌ๋กค๋ฌ๊ฐ HTML ์ฝ๊ฒ ์ฝ์ ์ ์์ด ๊ฒ์ ๊ฒฐ๊ณผ์ ์ ๋
ธ์ถ๋จ
๐CSR[ Client Side Rendering ]
๐ ๋ธ๋ผ์ฐ์ ์์ ํ๋ฉด์ ๊ทธ๋ฆฌ๋ ๋ฐฉ์

1๏ธโฃ ์ฌ์ฉ์๊ฐ ์น์ฌ์ดํธ์ ์ ์โex ) localhost:3000/
2๏ธโฃ ๋ธ๋ผ์ฐ์ ๊ฐ HTML์ ๋ฐ์ โ ๋น์ด ์๋ HTML
3๏ธโฃ ์๋ฐ์คํฌ๋ฆฝํธ( JS ) ํ์ผ ๋ค์ด๋ก๋ ํ ์คํ
4๏ธโฃ JS๊ฐ ์คํ๋๋ฉด์ ํ๋ฉด์ ๊ทธ๋ฆผ ( React, Vue ๋ฑ์ผ๋ก ๋ ๋๋ง๋จ๐ป )
5๏ธโฃ ์์ฑ๋ ํ๋ฉด์ด ์ฌ์ฉ์์๊ฒ ๋ณด์
๐ ํน์ง
๐น ์ฒ์ ๋ก๋ฉ ๋๋ฆผ๐ข,, ( JS ํ์ผ ๋ค ๋ฐ์์ผ ํ๋ฉด์ด ๋ณด์ )
๐น ์ดํ๋ ๋น ๋ฆ๐ ( ํ ๋ฒ ๋ก๋ฉํ๋ฉด ํ์ด์ง ์ด๋์ด ๋น ๋ฆ )
๐น ๊ฒ์ ์์ง ํฌ๋กค๋ฌ๊ฐ HTML์ ์ ๋๋ก ๋ชป ์ฝ์ ์ ์์ ( ๐SEO ๋ถ๋ฆฌ๐ )
๐ฅSSR[ Server Side Rendering ]
๐ ์๋ฒ์์ ํ๋ฉด์ ๊ทธ๋ ค์ ๋ณด๋ด๋ ๋ฐฉ์ ( Next.js ์์ ์ฌ์ฉ ๊ฐ๋ฅ๐ )

1๏ธโฃ ์ฌ์ฉ์๊ฐ ์น์ฌ์ดํธ์ ์ ์
2๏ธโฃ ์๋ฒ์์ ์์ฒญ์ ๋ฐ์
3๏ธโฃ ์๋ฒ์์ HTML์ ๋ฏธ๋ฆฌ ๋ง๋ค์ด์ ์์ฑ๋ ํ์ด์ง๋ฅผ ๋ณด๋
4๏ธโฃ ์ฌ์ฉ์๋ ๋ฐ๋ก ํ๋ฉด์ ๋ณผ ์ ์์
5๏ธโฃ JS๊ฐ ์คํ๋๋ฉด์ ์ถ๊ฐ ๊ธฐ๋ฅ ํ์ฑํ ( ๋ฒํผ ํด๋ฆญ, ์ ๋๋ฉ์ด์
๋ฑ )
๐ ํน์ง
โ
์ฒซ ๋ก๋ฉ ๋น ๋ฆ ( HTML์ด ์์ฑ๋ ์ํ๋ก ์ ๋ฌโญ )
โ
๊ฒ์ ์์ง์ด ๋ด์ฉ์ ์ฝ๊ฒ ์ฝ์ ์ ์์ ( ๐SEO ์ ๋ฆฌ๐ )
โ
์๋ฒ์์ ๋ ๋๋ง์ ํด์ผ ํ๋ฏ๋ก ์๋ฒ ๋ถํ๊ฐ ์์๐คฏ

๐ฉโ๐ป Next.js ์ฌ์ฉํด๋ณด์ โก
๐๋ฐํํ๋ฉด์ nextjs-app ํด๋ ๋ง๋ค๊ธฐ

VScode ํฐ๋ฏธ๋์์ npx create-next-app ./ ๋ช
๋ น์ด๋ก Next.js ์ค์นํ๊ธฐ


์ค์นํ์ ๋ src/ ํด๋ ์ฌ์ฉํ๋ค๊ณ ๋์ํด์ ์๊ธด๊ฒ
๊ทธ๋ฆฌ๊ณ App Router ์ฌ์ฉ ์ ํ๋ค๊ณ ํ์ด์ pages ํด๋๊ฐ ์์ฑ๋๊ฑฐ์

๐next.js ์คํ : npm run dev
โฌ


๐index.js ํ์ผ์ด ์์์ ์ธ ๊ฑธ ์ ์ ์์

ํฐํธ ์ ์ ์ธ ํ์ผ๋ค์ด ์ฌ๊ธฐ์ ๋ค์ด์์

๐์ ์ญ ์คํ์ผ์ src>styles>globals.css ํ์ผ์ ์์
์ ์ญ ์คํ์ผ ์ฝ๋ ์ง์ฐ๋ฉด ์คํ์ผ ๋ณ๊ฒฝ์ด ๋จ

HTML ๋ฌธ์์ ๊ธฐ๋ณธ ๊ตฌ์กฐ๋ฅผ ์ปค์คํฐ๋ง์ด์งํ ๋ ์ฌ์ฉํ๋ ํ์ผโ
๋ฆฌ์กํธ์ index.html ๊ฐ์ ์ญํ ์ ํ๋๋ฐ
Next.js์์ ์๋ฒ์์ ํ ๋ฒ๋ง ๋ ๋๋ง๋๊ณ ํด๋ผ์ด์ธํธ์์ ๋ณ๊ฒฝโ
- html, head, body ํ๊ทธ ์ง์ ์์ ๊ฐ๋ฅโ
- ๊ธ๋ก๋ฒ ์คํ์ผ ์ํธ( CSS )๋ ํฐํธ, ๋ฉํ ํ๊ทธ ์ค์ ํ ์ ์์โ
- ๋คํฌ ๋ชจ๋ ๊ฐ์ ํ
๋ง ์ค์ ํ ๋ ์ ์ฉโ


๐ฏ ../.. ์ด๊ฑฐ ๋์ @ ์ด๋ ๊ฒ ํ ์ ์์

โ๏ธnext.js ์ค์ ( config )ํ๋ ํ์ผ ( ์์ฒญ ๋ง์ ์ค์ ํ ์ ์์ )
reactStrictMode: true ์ค์ ํ๋ฉด ๊ฐ๋ฐ ์ค์ ๋ฌธ์ ๋ฅผ ๊ฐ์งํ๊ณ ๊ฒฝ๊ณ ๋ฅผ ๋ณด์ฌ์ฃผ๋ ๋ชจ๋๊ฐ ์ผ์ง๐ก
postcss.config.mjs ํ์ผ์ tailwind.css ์ฌ์ฉํ๊ธฐ ์ํ ํ์ผ
tailwind๋ css ํ๋ ์์ํฌ( ๋ฌด์กฐ๊ฑด ๋ฐฐ์์ผํ๋ CSS Framework )
F1๏ธโฃ2๏ธโฃ ๋๋ฌ์ ์์ค๋ณด๊ธฐํ๋ฉด
๊ทธ๋ฅ ๋ฆฌ์กํธ๋ ์ด๋ ๊ฒ ๋์ด์์ ( ์ฝ์ด์ผ ๋๋ ๋ถ๋ถ์ด ํ
๋น์ด์์ ) ๋ฐ๋ฉด์
Next.js๋ ์ด๋ ๊ฒ ๋์ด์์
npm run build๋ฅผ ํ๊ณ

์ฌ๊ธฐ๋ฅผ ๋ณด๋๊น Generating static pages 3๊ฐ ๋ผ๊ณ ๋์ด์์
3๊ฐ์ ํ์ผ์ด ๋ง๋ค์ด์ ธ์๋๊ฑธ ๋ณผ ์ ์์
Next.js๋ ์ ์ ํ์ด์ง( SSG )์ฉ index.html ํ๊ณ
์ค๋ฅ ํ์ด์ง( 404.html, 500.html )๋ฅผ ๋ฏธ๋ฆฌ ์์ฑํด์ ๋ฐฐํฌํ ๋ ์ฌ์ฉํ ์ ์๋๋ก ํจ๐ฅ
๐ 404 ( Not Found ) : ์๋ ํ์ด์ง์ ์ ๊ทผํ์ ๋ ๋ํ๋๋ ์ค๋ฅ
๐ 500 ( Internal Server Error ) : ์๋ฒ์์ ๋ฌธ์ ์๊ฒผ์ ๋ ๋ํ๋๋ ์ค๋ฅ
โ์ ๊นโ
๐๏ธPre-rendering
NextJSโก๋ชจ๋ ํ์ด์ง๋ฅผ pre-render ํจโก
pre-render ํ๋ค๋ ์๋ฏธ : ๋ชจ๋ ํ์ด์ง๋ฅผ ์ํ HTML์
Client ์ฌ์ด๋์์ ์๋ฐ์คํฌ๋ฆฝํธ๋ก ์ฒ๋ฆฌํ๊ธฐ ์ "์ฌ์ ์" ์์ฑํ๋ค๋ ๊ฒ
์ด๋ ๊ฒ ํ๊ธฐ์ ๐SEO ๊ฒ์์์ง ์ต์ ํ๊ฐ ์ข์์ง๐
๐น Client ์ฌ์ด๋ : ํฌ๋กฌ, ์ฌํ๋ฆฌ ๊ฐ์ ๋ธ๋ผ์ฐ์ ์์ ์น์ฌ์ดํธ ์ด์์ ๋
๊ทธ ๋ธ๋ผ์ฐ์ ์์ ์คํ๋๋ ์ฝ๋( HTML, CSS, JS ๋ฑ )
๐ฐํฌ๋กค๋ฌ( ์ ๋ณด ์์ง ํ๋ก๊ทธ๋จ )๊ฐ index.html ๋ณด๊ณ ์
ํฌ๋กค๋งํ ์ ์๊ธฐ ๋๋ฌธ์ SEO ๊ฒ์์์ง์ด ์ข์์ง ์ ๋ฐ์ ์๋๊ฑฐ๐
์ฆ, ํฌ๋กค๋ฌ๊ฐ ๋ฏธ๋ฆฌ ๋ ๋๋ง๋ HTML์ ์ฝ์ผ๋๊น, ํ์ด์ง๊ฐ ๋ ์ ๊ฒ์๋ ์๋ฐ์ ์๋ ๊ฒโ

๐ซ๋ฆฌ์กํธ์์ ์๋ฐ์คํฌ๋ฆฝํธ๋ฅผ ๋๋ฒ๊ทธ( disable ) ์์ผ๋ณด๊ธฐ( JS๋ฅผ ์ฌ์ฉํ์ง ์๊ฒ ๋ค๋ ๊ฒ )
๐ค ๊ทธ๋ฌ๊ณ ์๋ก๊ณ ์นจํ๋๊น ์ด๋ ๊ฒ ๋จ๋๋ฐ ์ ์ด๋ ๊ฒ ๋์ค๋๊ฑธ๊น โ

CSR ์์ ์ค์์ JS๋ฅผ ๋ง์๊ฑฐ๋๊น ๋ณด์ด๋ ํ๋ฉด์ด ์ด๋ถ๋ถ์ธ ๊ฒ,,,๐ฏ๐ก
๊ณ์ ์งํ์ด ๋ผ์ผ ํ๋ฉด์ด ๋ณด์ฌ์ง๊ธฐ ๋๋ฌธ์ ์ด๋ฐ ํ์์ด ๋ฐ์ํ๋๊ฑฐ์
next.js๋ฅผ ๋๊ฐ์ด disable ์์ผ๊ณ ์๋ก๊ณ ์นจ ํด๋ ํ๋ฉด์ด ๋๊ฐ์โ
๐ค ์ด๊ฑด ์ ํ๋ฉด์ด ๋๊ฐ์ด ๋์ฌ๊น โ
JS ๋ถ๋ถ์ ๋ง์์ง๋ง ๋ณด๋๋ฐ๋ ์ง์ฅ์์๐
โโ๏ธ
์๋, ์ด๋ฏธ html์ ๋ง๋ค์ด๋์ ์ด๊ฑธ ํ๋ฉด์์ ๋ณด์ฌ์ฃผ๊ธฐ ๋๋ฌธโจ
ํ์ง๋ง ๋ฒํผ์ ๋๋ฅด๊ฑฐ๋ ํ์ ๋ ๋์์ด ์ ๋ ๊ฒ ( JS ์์ญ )

Next.js ์์ ์ฒจ์ ๋ก๋ํ ๋ ์ด๋ฏธ ์ฌ์ ์ ์ค๋น๋ html์ ๋ณด์ฌ์ฃผ๊ณ
๊ทธ๋ด์ JS๋ฅผ ๋ค์ด๋ก๋ ํจ๐ฅ
๊ทธ๋ฌ๊ณ ๋ฆฌ์กํธ๋ฅผ ์คํํ๊ณ ์ด๋ ํ๋ ๊ฑธ ๐ง'Hydration'( ์๋ถ์ ๊ณต๊ธ ) ์ด๋ผ๊ณ ํจ
๐ HTML๊ณผ JS๊ฐ ํฉ์ณ์ ธ์ React ์ฑ์ด ์์ฑ๋๋ ๊ณผ์ ๐ก
๊ทธ๋ฌ๋ฉด ์ด์ ์ํธ์์ฉํ ์ฑ์ด ๋๋ ๊ฒ ๐ฅ

๋ฆฌ์กํธ์์ ์ฒจ์ ์๋ฌด๊ฒ๋ ์ ์ผ์ด๋๊ณ JS ๋ค์ด๋ก๋ํ๊ณ ๋ฆฌ์กํธ๋ฅผ ์คํํจ
๊ทธ ๋ค์ ํ๋ฉด์ด ๋ํ๋๊ณ ์ํธ์์ฉ ๊ฐ๋ฅํ ๊ฑฐ์๐โโ๏ธ
๐Data Fetching
๐Next.js ์์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๋ ๋ฐฉ๋ฒ์โ
์ฌ๋ฌ๊ฐ์ง๊ฐ ์์ด์ ์ ํ๋ฆฌ์ผ์ด์
์ ์ฌ์ฉ ์ฉ๋์ ๋ฐ๋ผ ๋ค๋ฅธ ๋ฐฉ๋ฒ์ผ๋ก ์ฌ์ฉํด์ฃผ๋ฉด ๋จ
๋ณดํต React ์์ ๋ฐ์ดํฐ ๊ฐ์ ธ์ฌ ๋ useEffect ์์์ ๊ฐ์ ธ์ด
ํ์ง๋ง Next.js ์์ ๋ค๋ฅธ ๋ฐฉ๋ฒ ์ฌ์ฉํด์ ๊ฐ์ ธ์ด
๐ React ์์ useEffect ์ฌ์ฉํ ๋ฐ์ดํฐ ์์ฒญ ํ๋ฆ

user๊ฐ ์๋ฒํํ
๋ฐ์ดํฐ๋ฅผ ์์ฒญ( request )๋ณด๋ผ ๋
์ปดํฌ๋ํธ์ useEffect ์์์ ์์ฒญ์ ๋ณด๋์์
โ
์์ : state ๋ถ๋ถ๋ค์ด ์์ฑโกUI ๋ถ๋ถ ๋ ๋๋งโก๊ทธ ๋ค์ useEffect ์คํ
1๏ธโฃ user๊ฐ localhost:3000 ๊ฒฝ๋ก๋ก ์ ์
๐ ํด๋น ํ์ด์ง์ ์ปดํฌ๋ํธ๊ฐ ์คํ๋จ
2๏ธโฃ ์คํํ ํด๋น ์ปดํฌ๋ํธ์ state๊ฐ ์์ฑ
๐ useState๋ก ๊ด๋ฆฌํ๋ ์ํ ๋ณ์๋ค์ด ์ด๊ธฐ๊ฐ์ ๊ฐ์ง๐
3๏ธโฃ UI๊ฐ ๋ ๋๋ง๋จ ( return ๋ถ๋ถ ์คํ )
๐ ํ๋ฉด์ ์ด๊ธฐ UI๊ฐ ํ์๋จ( ์์ง ๋ฐ์ดํฐ ์์โ )
4๏ธโฃ useEffect ์คํ
๐ ์ปดํฌ๋ํธ๊ฐ ๋ ๋๋ง๋ ํ ๋น๋๊ธฐ ์์ฒญ( fetching ) ์์
5๏ธโฃ ๋น๋๊ธฐ ๋ฐ์ดํฐ ์์ฒญ( fetching ) ๋ฐ์
๐ API ์์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ด ( ex - fetch or axios ์ฌ์ฉโญ )
6๏ธโฃ ๊ฐ์ ธ์จ ๋ฐ์ดํฐ state์ ์ ์ฅ
๐ setState ์ฌ์ฉํด ์ํ๋ฅผ ์
๋ฐ์ดํธ๐
7๏ธโฃ state ๋ณ๊ฒฝ๋์ผ๋ ์ปดํฌ๋ํธ ๋ฆฌ๋ ๋๋ง
๐ ์๋ก์ด ๋ฐ์ดํฐ๋ฅผ ๋ฐ์ํ UI๊ฐ ๋ค์ ๋ ๋๋ง๋จ
๐ฅNext.js์ ๋ฐ์ดํฐ ๊ฐ์ ธ์ค๋ 3๊ฐ์ง ๋ฐฉ๋ฒ
๐ธ getStaticProps : ์ ์ ์ธ HTML์ ๋ฏธ๋ฆฌ ๋ง๋ค์ด์ ๋น ๋ฅด๊ฒ ๋ณด์ฌ์ค
- ๋น๋ ํ์์ ์คํ โ HTML ๋ฏธ๋ฆฌ ๋ง๋ค์ด์ ์๋ ๋น ๋ฆ๐
- ํ์ด์ง์ ๋ณ๋์ด ๊ฑฐ์ ์๋ ๋ฐ์ดํฐ์ ์ ํฉ ( ex - ๋ธ๋ก๊ทธ ๊ธ, ์ ํ ๋ชฉ๋ก )
๐ค ์์ : ๋ธ๋ก๊ทธ ๊ฒ์๊ธ ๋ฏธ๋ฆฌ ๋ง๋ค์ด๋๊ธฐ
export async function getStaticProps() {
const res = await fetch("https://api.example.com/posts");
const posts = await res.json();
return { props: { posts } };
}
๐ก ๊ฒฐ๊ณผ : ๋น๋ํ ๋ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์์ ์์ฑ๋ HTML์ ๋ณด์ฌ์ค
๐ธ getStaticPaths : ์ฌ๋ฌ ๊ฐ์ ์ ์ ํ์ด์ง๋ฅผ ๋ฏธ๋ฆฌ ๋ง๋ค์ด ๋
- getStaticProps์ ํจ๊ป ์ฌ์ฉโ
- ๋์ ์ธ ๊ฒฝ๋ก( ex - /posts/1, /posts/2 )๋ฅผ ๋ฏธ๋ฆฌ ์์ฑํ ๋ ์ฌ์ฉโ
๐ค ์์ : ์ฌ๋ฌ ๊ฐ์ ๋ธ๋ก๊ทธ ๊ธ ํ์ด์ง ๋ฏธ๋ฆฌ ๋ง๋ค๊ธฐ
export async function getStaticPaths() {
const res = await fetch("https://api.example.com/posts");
const posts = await res.json();
const paths = posts.map((post) => ({
params: { id: post.id.toString() },
}));
return { paths, fallback: false };
}
๐ก ๊ฒฐ๊ณผ : /posts/1, /posts/2 ๊ฐ์ ํ์ด์ง๋ค์ ๋ฏธ๋ฆฌ ๋ง๋ค์ด๋
๐ธ getServerSideProps : ๋งค๋ฒ ์๋ก ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ด
- ์ฌ์ฉ์๊ฐ ์ ์ํ ๋๋ง๋ค ์๋ฒ์์ ์คํ๋จ
- ํญ์ ์ต์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์์ผ ํ ๋ ์ ํฉ ( ex - ์ค์๊ฐ ๋ด์ค, ์ฌ์ฉ์๋ณ ๋ฐ์ดํฐ )
๐ค ์์ : ์ ์ํ ๋๋ง๋ค ์ต์ ๋ด์ค ๋ถ๋ฌ์ค๊ธฐ
export async function getServerSideProps() {
const res = await fetch("https://api.example.com/news");
const news = await res.json();
return { props: { news } };
}
๐ก ๊ฒฐ๊ณผ : ์ฌ์ฉ์๊ฐ ํ์ด์ง๋ฅผ ๋ฐฉ๋ฌธํ ๋๋ง๋ค ์ต์ ๋ด์ค ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ด

๐ฑโ๐ป์ค์ ์ฌ์ฉํด๋ณด์โก
โซ src>pages>index.js
์ด๋ถ๋ถ ์ ์ฒด ๋ค ์ง์ฐ๊ณ
div ํ๊ทธ๋ง ๋จ๊ฒจ๋๊ฒ ์
โซ src>styles>globals.css
10๋ฒ ์ค๋ถํฐ ์น ๋ค ์ง์ฐ๊ณ
โฌ
npm run dev๋ก ์คํํด๋ณด๋ฉด ์ด๋ฐ์์ผ๋ก ๋๋ ๊ฑธ ๋ณผ ์ ์์๐
โซ src>pages>index.js


Head ํ๊ทธ ์์ title Your Name ์ฐ๋ฉด ์ ๋ชฉ์ด ์ ํ์ง

๐section ์๋ฉํฑ ํ๊ทธ๋ฅผ ์ด์ฉํด์ p ํ๊ทธ ์์
[Your Self Introduction] ์ด๋ (This is a website) ๐
๐๋ฌธ์์ ํน์ ์ฃผ์ ๋ฅผ '๊ทธ๋ฃนํ' ํ๋ ์ฉ๋๋ก ์ฌ์ฉ๋๋ ๋ธ๋ก ์์

๋ section ํ๋ ๋ ํด์ ๋ถ์ ๋ชฉ์ผ๋ก Blog ํด์ฃผ๊ณ
๊ทธ ๋ฐ์ ul ์์ ์๋ ํ๊ทธ ์ด๋ ๊ฒ ํด๋๊ธฐ
โฌ

๊ทธ๋ฐ ๋ด์ ์ด์ ํด์ผํ๋๊ฑด Blog ๋ค์ ๋์ดํ๋ฉด ๋จโ
๋ธ๋ก๊ทธ๋ค์ ์ ๋ชฉ๋ค๋ง ๋์ดํ๊ฑด๋ฐ When~ ์ด๋ถ๋ถ์ ์ํ ํ์ผ์ด๋
Two~ ์ด๋ถ๋ถ์ ์ํ ํ์ผ ์ด 2๊ฐ๋ฅผ ๋ง๋ค๊ฑฐ์๐โโ๏ธ
pre-render.md ํ์ผ์ด๋ static.md ํ์ผ ๋ง๋ค๊ธฐ




'๋งํฌ๋ค์ด ํ์ผ'์ ์ด๋ฐ์์ผ๋ก ๋ฃ์์
โ ํ
์คํธ๋ฅผ ๊ฐ๋จํ ๊ท์น์ ์ฌ์ฉํด์ ๊พธ๋ฏธ๋ ํ์ผ
๋งํฌ๋ค์ด ์ฌ์ฉํ๋ฉด ๋ฌธ์๋ฅผ ๋น ๋ฅด๊ฒ ์์ฑํ๊ณ ,
HTML์ฒ๋ผ ๋ณต์กํ ํ๊ทธ๋ฅผ ์ฌ์ฉํ์ง ์๊ณ ๋
๊ธ์ ํฌ๊ธฐ, ์ ๋ชฉ, ๋ฆฌ์คํธ, ๋งํฌ, ์ด๋ฏธ์ง ๋ฑ์ ์ถ๊ฐํ ์ ์์โ
DB๊ฐ ์ง๊ธ ์์ผ๋๊น ๊ทธ๋์ ๊ทธ๋ฅ ํ์ผ์๋ค๊ฐ ๋ฐ์ดํฐ๋ฅผ ๋ฃ์ด๋ ๊ฒโ
๋ธ๋ก๊ทธ ํ๋์ ๊ฒ์๋ฌผ์ ๋ํ ๋ฐ์ดํฐ๋ฅผ ๋ฃ์ด๋๊ฑฐ์๐
์๋ ์๋ค๋ค์ด ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ๋ค์ด์์๊ฑฐ์โญ

posts ๋ผ๋ ํด๋๋ฅผ ๋ง๋ค๊ณ ์ด ์์ pre-render.md & static.md ํ์ผ์ ๋ฃ์ด์ฃผ๊ธฐ


Blog ๋ฐ์๋ค๊ฐ ์ด๋ถ๋ถ๋ง ๊ฐ์ ธ์์ ํ๋ฉด์ ๋ณด์ด๊ฒ ํ ๊ฒ๐ค
์ด ๋ฐ์ดํฐ๋ค์ ๊ฐ์ ธ์์ผํ๋๋ฐ Next.js๋๊น ์ธ์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์์ผํ ๊นโ
๐ build time

โ
๋ฆฌ์กํธ ์ผ์ ๋ useEffect ์จ์ ๋ฐ์ดํฐ ์์ฒญํด์ ๊ฐ์ ธ์์์

๋ฐ์ดํฐ ๊ฐ์ ธ์ค๊ธฐ ์ํด์ ๋ ๊ฐ์ ํ์ผ์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์์ผํ๋๋ฐ
๊ทธ๋ฌ๊ธฐ ์ํด ๋ ๊ฐ์ ํ์ผ์ ์ ๊ทผํด์ผํจโก

์ด fs๋ ํ์ผ ์์คํ
์ด๋ผ๊ณ ํ๋ API
๐ Node.js ๋๋ถ์ ์ฌ์ฉํ ์ ์๋ ์ ๐ฅ
โclient side ์์ ์ฌ์ฉ ๋ถ๊ฐโ
๐คทโโ๏ธ์โโกclient side ์์ ๋ธ๋ผ์ฐ์ ์์ ์ ๊ณตํด์ฃผ๋๊ฑธ ์ธ ์ ์๋๋ฐ
fs๋ ๋ธ๋ผ์ฐ์ ์์ ์ ๊ณตํด์ฃผ๋ ๊ฒ์ด ์๋, Node.js ์์ ์ ๊ณตํด์ฃผ๊ธฐ ๋๋ฌธโ
Node.js ์์ ์ ๊ณตํด์ฃผ๋๊ฑธ ์ด๋ป๊ฒ ์ธ ์ ์๋๋ฉด
๐ฅ์ฐ๋ฆฌ ์ปดํฐ์ ์ด๋ฏธ Node.js๊ฐ ์ค์น ๋์ด์์๐
๐fs๊ฐ ํ๋ ์ผ : ํ์ผ์ ์์ ํน์ ์ญ์ ํ๊ฑฐ๋, ์
๋ฐ์ดํธ ํ๊ฑฐ๋ ํ ์ ์์โ
์ง๊ธ ์ฐ๋ฆฐ ์ด ํ์ผ๋ค์ ์ฝ์ผ๋ ค๊ณ ํ๋ ๊ฒ์ด๊ธฐ์
๐fs.readdirSync( ๋๋ ํ ๋ฆฌ ์ฑํฌ์ ์ฝ์ ) ์ฐ์ ๋๋ ํ ๋ฆฌ๋ฅผ ๋ฃ์ด์ฃผ๋๋ฐ

๐ ์ฝ์ผ๋ ค๊ณ ํ๋ ํ์ผ์ด ํ์ฌ posts ์์ ์์ผ๋๊น


๊ทธ๋์ ์ด๋ ๊ฒ process.cwd( ), 'posts' ๋ผ๊ณ ํด์ค๊ฑฐ์๐
nextjs-app ํด๋ ๊น์ง์ ๊ฒฝ๋ก๊ฐ process.cwd( ) ์ด๊ณ ,
'posts' ๊น์ง์ ๊ฒฝ๋ก๊ฐ postsDirectory ์ธ ๊ฒ๐ฅ

์ฐ๋ฆฐ ํ์ฌ src ํด๋ ์์ posts ํด๋๋ฅผ ๋ง๋ ๊ฑฐ๋๊น src๋ฅผ ํ๋ ๋ ๋ฃ์ด์ค์ผํจ
์๋๋ฉด posts ๋ถ๋ถ์ src ๋ฐ์ผ๋ก ๋นผ์ฃผ๋ฉด ํด๊ฒฐ๋จ๐


์ฐ์ ํ์ผ ์ด๋ฆ์ ์ฃผ์์ฒ๋ผ ๋๊ฐ์ด pre-rendering.md, ssg-ssr.md๋ก ๋ฐ๊ฟ์ฃผ๊ธฐ
postsDirectory ๊ฒฝ๋ก์ ์๋ ํ์ผ์ ์ฝ๋๋ค๋๊ฑฐ์๐
๊ฒฝ๋ก์ ์๋ ํ์ผ์ ์ฝ์ผ๋ฉด fileNames ๋ถํฐ ์ฝ๊ฒ๋จ
readdirSync๋ฅผ ์ด์ฉํด์ fileNamesโกpre-rendering.md, ssg-ssr.md ๋ ๋ค ์ฝ์์
๊ทธ ๋ด์ fileName.replace ๋ผ๊ณ ํ๋๋ฐ ์ ๊ฒ ''์ด๊ฑธ๋ก ๋์ฒดํ๋ค๋ ๊ฒ
๐ ์ฆ, id์ pre-rendering ์ด๋ ssg-ssr ๊น์ง๋ง ๋ค์ด๊ฐ๊ฒ๋จ ( .mdโ )

postsDirectory( posts ํด๋ )์
fileName( pre-rendering ์ด๋ ssg-ssr ํ์ผ๋ค )์ join( ํฉ์นจ )๐ฑโ๐
๊ทธ๋ฆฌ๊ณ ๋ฐ์๊ฐ ๊ฐ๊ฐ์ ํ์ผ ์ ์ฒด๋ฅผ ์ฝ๋๊ฑฐ์โจ

์ด๋ถ๋ถ์ ํ์ผ ๊ฐ์ ธ์ฌ ๋ string ๋ฐ์ดํฐ๋ก ๊ฐ์ ธ์ค๋๋ฐ


์ฌ๊ธธ ๋ณด๋ฉด content๋ ๋ญ๊ณ data์ title์ ๋ญ๊ณ date๋ ๋ญ๊ณ
์ด๋ฐ์์ผ๋ก ๋ถ์ํด์ฃผ๋ ๋ถ๋ถ์ด ์ ์ฝ๋์๐ก
matter : ๋งํฌ๋ค์ด ํ์ผ์์ ๋ฉํ๋ฐ์ดํฐ(์ ๋ชฉ, ๋ ์ง ๋ฑ)๋ฅผ ์ถ์ถํ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ํ์๐

๊ฐ์ ธ์จ ๋ฐ์ดํฐ๋ฅผ ๋ฆฌํดํด์ค๊ฑฐ์๐
allPostsData๊ฐ id๋ ๋ญ๊ณ , ์ฌ๊ธฐ์ ์๋ content๋ ๋ญ๊ณ
date๋ ๋ญ๊ณ title์ ๋ญ์ง ๋ค ๋ฆฌํด์ ํด์ค ๊ฒ๐ฏ

๐ฏdate๋ฅผ ์ด์ฉํด์ ์ ๋ ฌํ๋ ๋ถ๋ถ
๐ฉโ๐ป์ด์ ์ง์ ์์ฑํด๋ณด์

src ํด๋ ์์ utils ํด๋ ๋ง๋ค๊ณ getSortedPostsData.js ํ์ผ ๋ง๋ค๊ธฐ
โซ src>utils>getSortedPostsData.js
์ด๋ ๊ฒ ํด์ฃผ๊ณ
๋จผ์ ์ด ํ์ผ๋ค์ ์ด๋ฆ์ ๊ฐ์ ธ์ฌ๊ฑฐ์
๊ทธ๋ด๋ ค๋ฉด posts์ ๊ฒฝ๋ก๋ถํฐ ์ ๊ทผํด์ผํจโ

๊ฒฝ๋ก ์ ๊ทผํ๋ ค๋ฉด path ์ฌ์ฉโก
process.cwd( )โกnextjs-app ํด๋ ๊น์ง์ ๊ฒฝ๋ก โ 'posts'โกposts ํด๋ ๊น์ง์ ๊ฒฝ๋ก
๐ ์ด ๋๊ฐ์ ๊ฒฝ๋ก๊ฐ ํฉ์ณ( join )์ง๊ฒ postsDirectory๐ฅ


๊ทธ๋ด์ postsDirectory ์ด ํด๋์ ์๋ ํ์ผ๋ค์ ์ด๋ฆ ๊ฐ์ ธ์ค๊ธฐ ์ํด
fs( ํ์ผ ์์คํ
).readdirSync ํ ๋ด์
postsDirectory ์ฌ๊ธฐ ๊ฒฝ๋ก์ ์๋ ํ์ผ๋ค์ ๋ค ์ฝ๊ฒ ๋ค๋ ๊ฒโ

๊ทธ๋ฌ๊ณ pre-rendering.md๋ ssg-ssr.md์ ์๋ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๊ณ ์ถ์ผ๋ฉด
ํ์ผ๋ค์ ์๋ content๋ฅผ ๋จผ์ ์ฝ์ด์ผํจโญ
โ
๊ทผ๋ฐ ์ง๊ธ fileName์ ๋ฐฐ์ด๋ก ๋์ด์์โก[ 'pre-rendering.md', 'ssg-ssr.md']
๐บ fileName( ๋ฐฐ์ด ). ํ๋์ฉ ์ฝ๋๊ฑฐ๋๊น map ๋ฉ์๋๋ก ํ๊ธฐ
๐ ํ๋์ fileName ( 'pre-rendering.md' | 'ssg-ssr.md' ์ )
๐ ์ฒจ ์ํํ ๋ 'pre-rendering.md', ๋ด์ 'ssg-ssr.md'

์ฐ์ ์ฌ๊ธฐ์ ์ด ํ์ผ์ ์ฝ์ผ๋ ค๋ฉด fs.readFileSync๋ก ํ๋ฉด ๋๋๋ฐ
( ์ด ์์ ๋ ๊ฐ์ ํ์ผ๊น์ง์ ๊ฒฝ๋ก๋ฅผ ๋ฃ์ด์ค์ผ ์ด ํ์ผ๋ค์ ์ฝ์ ์ ์์๐โโ๏ธ )

๐posts ํด๋์ ๊ฒฝ๋ก๊น์ง๊ฐ postsDirectory๋๊น
๐ postsDirectory โ fileName( 'pre-rendering.md' | 'ssg-ssr.md' ) ํด์ฃผ๋ฉด ๋จ


์์ ์ต์
์ผ๋ก ์ธ์ฝ๋ฉ ์ด๋ป๊ฒ ํ ๊ฑด์งโก'utf8'
์ด๋ถ๋ถ์์ ํ๋๊ฒ ํ์ผ์ ์ฝ์ด์ ์ด ๋ฐ์ดํฐ๋ฅผ ์ฌ๊ธฐ์ ๊ฐ์ ธ์ค๋ ๊ฒโกfileContents

์ด์ ์ฌ๊ธฐ์ title์ ๋ญ๊ณ date๋ ๋ญ๊ณ content๋ ๋ญ๊ณ
์ด๋ฐ์์ผ๋ก ์ํ๋ ๋ฐ์ดํฐ ํ์์ผ๋ก ๋ณํ์์ผ์ค์ผํจ๐ฎ

๋ณํ ์์ผ์ฃผ๊ธฐ ์ํด ๋ชจ๋ ํ๋๋ฅผ ์ค์นํด์ผํจ
๐ฅ npm install gray-matter


์ค์นํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ matter๋ก fileContents๋ฅผ ๋ณ๊ฒฝ์์ผ์ค ๊ฒ

allPostsData๋ฅผ return ํ๋ฉด ์ด๋ค ํ์์ด ๋ ๊นโ
์ง๊ธ ์ฌ๊ธฐ ๋ฐ์ดํฐ 2๊ฐโก[ ๋ฐฐ์ด ์์ { ๊ฐ์ฒด 1 }, { ๊ฐ์ฒด 2 } ]
๊ทธ๋ผ ๊ฐ๊ฐ์ ๊ฐ์ฒด ์์ ์ ๋ํฌํ id๊ฐ ์์ด์ผํจ
#๏ธโฃ { id: 'pre-rendering' }, { id: 'ssg-ssr' } ์ด๋ ๊ฒ ํด์ฃผ๊ณ ์ถ์๊ฑฐ์
const id = fileName( 'pre-rendering.md' | 'ssg-ssr.md' ์ธ๋ฐ .md ์ญ์ ํ ๊ฑฐ์โ )
๐ ๋์ฒดํด์ฃผ๋ replace ์ด์ฉํด์ .md ์์จ ๊ฒ๐

postsDirectory๋ posts ํด๋ ๊ฒฝ๋ก๊น์ง ์์
fileName์ ํ์ผ( pre-rendering, ssg-ssr )๊น์ง์ ๊ฒฝ๋ก๋ฅผ fullPath์ ๋ฃ์ด์ค ๋ด์
readFileSync๋ก fullPath ํ์ผ์ ์ฝ์ผ๋ ค๊ณ ํ๋ ๊ฒ๐ฃ๐

fileContents๋ string์ผ๋ก ๋ค ๋์ด์์๋๋ฐ
title์ ๋ญ๊ณ date๋ ๋ญ๊ณ content๋ ๋ญ์ธ์ง ๋ถ์ํด์ ํ์์ ๋ณ๊ฒฝํด์ฃผ๋ ๊ฒ๐

๊ทธ๋์ ์ด๊ฑธ ๋ฆฌํดํ ๋ ๊ฐ์ฒด์ ํ์์ผ๋ก ๋ฆฌํด์ ํ๊ณ ์ถ์๋ฐ
id๋ id, matterResult๊ฐ
์ฌ๊ธฐ์์ผ๋๊น matterResult.data ์ธ๋ฐ matterResult.data ์ด๋ ๊ฒ๋ง ๋ฃ์ผ๋ฉด๋ ๊นโ
matterResult์ ์๋ data ์ด๋ถ๋ถ๋ง ๋ฃ์ด์ค๊ฑฐ๋๊นโก...matterResult.data โ

๊ทธ๋ฌ๋ฉด allPostsData ์ฌ๊ธฐ์ ์ด๋ป๊ฒ ๋์ด์์๊นโ
๐ ๋ฐฐ์ด ์์ ๊ฐ์ฒด ๋ ๊ฐ๊ฐ ์์ํ
๋ฐ id ์๊ณ , titleํ๊ณ date๊ฐ ์์๊ฑฐ์โ
์ด๋ ๊ฒ ๋ฐ๋ก ๋ฆฌํดํด์ค๋ ๋ฌด๊ด๐
๐ข๊ทธ๋ฌ๋ฉด getSortedPostsData ํจ์ ํธ์ถํ๋ฉด ์ ๋ฐฐ์ด์ด ๋ฆฌํด๋ ๊ฑฐ์๐
๊ทผ๋ฐ ์ฌ๊ธฐ์ ์ข๋ ๋์๊ฐ์

์๋ ํจ์ฌ ์ด๋ฐ ์ ๋ค์ด ์๋๋ฃฉ ํ ๊ฑฐ๋ผ date๋ฅผ ์ด์ฉํด์ ์ ๋ ฌํด์ฃผ๋๊ฒ ์ข์๊ฑฐ์๐ฅ

allPostsData์ sort ๋ฉ์๋ ์ด์ฉํด์ ์ ๋ ฌํด์ฃผ๊ธฐ๐
๐ a.date๊ฐ ๋ ๊ณผ๊ฑฐ๋ผ๋ฉด b๋ฅผ ์์ชฝ์ผ๋ก ์ด๋ ( ์ต์ ์ ์ ๋ ฌ )
๐ ๊ทธ๋ ์ง ์์ผ๋ฉด a๋ฅผ ์์ชฝ์ผ๋ก ์ด๋
๊ทธ๋ฌ๋ฉด ํจ์๋ฅผ ๋ง๋ค์๊ณ

index.js๋ ์ด๋ฐ์์ผ๋ก ๋์ด์์
โฌ
์คํ์ ํ๋ฉด ์ด๋ ๊ฒ ๋์ด์์โก
์ด ์ฑ์ฒ๋ผ ์ฒจ์ ์ด๋ ๊ฒ ๋์ดํ๊ณ ์ถ์
๋์ดํ๋ ค๋ฉด ์ด ๋ฐ์ดํฐ ๊ฐ์ ธ์์ผํ๋๋ฐ ๊ฐ์ ธ์ค๋ ค๋ฉด index.js ์์ ์ด๋ป๊ฒํ๋ฉด ๋ ๊นโ
๋ฆฌ์กํธ ํ์ ๋ ๋ฐ์ดํฐ ๊ฐ์ ธ์ฌ ๋ useEffect ์ฌ์ฉํด์ ํ์๋๋ฐ
๐ getStaticProps ์ด์ฉโ
๐getStaticProps ์ด์ฉํด์ ๋ฐ์ดํฐ ๊ฐ์ ธ์ค๊ธฐ
โซ src>pages>index.js

โจ์ปดํฌ๋ํธ ๋ฐ์๋ค getStaticProps ์์ฑํ๊ธฐ
๐ฏ์ด ํจ์๋ ์๋ฒ์์ ์คํ๋๋ฉฐ, ๋น๋ ์์ ์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ ์ ์ ํ์ด์ง๋ฅผ ์์ฑํจ
allPostsData ( ๋ฐฐ์ด ๋ฐ์ดํฐ )

props.allPostsData๋๊นโก{ allPostsData } ์ด๋ ๊ฒ ๊ฐ์ ธ์ค๋ฉด ๋จโญ
์ฝ์ ๊ฒฐ๊ณผ๋ ์๋ ๊ฒ ์ํ๋ ๋ฐ์ดํฐ๊ฐ ์ ๋์ค๋ ๊ฑธ ๋ณผ ์ ์์๐โโ๏ธ

๊ทธ๋ผ ์ด์ allPostsData๋ก UI์ ์ ๋์ค๊ฒ ํด์ค๊ฑฐ์๐ป
โฌ
์ด๋ ๊ฒ ํด์ฃผ๋๊น ์ด๋ฐ์์ผ๋ก ํ๋ฉด์ ์ ๋์ค๋ ๊ฑธ ๋ณผ ์ ์์๐

๊ทธ๋ฆฌ๊ณ ์ด๋ถ๋ถ์ ํด๋ฆญํ๋ฉด
์์ธํ์ด์ง๋ก ์ด๋ํ๊ฒ ๋จ๐ซ๐ฑโ๐
๋ฆฌ์กํธ ์ฌ์ฉํ์ ๋ ํ์ด์ง ์ด๋ํ ๋ ์ด๋ค๊ฑฐ ์ด์ฉํ์์งโ
๐ React-Router-Dom ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ด์ฉํด์ ๋ง๋ค์์โ
Next.js ์์ ๋ค๋ฅธ ๊ฑธ ์ฌ์ฉํจ
๐ File System Routing ์ฌ์ฉํ ๊ฒ ( ํ๋ ์์ํฌ๋๊น ์ด๋ฏธ ๋ง์ ๊ฑธ ๊ฐ๊ณ ์์ )
๐ฏFile System Routing ํ์ฉํ ์๋ ํ์ด์ง ์ด๋ ์ค์

๐ฑโ๐localhost:3000/posts/:id ๋ค์ด๋๋ฏนํ๊ฒ ํด์ค์ผํจ
posts ํด๋ ๋ง๋ค๊ณ :id ๋ค์ด๋๋ฏน ํ๊ฒ ์์ผํ๋ฏ๋ก [id].js ํ์ผ ๋ง๋ค๋ฉด ๋จ
๐ localhost:3000/posts/pre-rendering | ssg-ssr ์ด๋ ํ ์ ๊ฐ ์ค๋ ์ฒ๋ฆฌ๋ ์ฌ๊ธฐ์๐
์ด๋ฐ๊ฑธ file system routing ์ด๋ผ๊ณ ํ๋ ๊ฒ๐ฅ


โซ src>pages>posts>[id].js

rafce๋ก ํจ์ํ ์ปดํฌ๋ํธ ์๋์ผ๋ก ์์ฑํด์ฃผ๊ณ PostsDetailPage ๋ผ๊ณ ์ด๋ฆ ๋ฐ๊ฟ์ฃผ๊ธฐ
โซ src>pages>index.js
title ํด๋ฆญํ์ ๋ ๊ฐ๊ฐ์ ๋ํ
์ผํ ํฌ์คํธ ํ์ด์ง๋ก ์ด๋ํ๊ฒ ํ๋ ค๋ฉดโ
๐ Next.js ์์ ์ ๊ณตํด์ฃผ๋ Link ์ด์ฉํ๊ธฐโ


๐href={ ์ฌ๊ธฐ์ ์ด๋ํ๊ณ ์ ํ๋ ๊ฒฝ๋ก๋ฅผ ๋ฃ์ด์ฃผ๋ฉด ๋จ }
โฌ
์ ๋์ค๋ ๊ฑธ ๋ณผ ์ ์์๐
๊ทธ๋ผ ์ด์ ํ๋ฉด์ ์ ๋์ค๊ฒ ํด์ค์ผํจ
โซ src>pages>posts>[id].js
build time( npm run build )ํ์ ๋ ์ด๋ ํ id์ ํฌ์คํธ๋ค์ด ์๋์ง ์ ์ ์์๐คโ
๐
๐ฏgetStaticPaths : ๋น๋ ์์ ์ ๋์ ์ผ๋ก ์์ฑํ ํ์ด์ง์ id ๋ชฉ๋ก์ ๋ฐํํ๊ณ ,
๐ฏgetStaticProps : ํด๋น id์ ๋ง๋ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์
์ปดํฌ๋ํธ์ props๋ก ์ ๋ฌํ์ฌ ํ์ด์ง๋ฅผ ๋ฏธ๋ฆฌ ์์ฑํ๋ ๋ฐฉ์โจ

์์ธํ์ด์ง ๋ง๋ค๊ธฐ ์ํด ํฌ์คํธ๊ฐ ์ฌ๋ฌ๊ฐ๋๊น ๋์ ๋ผ์ฐํ
์ ํด์ผํจ
์ด๋ ํ ํฌ์คํธ๋ค์ด ์๋์ง ๊ทธ ๊ฒฝ๋ก๋ฅผ ๋ค ๊ฐ์ ธ์ค๊ธฐ ์ํด getStaticPaths ์ด์ฉโญ
๐์ฌ๊ธฐ์ ํด์ค์ผํ๋๊ฑด ๋ชจ๋ ํฌ์คํธ์ id๋ค์ ๊ฐ์ ธ์์ผํจโ

โ
fallback์ true & false ๋ฃ์ด์ค ์ ์์
falseโก์ฌ๊ธฐ์ ํฌ์คํธ๊ฐ 1, 2, 3, 4๊ฐ ์๋ค๊ณ ํ์ ๋
getStaticProps ์์ ๊ฐ๊ฐ์ ํฌ์คํธ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ฌ๊ฑด๋ฐ
๊ฐ์๊ธฐ ์ ์ ๊ฐ 5( pre-render ๋ html ์๋ )๋ก ์ ๊ทผํ์ ๊ฒฝ์ฐ 404 ํ์ด์ง๊ฐ ๋จ๊ฒํจ๐จ
trueโกfallback ํ์ด์ง๋ฅผ ๋ง๋ค์ด์ ๊ทธ๋ถ๋ถ์ ๋ณด์ฌ์ค ์ ์๊ฒ ํด์ฃผ๋ฉด ๋จ
โซ src>utils>posts.js
๐ getSortedPostsData ์์ posts.js๋ก ํ์ผ ๋ฆฌ๋ค์ํจโ

getAllPostsIds( ) ๋ง๋ค์ด์ ์ด ํจ์์ ์ด๋ค ๋ก์ง์ ์์ฑํ ๊นโ
์ง๊ธ posts๊ฐ ๋ ๊ฐ ์๋๋ฐ id( pre-rendering & ssg-ssr )๋ฅผ
๊ฐ์ ธ์ค๋ ๋ก์ง์ ์ฌ๊ธฐ์ ์์ฑํ๋ฉด ๋จโ

fileNames์ ๋ฐฐ์ด๋ก ๋ ๊ฐ์ ํ์ผ ์ด๋ฆ์ด ๋ค์ด๊ฐ์์โ

๊ทธ๋ค์ ๋ฆฌํดํ ๋ fileNames.map ๋ฉ์๋ ์ด์ฉํด์ ํ๋์ fileName ํ๊ณ

์ด๋ค ํ์์ผ๋ก ๋ฆฌํด ํด์ค๊ฑฐ๋๋ฉด [id].js paths: ์์ ๋ค์ด๊ฐ ๊ฑฐ
์ด ํ์์ผ๋ก ํด์ฃผ๋ ค๋ฉด ์ด๋ป๊ฒ ํด์ผํ ๊นโ

โ
id: 'pre-rendering', id: 'ssg-ssr' ์ด๋ ๊ฒ ๋ค์ด๊ฐ์ผํจ
๐ { } ์ค๊ดํธ ํด์คฌ์ผ๋๊น return์ ํด์ค์ผํจ
id๋ฅผ fileName ์์ .md ์ญ์ ํ๋๊นโกpre-rendering & ssg-ssr
โซ src>pages>posts>[id].js

getAllPostsIds( ) ํจ์ ๊ฐ์ ธ์์ paths ์์ ์ด๋ฆ ๋ฆฌํด์์ ์จ์ฃผ๊ธฐ
paths: paths ์ด๋ฆ ๊ฐ์ผ๋๊น paths๋ง ์จ์ฃผ๊ธฐ๐
๐คทโโ๏ธ ๊ทธ๋ฌ๋ฉด ์ฌ๊ธฐ paths ๋ฆฌํดํ๊ฑฐ ์ด๋๋ก ๊ฐ๊น โ
๐ getStaticProps๋ก โ

paths ์์ params๊ฐ ์์ผ๋๊น

params ๊ฐ์ ธ์ดโ
params ์์ id๊ฐ ์์ผ๋๊นโกparams.id
๐ posts/ssg-ssr ๊ฒฝ๋ก๋ก ์์ผ๋ฉด params.id๋ ssg-ssr ์ด๊ฒ ๋๋๊ฑฐ๊ณ ,
๐ posts/rendering ์ผ๋ก ์์ผ๋ฉด pre-rendering์ด ๋๋ ๊ฒ

โ
์ด๊ฑธ ์ด์ฉํด์ ํ์ผ์ ์์ธ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ฌ๊ฑด๋ฐ ์ฌ๋ฐ๋ฅธ ํ์์ผ๋ก ๊ฐ์ ธ์์ผํจ

์ ๋ฐ์ดํฐ ๊ฐ์ ธ์ค๋ ๊ฑธ ์ฌ๊ธฐ์ ์์ฑํด์ฃผ๋ฉด ๋จ๐โโ๏ธ
๐ ์ฌ๋ฐ๋ฅธ ๋ฐ์ดํฐ ๊ฐ์ ธ์จ ๋ด์ ์ด๋ป๊ฒ ๋ฆฌํดํ ๊น โ

โก์ฌ๊ธฐ์ ๋ฆฌํดํ๋๊ฑด ์ด props๋ก ๊ฐ๋๊ฑฐ๋๊น

props ํ๊ณ ๋ฆฌํดํ ๊ฐ์ ssg-ssr ํ๋์ ํฌ์คํธ์ ๋ํ ๋ฐ์ดํฐ๋ฅผ ์ฌ๊ธฐ๋ค ๋ฃ์ด์ฃผ๋ฉด ( ์ ์ชฝ์ผ๋ก ๊ฐ๊ฑฐ์โ )

๋ฐ์ดํฐ ๊ฐ์ ธ์ค๋ ๋ก์ง์ ์ฌ๊ธฐ๋ค ์์ฑํด๋ณด์โ
โซ src>utils>posts.js

์ด๊ฒ๋ posts.js ์์ ๋ง๋ ๋ด์ ๊ฐ์ ธ์ฌ๊ฑฐ์
์ฌ๊ธฐ์ ๋น๋๊ธฐ๋ฅผ ํด์ค์ผํ๋ ๋ถ๋ถ์ด ์์ด์ async๋ก ๊ฐ์ธ์ค ๊ฒ๐
์ด ํจ์์ ๋ชฉํ๋ ํ์ผ์ ๋ฐ์ดํฐ ์ ์ฒด๋ฅผ ๊ฐ์ ธ์ค๋ ๊ฒ๐ค
getSortedPostsData๋ ๋น์ทํ ๊ฑด๋ฐ

์ฌ๊ธฐ์ ํ๋ ๊ฑด ์ด๋ถ๋ถ๋ง ๊ฐ์ ธ์์์โญ

๐ ์๋, ์ฒจ์ ํ๋ฉด ๋ณด์ฌ์ค๋ title ํ๊ณ date๋ง ๋ณด์ฌ์ค์ผํ๊ธฐ ๋๋ฌธ
โ
title ํด๋ฆญํ๊ณ ๋ค์ด๊ฐ๋ ํ์ด์ง์์ ํ์ผ์ ์ ์ฒด ๋ฐ์ดํฐ๊ฐ ํ์ํจ

[id].js ์ฌ๊ธฐ์ getPostData ํจ์ ํธ์ถํ ๊ฑด๋ฐ๐ข( ์ด๋ params.id๋ฅผ ๋ฃ์ด์ค๊ฑฐ์โ )
๐โกpre-rendering ์ธ์ง ์๋ ssg-ssr ์ธ์ง๋ฅผ ๋ฃ์ด์ค ๊ฒ

id ๋ฐ์์ค์โ
๊ทธ๋ด์ ์ด๋ ๊ฒ ํ๋ฉด ํ์ผ์ ์ด๋ฆ์ด ๋๋๊ฑฐ์
( ํ์ผ์ ์ด๋ฆ์ ์์์ผ ํด๋น ํ์ผ์ ๋ฐ์ดํฐ๋ฅผ ์ฝ์ ์๊ฐ ์์๐ )

๐ฃ์ฝ์ ๋โโกfs( ํ์ผ ์์คํ
).readFileSync( )๋ก ์ฝ์ด์ค ๊ฒ๐
( ๐์ ์ฒด path๋ฅผ ๋ฃ์ด์ค์ผํ๋ฏ๋กโกpostsDirectory( posts ํด๋๊น์ง์ ๊ฒฝ๋ก )โid.md๐ฅ )
fullPath ๋ฃ์ด์ฃผ๊ณ ์ต์
์๋ค๊ฐ encoding ์ต์
'utf-8' ๋ฃ์ด์ค
๋ฃ์ด์ฃผ๋ฉด ํ์ผ์ ์ปจํ
์ธ ๋ฅผ ๋ฆฌํด์ ํ๋๋ฐ ์ด๋ฆ์ fileContents๋ก ํด์ค๊ฑฐ์๐
๋จผ์ ํ์ผ์ ์ด๋ ๊ฒ ๋ณ๊ฒฝํ๊ณ
๋์ค์ ์ด๋ ๊ฒ ๋ณ๊ฒฝํด์ค๊ฑฐ์๐ฎ

โ์ฒ๋ผ ๋ณ๊ฒฝํด์ฃผ๊ธฐ ์ํด matter ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ด์ฉํด์ fileContents ๋ฃ์ด์ฃผ๊ธฐ
๋ฉํ๋ฐ์ดํฐ๋ฅผ ๋ถ์( parse )ํด์ ์ ๋ฐ์์ผ๋ก ๋ง๋๋๊ฑฐ์
โ์ฒ๋ผ html string ์ผ๋ก ๋ง๋ค์ด์ฃผ๋ ๋ถ๋ถ์ ์ํ ์ฝ๋ ๋ง๋ค์โ
๐Markdown ํ์ฑํ๊ณ ๋ณํํ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ

๐Markdown์ HTML๋ก ๋ฐ๊ฟ์ฃผ๋ ํ๋ฌ๊ทธ์ธ ( ๐ฅํ๋ ๋ ์ค์นํ๊ธฐ )



contentHtml ์ ๋ถ๋ถ์ด ์ด๋ถ๋ถ์ ํด๋นโ

๐ขgetPostData ์ด ํจ์๋ฅผ ํธ์ถํ์ ๋ ๊ฐ์ฒด ํ์์ผ๋ก ๋ฆฌํด์ ํด์ค๊ฑฐ์๐
๐๋ ์ด id ๋ผ๊ณ ํด์ฃผ๊ณ , ์ด html string ๋ถ๋ถ๋ contentHtml ์ด๋ ๊ฒ ํด์ฃผ๊ณ
์ฌ๊ธฐ์ ๋ค์ด์๋๊ฒ

์ด๋ถ๋ถ๋ ์๊ณ ์ฌ๊ธฐ๋ ์์ง๋ง content ๋ถ๋ถ์ ๊ฐ๊ณตํ์ง ์๊ณ ์ ๋ณด๋ด์ค ๋ถ๋ถ์โญ
'๋งํฌ๋ค์ด'์ ๋ฐ๋ก html๋ก ์ฌ์ฉํ ์ ์์โ
br ํ๊ทธ๋ฉฐ pํ๊ทธ๋ฉฐ ์์ํ
๋ฐ ์ด๊ฑธ html๋ก string ์ผ๋ก ๊ฐ๊ณตํด์ฃผ๋ ๋ถ๋ถ์ด
๋ฐ๋ก ์ด๋ถ๋ถโ

ํ์ผ์ title / date / content ์ด ์ ์ฒด์ ์ธ ๋ถ๋ถ ๋ค ๋ด๋ ค์ฃผ๊ธฐ ์ํด์
์์ชฝ์์ ํ๋ ๊ฒ์ฒ๋ผ ...matterResult.data ํด์ฃผ๋ฉด ๋จ๐ค
โซ src>pages>posts>[id].js

await const postData ํ๊ณ postData๋ฅผ ๋ด๋ ค์ฃผ๊ธฐ
postData ์ด๋์ ๊ฐ์ ธ์ค์งโ

๐ { postData } ์ฌ๊ธฐ์ ๊ฐ์ ธ์ดโ
์ฝ์๋ก ์ฐ์ด๋ณด๋ฉด
โฌ
์ด๋ฐ์์ผ๋ก ๋ฐ์ดํฐ ์ ๊ฐ์ ธ์จ๊ฑธ ๋ณผ ์ ์์๐
โ
์ด์ ํ๋ฉด์ ๋ฐ์ดํฐ๋ค์ด ์ ๋์ค๊ฒ ํด์ฃผ๋ฉด ๋จ
๐์์ธํ์ด์ง์์ ๋ฐ์ดํฐ ์ ๋์ค๊ฒ ํ๊ธฐ

title ์ ๋ชฉ ๋ฐ๊ฟ์ฃผ๊ธฐ

article ์ด๋ผ๋ ์๋ฉํฑ ํ๊ทธ ์ฌ์ฉํด์ title, date ํด์ฃผ๊ธฐ


๊ทธ ๋ด์ ์ฌ๊ธฐ ๋ถ๋ถ ๋ณด์ฌ์ค์ผํจ

๐จdangerouslySetInnerHTML : ๋ฆฌ์กํธ์์ HTML์ ์ง์ ์ฝ์
ํ ๋ ์ฌ์ฉํ๋ ์์ฑโ
โฌ
๊ทธ๋ผ ์ด๋ ๊ฒ ์ ๋์ค๋ ๊ฑธ ๋ณผ ์ ์์๐
์ฌ๊ธฐ๋ก ๊ฐ์ title์ ํด๋ฆญํด๋

ํด๋น ํ์ผ ์์ธํ์ด์ง๊ฐ ์ ๋์ค๋ ๊ฑธ ๋ณผ ์ ์์๐ฅณ
๐คฉํต์ฌ
โ Next.js์ pages ๋ผ์ฐํฐ๋ฅผ ์ด์ฉํ ๋ ํ์ผ ์์คํ
๋ผ์ฐํ
์ด์ฉํด์ ํ์ด์ง ์ฒ๋ฆฌํ๋ค๋ ๊ฒ
๐ ์ด๋ป๊ฒ ํด๋ ๊ตฌ์กฐ๋ฅผ ๊ฐ์ ธ๊ฐ๋์ง ( ํด๋๋ ํ์ผ ์ด๋ฆ )
โ ๋ฐ์ดํฐ ํจ์นญ ์ด๋ค์์ผ๋ก ํ๋์ง ( getStaticProps, getStaticPaths, ... )