Bellog

๐Ÿ˜

์ธ์ƒ ์ฒซ ๋‚˜๋งŒ์˜ ๋ธ”๋กœ๊ทธ๋ฅผ ๋งŒ๋“  ๊ฑด์— ๋Œ€ํ•˜์—ฌ

blog

2025-04-01

๋“œ๋””์–ด ๋ธ”๋กœ๊ทธ๋ฅผ ๋งŒ๋“ค์—ˆ๋‹ค.

์˜›๋‚ ๋ถ€ํ„ฐ ํ•ด์•ผ์ง€ ํ•ด์•ผ์ง€ ํ–ˆ์—ˆ์ง€๋งŒ, ๊ทธ๋งŒํผ ๋ฏธ๋ฃจ๊ณ  ๋ฏธ๋ค„๋‘” โ€˜๋‚˜๋งŒ์˜ ๋ธ”๋กœ๊ทธโ€™ ๋งŒ๋“ค๊ธฐ!
์ด๋ฒˆ์— ์ง€์›์„œ๋ฅผ ์ž‘์„ฑํ•˜๋ฉด์„œ, ๋‚˜๋งŒ์˜ ๊ฐ•์ ์ด ๋ญ˜๊นŒ์— ๋Œ€ํ•ด์„œ ๋งŽ์ด ๊ณ ๋ฏผํ–ˆ๊ณ  ์•ž์œผ๋กœ ์–ด๋–ค ๊ฒฝ์Ÿ๋ ฅ์„ ๊ฐ–์ถฐ์•ผ ํ• ๊นŒ?๋ฅผ ๋งŽ์ด ์ƒ๊ฐํ–ˆ๋‹ค.

๊ธฐ๋ก์€ ๊ฑฐ์ง“๋ง์„ ํ•˜์ง€ ์•Š๋Š”๋‹ค.

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

๊ทธ๋ฅผ ์œ„ํ•ด์„  ๋”๋”์šฑ ๋‚˜๋งŒ์˜ ๋ธ”๋กœ๊ทธ ํ”„๋กœ์ ํŠธ๋ฅผ ์™„์„ฑํ•ด์•ผ๋งŒ ํ–ˆ๋‹ค.

์–ด์งธ์„œ ๋ธ”๋กœ๊ทธ๋ฅผ ๋งŒ๋“ค์—ˆ๋‚˜?

์‚ฌ์‹ค ์ด์ „์—๋Š” ๋ฒจ๋กœ๊ทธ์— ๊ธ€์„ ์ฃผ๋กœ ์ผ๋‹ค. ๋ฒจ๋กœ๊ทธ๋Š” ํ™•์‹คํžˆ ๊ฐ€๋ณ๊ฒŒ ๊ธ€์„ ์“ฐ๊ธฐ์—” ์ข‹์€ ํ”Œ๋žซํผ์ด๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋”ฑ ๊ฑฐ๊ธฐ๊นŒ์ง€๋‹ค. ๊ฐ€์žฅ ํฐ ๋ถˆํŽธํ•จ์€ ์ด๋ฏธ์ง€์˜ ํฌ๊ธฐ ๋ฐ ์Šคํƒ€์ผ ์กฐ์ •์ด ๋ฒˆ๊ฑฐ๋กญ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๋ธ”๋กœ๊ทธ ๊พธ๋ฏธ๊ธฐ๊ฐ€ ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค(์ด๊ฒŒ ๊ฐ€์žฅ ํฐ ์ด์œ ์ž„).

์–ด๋””์„ ๊ฐ€ ๊ทธ๋Ÿฐ ๊ธ€์„ ๋ณธ ์ ์ด ์žˆ๋‹ค. โ€œํ”„๋ก ํŠธ์—”๋“œ ๊ฐœ๋ฐœ์ž๋ผ๋ฉด, ์ž๊ธฐ ๋ธ”๋กœ๊ทธ ์ •๋ˆ ๋งŒ๋“ค์–ด์•ผ ํ•˜์ง€ ์•Š๊ฒ ๋Š”๊ฐ€?โ€

๋‚˜๋„ ์ด ๊ธ€์— ๊ณต๊ฐํ•˜๋ฉฐ ๋‚˜๋งŒ์˜ ๋ธ”๋กœ๊ทธ๋ฅผ ๋งŒ๋“ค์–ด๋ณด๊ฒ ๋…ธ๋ผ ๋‹ค์ง์„ ํ•œ์ง€ ์–ด์–ธ 1๋…„. . . .

์‚ฌ์‹ค ๊ทธ ๋™์•ˆ ์ข€ ๋ฐ”๋นด๊ธฐ๋„ ํ•˜๊ณ  ๋ฌด์—‡๋ณด๋‹ค ๋ธ”๋กœ๊ทธ๋ฅผ ๋งŒ๋“ค ๋™๊ธฐ๊ฐ€ ๋ถ€์กฑํ–ˆ๋‹ค. ์ง€๊ธˆ ๋ฒจ๋กœ๊ทธ๋กœ๋„ ์ถฉ๋ถ„ํžˆ ์ž˜ ์“ฐ๊ณ  ์žˆ๊ณ , ๋…ธ์…˜์—๋„ ํ”„๋กœ์ ํŠธ๋ฅผ ํ•˜๋ฉด์„œ ๊ฒช์€ ํŠธ๋Ÿฌ๋ธ” ์ŠˆํŒ…๊ธ€์„ ์ž‘์„ฑํ•ด๋‘๊ณ  ์žˆ์—ˆ๊ธฐ ๋•Œ๋ฌธ์— โ€˜๊ธฐ๋ก๋งŒ ์ž˜ ํ•ด๋‘๋ฉด ๋˜์ง€~โ€™ ๋ผ๋Š” ์ƒ๊ฐ์œผ๋กœ ์ง€๋‚ด๊ณ  ์žˆ์—ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ 25๋…„์ด ๋ฐ์•„์™”๊ณ  ๋‚˜๋Š” ์Šฌ์Šฌ ์ทจ์ค€์— ๋ฐœ์„ ๋“ค์˜€๋‹ค. ์ทจ์ค€์„ ์œ„ํ•ด์„œ๋Š” ํฌํŠธํด๋ฆฌ์˜ค๋ฅผ ๋งŒ๋“ค์–ด์•ผ ํ–ˆ๋Š”๋ฐ, ํŠธ๋Ÿฌ๋ธ” ์ŠˆํŒ… ๊ธ€์ด ์—ฌ๊ธฐ ์ €๊ธฐ์— ๋ถ„์‚ฐ๋˜์–ด ์žˆ์—ˆ๋‹ค. ํ”„๋กœ์ ํŠธ A์˜ ํŠธ๋Ÿฌ๋ธ” ์ŠˆํŒ… ๊ธ€์€ ํ”„๋กœ์ ํŠธ A ๋…ธ์…˜์— ์žˆ์—ˆ๊ณ , ํ”„๋กœ์ ํŠธ B์˜ ๊ธ€์€ B ๋…ธ์…˜์— ์ž‘์„ฑ๋˜์–ด ์žˆ์—ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๋‚˜๋Š” ํ•ด๋‹น ๊ธ€๋“ค์„ ๋ชจ๋‘ ๋ณต์‚ฌํ•ด์„œ ๋‚ด ๋…ธ์…˜์— ๋ถ™์—ฌ๋„ฃ๊ธฐ ํ•œ ํ˜•ํƒœ๋กœ ๊ด€๋ฆฌํ•˜๊ณ  ์žˆ์—ˆ๋‹ค.

์œ„์™€ ๊ฐ™์€ ํ˜•ํƒœ์ด๋‹ค ๋ณด๋‹ˆ, ์›๋ณธ ๊ธ€์ด ์—…๋ฐ์ดํŠธ ๋˜๋ฉด ๋‚ด๊ฐ€ ์†์ˆ˜ ๋‚ด ๋…ธ์…˜์— ์žˆ๋Š” ๋ณต์‚ฌ๋ณธ๋„ ์—…๋ฐ์ดํŠธ๋ฅผ ํ•ด์ค˜์•ผ ํ–ˆ๋‹ค. ์‚ฌ์‹ค ์ด๊ฑด ์—„์ฒญ๋‚˜๊ฒŒ ํฐ ๋ฌธ์ œ๊ฐ€ ์•„๋‹ˆ์—ˆ๋‹ค. ๊ฐ€์žฅ ํฐ ๋ฌธ์ œ๋Š” โ€˜๋ธ”๋กœ๊ทธ์˜ ์ •์ฒด์„ฑโ€™์ด์—ˆ๋‹ค.

๋‚ด ๋ฒจ๋กœ๊ทธ(Velog)๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜ + ์ผ์ƒ ํšŒ๊ณ ๋ก์œผ๋กœ ์‚ฌ์šฉ๋˜๊ณ  ์žˆ์—ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ํŠธ๋Ÿฌ๋ธ” ์ŠˆํŒ…๊ณผ ๊ฐ™์ด ๊ธฐ์ˆ  ๊ด€๋ จ๋œ ๊ธ€๋„ ์–ด๋”˜๊ฐ€์— ์ €์žฅ์„ ํ•ด์•ผ ํ•˜๋Š”๋ฐ, ๋‚˜๋Š” ๋…ธ์…˜, ๋ฒจ๋กœ๊ทธ ๋‘˜ ๋‹ค ๋‚ด ๋ง˜์— ์ฉ ๋“ค์ง€ ์•Š์•˜๋‹ค. ๋ฒจ๋กœ๊ทธ๋Š” ์œ„์—์„œ ๋งํ–ˆ๋“ฏ์ด ์ž์œ ๋กœ์šด ์ปค์Šคํ„ฐ๋งˆ์ด์ง•์ด ๋ถˆ๊ฐ€๋Šฅํ•˜๊ณ , ๋…ธ์…˜์€ ๊ธ€๋“ค์„ ๊ด€๋ฆฌํ•˜๊ธฐ์—” ๋›ฐ์–ด๋‚˜์ง€๋งŒ ๊ทธ ๊ธ€๋“ค์„ ๋ณด์—ฌ์ฃผ๋Š” ๊ฒƒ์— ์žˆ์–ด์„œ๋Š” ๋„ˆ๋ฌด โ€˜๋Œ€์ค‘์ โ€™์ด์—ˆ๋‹ค.

๋‹ค๋ฅธ ์‚ฌ๋žŒ๋“ค๋„ ๋ฒจ๋กœ๊ทธ, ๋…ธ์…˜, ํ‹ฐ์Šคํ† ๋ฆฌ, ๋ฏธ๋””์—„ ๋“ฑ ๋‹ค์–‘ํ•œ ํ”Œ๋žซํผ์„ ์ด์šฉํ•˜์—ฌ ์ž์‹ ๋งŒ์˜ ์ด์•ผ๊ธฐ๋ฅผ ๊ธฐ๋กํ•ด ๋‚˜๊ฐ€๊ณ  ์žˆ์„ ๊ฒƒ์ด๋‹ค. ๋‚ด๊ฐ€ ๋ฉด์ ‘๊ด€์ด๋ผ๋ฉด ์ข€ ์ง€๊ฒจ์šธ ์ˆ˜ ์žˆ๊ฒ ๋‹ค. ๋ผ๋Š” ์ƒ๊ฐ์ด ๋“ค์—ˆ๋‹ค.

๋…ธ์…˜, ๋ฒจ๋กœ๊ทธ, ํ‹ฐ์Šคํ† ๋ฆฌ . . . ๋งจ๋‚  ๋˜‘๊ฐ™๋„ค ์–ด๋”” ์ƒˆ๋กœ์šด ๊ฑฐ ์—†๋‚˜?

ํ‘๋ฐฑ์š”๋ฆฌ์‚ฌ์—์„œ ๋‚˜ํด๋ฆฌ ๋ง›ํ”ผ์•„๊ฐ€ ํŒจ์ž๋ถ€ํ™œ์ „์—์„œ ๋งŽ์€ ์ž๊ทน์ ์ธ ์Œ์‹๋“ค ์†์—์„œ ๋””์ €ํŠธ๋ฅผ ๋‚ด๋†“์•„ ์‚ด์•„๋‚จ๊ณ  ๋‹น๋‹นํžˆ ์šฐ์Šน์„ ์ฐจ์ง€ํ•œ ๊ฒƒ์ฒ˜๋Ÿผ, ๋‚˜๋Š” ๋ฉด์ ‘๊ด€๋“ค์—๊ฒŒ ์ž‘์ง€๋งŒ ์‹ ์„ ํ•จ์„ ์ฃผ๊ณ  ์‹ถ์—ˆ๊ธฐ์— โ€˜๋‚˜๋งŒ์˜ ๋ธ”๋กœ๊ทธโ€™ ํ”„๋กœ์ ํŠธ๋ฅผ ์ถ”์ง„ํ•˜๊ฒŒ ๋˜์—ˆ๋‹ค.

๋ญ๋กœ ๋งŒ๋“ค๊ฑด๋ฐ?

๋‹จ์—ฐ์ฝ” NextJS์˜€๋‹ค. NextJS๊ฐ€ ReactJS ํ”„๋ ˆ์ž„์›Œํฌ๋กœ์„œ ์ ์  ํ”„๋ก ํŠธ๊ฐœ๋ฐœ์ž์˜ ๊ธฐ๋ณธ ์†Œ์–‘ ์ค‘ ํ•˜๋‚˜๋กœ ์ž๋ฆฌ ์žก๊ณ  ์žˆ์œผ๋ฉฐ, SSR, SSG, ISR, Server Component, App router . . . ๋“ฑ๋“ฑ ๋ฐฐ์šธ ๊ฒƒ์ด ์ฐธ ๋งŽ์€ ๋‚˜์—๊ฒŒ๋Š” ๋„์ „ ํˆฌ์„ฑ์ด์ธ ํ”„๋ ˆ์ž„์›Œํฌ์˜€๊ธฐ์— NextJS๋ฅผ ์„ ํƒํ–ˆ๋‹ค.

๋ธ”๋กœ๊ทธ๊ฐ€ ์‚ฌ์‹ค NextJS์˜ ๋ชจ๋“  ๊ธฐ๋Šฅ๋“ค์„ ํ™œ์šฉํ•˜๋ ค๋ฉด ์ •๋ง ๋ณผ๋ฅจ์ด ์ปค์ ธ์•ผ ํ•œ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋‚˜๋Š” ๊ทธ๋Ÿด ์—ญ๋Ÿ‰์ด ์—†์„ ๋ฟ๋”๋Ÿฌ, ์ง€๊ธˆ ๋‹น์žฅ ๊ธ€์„ ์ž‘์„ฑํ•  ๋ธ”๋กœ๊ทธ๊ฐ€ ํ•„์š”ํ–ˆ๋‹ค. ๊ทธ๋ž˜์„œ ์ตœ๋Œ€ํ•œ ์ž‘์€ ๋ณผ๋ฅจ์„ ์ง€ํ–ฅํ•˜๋ฉฐ ์ฐจ์ฐจ ๊ธฐ๋Šฅ๋“ค์„ ์ถ”๊ฐ€ํ•ด ๋‚˜๊ฐ€์ž! ๋ผ๋Š” ์ƒ๊ฐ์œผ๋กœ ์ผ๋‹จ CRN ์ปค๋งจ๋“œ๋ฅผ ๋ˆŒ๋Ÿฌ๋ณด์•˜๋‹ค.

์Šคํƒ€์ผ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋„ ๊ธฐ์กด์— ์‚ฌ์šฉํ–ˆ๋˜ ์Šคํƒ€์ผ๋“œ ์ปดํฌ๋„ŒํŠธ ๋Œ€์‹ ์— ํ…Œ์ผ์œˆ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ๋กœ ํ–ˆ๋‹ค. ์š”์ฆ˜ ๋งค์šฐ ํ•ซํ•˜๊ธฐ๋„ ํ•˜๊ณ  ํ•œ๋ฒˆ์ฏค์€ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ์—ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๋‚˜์ค‘์— ํ…Œ์ผ์œˆ๋“œ๋กœ ํ”„๋กœ์ ํŠธ๋ฅผ ํ•˜๊ฒŒ ๋์„ ๋•Œ ๋„ˆ๋ฌด ํ—ค๋งค์ง€ ์•Š๋„๋ก ์ง€๊ธˆ ๋จผ์ € ๋งค๋ฅผ ๋งž์•„๋‘์ž. ๋ผ๋Š” ์ƒ๊ฐ์ด์—ˆ๋‹ค.

๊ทธ๋Ÿฐ๋ฐ ์ตœ๊ทผ(25/01/22)์— ํ…Œ์ผ์œˆ๋“œ 4.0์ด ์ถœ์‹œํ–ˆ๋‹ค.

์ด์™• ํ•  ๊ฑฐ ์ตœ์‹  ๋ฒ„์ ผ์„ ์‚ฌ์šฉํ•ด๋ณด์ž! ๋ผ๋Š” ์•ผ์š•์„ ๊ฐ–๊ณ  ํ…Œ์ผ์œˆ๋“œ 4.0์œผ๋กœ ํ”„๋กœ์ ํŠธ๋ฅผ ์‹œ์ž‘ํ•˜๊ฒŒ ๋๋‹ค.(์ด๋Ÿฌ์งˆ ๋ง์•˜์–ด์•ผ ํ–ˆ๋Š”๋ฐ. . . )

๊ทธ๋ž˜์„œ ์ด์ œ ๋ญ˜ ํ•˜๋ฉด ๋˜์ง€โ€ฆ?

๋ง‰๋ง‰ํ–ˆ๋‹ค. ๋‹ค๋ฅธ ์‚ฌ๋žŒ๋“ค์€ ์ž˜๋งŒ ๋งŒ๋“ค๋˜๋ฐ, ๋‚˜ ํ˜ผ์ž ๋‚™๋™๊ฐ• ์˜ค๋ฆฌ์•Œ ์ฒ˜๋Ÿผ ๋‘ฅ๋‘ฅ ๋– ๋‹ค๋‹ˆ๋ฉฐ ๋ฌด์—‡์„ ํ•ด์•ผํ• ์ง€ ๊ฐˆํ”ผ๋ฅผ ์žก์ง€ ๋ชปํ–ˆ๋‹ค. ์šฐ์„  ์ธํ„ฐ๋„ท์— โ€˜NextJS ๋ธ”๋กœ๊ทธ ๋งŒ๋“ค๊ธฐโ€™๋ฅผ ๊ฒ€์ƒ‰ํ•ด๋ณด๋‹ˆ ์ •๋ง ๋งŽ์€ ์˜ˆ์‹œ๋“ค์ด ๋‚˜์™”๋‹ค. ๊ทธ๋ž˜์„œ ์ผ๋‹จ ๊ทธ ์˜ˆ์‹œ๋“ค์„ ๋”ฐ๋ผํ•ด ๋ณด์•˜๋‹ค.

๋ฌด์ˆ˜ํžˆ ๋งŽ์€ ์—๋Ÿฌ๋“ค์ด ๋‚˜๋ฅผ ๋ฐ˜๊ฒจ์คฌ๋‹ค.

JUST ๋ณต๋ถ™์€ ์ด๋ž˜์„œ ์œ„ํ—˜ํ•˜๋‹ค๋Š” ๊ฒƒ์„ ๋‹ค์‹œ ํ•œ๋ฒˆ ๊นจ๋‹ฌ์•˜๋‹ค. ๊ทธ๋ž˜์„œ ์ˆ˜๋งŽ์€ ์‚ฝ์งˆ์„ ํ•˜๋ฉฐ, ๋งŽ์€ ์‹œ๊ฐ„๋“ค์„ ๋ณด๋‚ธ ๊ฒฐ๊ณผ!! ๋ฌด์–ผ ํ•ด์•ผํ• ์ง€ ์–ด๋Š์ •๋„ ์•Œ ์ˆ˜ ์žˆ์—ˆ๋‹ค.

์šฐ์„  ๋ธ”๋กœ๊ทธ ๊ธ€์„ ๋งˆํฌ๋‹ค์šด์œผ๋กœ ์ž‘์„ฑํ•ด์„œ ์ด๋ฅผ HTML๋กœ ํŒŒ์‹ฑํ•˜๋Š” ์ž‘์—…์ด ํ•„์š”ํ•˜๋‹ค. ์ด๋ฅผ ์œ„ํ•ด์„œ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ๋„์›€์„ ๋ฐ›์•„์•ผ ํ–ˆ๋‹ค.

๋Œ€ํ‘œ์ ์ธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ 2๊ฐœ๋ฅผ ๋ถ„์„ํ•ด๋ณด์•˜๋‹ค.

@next/mdx

NextJS์—์„œ ๊ณต์‹์œผ๋กœ ์ง€์›ํ•˜๋Š” ๋กœ์ปฌ์—์„œ์˜ ๋งˆํฌ๋‹ค์šด ํŒŒ์ผ์„ HTML๋กœ ํŒŒ์‹ฑํ•  ์ˆ˜ ์žˆ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ด๋‹ค. MDX ํŒŒ์ผ์„ ํ”„๋กœ์ ํŠธ ๋‚ด์— ๊ทธ๋Œ€๋กœ importํ•ด์„œ ์‚ฌ์šฉํ•˜๋‹ˆ, ํŒŒ์ผ ๊ธฐ๋ฐ˜ ๋ผ์šฐํŒ…์ด ์ž๋™์œผ๋กœ ์ง€์›๋˜์–ด ๋ณ„๋„์˜ ๋ณต์žกํ•œ ์„ค์ • ์—†์ด๋„ ์‰ฝ๊ฒŒ ์“ธ ์ˆ˜ ์žˆ๋‹ค. ๋นŒ๋“œ ํƒ€์ž„์— MDX ํŒŒ์ผ์ด ํŒŒ์‹ฑ๋˜์–ด ๋Ÿฐํƒ€์ž„์—์„œ๋Š” ํŒŒ์‹ฑ ์˜ค๋ฒ„ํ—ค๋“œ ์—†์ด ๋น ๋ฅธ ๋ Œ๋”๋ง์„ ๋ณด์žฅํ•ด์ค€๋‹ค.

next-mdx-remote

์„œ๋ฒ„์˜ getStaticProps๋‚˜ getServerProps์—์„œ MDX ์ฝ˜ํ…์ธ ๋ฅผ fetchํ•˜๊ฑฐ๋‚˜ ๋กœ์ปฌ ํŒŒ์ผ์„ ์ฝ์–ด ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์–ด, CMS๋‚˜ API ๋“ฑ ์™ธ๋ถ€ ์†Œ์Šค์™€์˜ ์—ฐ๋™์ด ์šฉ์ดํ•˜๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ํŒŒ์ผ ๊ธฐ๋ฐ˜ ๋ผ์šฐํŒ…์„ ์ž๋™์œผ๋กœ ์ œ๊ณตํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์—, MDX ์ฝ˜ํ…์ธ ๋ฅผ props๋กœ ์ „๋‹ฌํ•˜๋Š” ๋“ฑ์˜ ์ถ”๊ฐ€ ์ž‘์—…์ด ํ•„์š”ํ•˜๋‹ค. ๊ฑฐ๊ธฐ์— ๋”๋ถˆ์–ด MDX ํŒŒ์ผ ๋‚ด import/export ๋ฌธ๋ฒ• ์ง€์›์ด ์ œํ•œ์ ์ด๋‹ค. ๋งŒ์•ฝ ๊ธ€๋“ค์„ ์™ธ๋ถ€ ์†Œ์Šค๋กœ๋ถ€ํ„ฐ ๋ฐ›์•„์˜ค๋Š” ๋ฐฉ์‹์ด์—ˆ๋‹ค๋ฉด, ํ•ด๋‹น ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ–ˆ์„ ๊ฒƒ์ด๋‹ค.

์œ„ ์š”์†Œ๋“ค์„ ๊ณ ๋ คํ•˜์—ฌ ๋‚˜๋Š” ์„ค์ •์ด ๋‹จ์ˆœํ•˜๊ณ  ํŒŒ์ผ ๊ธฐ๋ฐ˜ ๋ผ์šฐํŒ…์„ ์ž๋™์œผ๋กœ ์ง€์›ํ•˜๋ฉฐ, ๋กœ์ปฌ MDX ์ฝ˜ํ…์ธ ๋ฅผ ํ™œ์šฉํ•˜๋Š” @next/mdx ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ๋กœ ๊ฒฐ์ •ํ–ˆ๋‹ค!

@next/mdx ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์‚ฌ์šฉํ•˜๊ธฐ

์ž์„ธํ•œ ๋‚ด์šฉ์€ ๊ณต์‹ ๋ฌธ์„œ์—์„œ ๋‹ค๋ค„์ฃผ๊ณ  ์žˆ๋‹ค. (์‚ฌ์‹ค ๊ทธ๋ฆฌ ์ž์„ธํ•˜์ง€ ์•Š์€ ๊ฒƒ ๊ฐ™๋‹คใ… )

์ปค๋งจ๋“œ๋กœ ์„ค์น˜ํ•ด์ฃผ๊ณ 

1npm install @next/mdx @mdx-js/loader @mdx-js/react @types/mdx

next.config ํŒŒ์ผ์— ์ถ”๊ฐ€ํ•ด์ฃผ๊ณ 

next.config.ts
1import createMDX from "@next/mdx";
2
3/** @type {import('next').NextConfig} */
4const nextConfig = {
5 // Configure `pageExtensions` to include markdown and MDX files
6 pageExtensions: ["js", "jsx", "md", "mdx", "ts", "tsx"],
7 // Optionally, add any other Next.js config below
8};
9
10const withMDX = createMDX({
11 // Add markdown plugins here, as desired
12});
13
14// Merge MDX config with Next.js config
15export default withMDX(nextConfig);

srcํด๋” ๋ฐ”๋กœ ์•„๋ž˜ ๋˜๋Š” ํ”„๋กœ์ ํŠธ ์ตœ์ƒ๋‹จ์— mdx-components.tsx ํŒŒ์ผ์„ ๋งŒ๋“ค์–ด์ค˜์•ผ ํ•œ๋‹ค. ์ฐธ๊ณ ๋กœ @next/mdx๋Š” App Router๋งŒ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค!

mdx-components.tsx
1import type { MDXComponents } from "mdx/types";
2
3export function useMDXComponents(components: MDXComponents): MDXComponents {
4 return {
5 ...components,
6 };
7}

๋‚ด App Router ๊ตฌ์กฐ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

1src/app
2โ”œโ”€โ”€ (contents)
3โ”‚ โ”œโ”€โ”€ layout.tsx
4โ”‚ โ”œโ”€โ”€ markdownTest
5โ”‚ โ”‚ โ””โ”€โ”€ page.mdx
6โ”‚ โ””โ”€โ”€ notion
7โ”‚ โ””โ”€โ”€ page.mdx
8โ”œโ”€โ”€ about
9โ”‚ โ””โ”€โ”€ page.tsx
10โ”œโ”€โ”€ layout.tsx
11โ”œโ”€โ”€ page.tsx
12โ”œโ”€โ”€ posts
13โ”‚ โ””โ”€โ”€ page.tsx
14โ””โ”€โ”€ projects
15 โ””โ”€โ”€ page.tsx

ํ•ด๋‹น mdx ํŒŒ์ผ๋“ค์„ ์–ด๋–ป๊ฒŒ ๊ฐ€์ ธ์™”๋ƒ? ์œ„์—์„œ๋„ ๋งํ–ˆ๋“ฏ์ด @next/mdx๋Š” src/app/(contents) ๋””๋ ‰ํ† ๋ฆฌ์— ์œ„์น˜ํ•œ MDX ํŒŒ์ผ๋“ค์„ ์ง์ ‘ importํ•˜์—ฌ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

getPosts
1import { PostData } from "@/types";
2import { readdir } from "fs/promises";
3import path from "path";
4
5export async function getPosts(): Promise<PostData[]> {
6 // MDX ํŒŒ์ผ๋“ค์ด ์œ„์น˜ํ•œ ๋””๋ ‰ํ† ๋ฆฌ
7 const postsDir = path.join(process.cwd(), "src", "app", "(contents)");
8
9 // ๊ฐ ํฌ์ŠคํŠธ ๋””๋ ‰ํ† ๋ฆฌ ์กฐํšŒ
10 const slugs = (await readdir(postsDir, { withFileTypes: true })).filter(
11 (dirent) => dirent.isDirectory()
12 );
13
14 // ๊ฐ MDX ํŒŒ์ผ์—์„œ metadata๋ฅผ ์ถ”์ถœํ•œ ํ›„ PostData ํ˜•ํƒœ๋กœ ๋งคํ•‘
15 const posts = await Promise.all(
16 slugs.map(async (dirent) => {
17 const { meta } = await import(
18 `../app/(contents)/${dirent.name}/page.mdx`
19 );
20
21 return {
22 slug: dirent.name,
23 emoji: meta.emoji || "",
24 title: meta.title || "",
25 date: meta.date || meta.publishDate || "",
26 preview: meta.preview || "",
27 tag: meta.tag || "",
28 } as PostData;
29 })
30 );
31
32 posts.sort((a, b) => +new Date(b.date) - +new Date(a.date));
33
34 return posts;
35}

์ดํ›„์— ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์‚ฌ์šฉํ•ด์ฃผ๋ฉด ๋œ๋‹ค.

usage
1export default async function Home() {
2 const posts = await getPosts();
3 const slicedPosts = posts.slice(0, 5);
4
5 return (
6 <div className="flex flex-col justify-between items-center gap-[10px] w-full">
7 <Intro />
8 <PostList posts={slicedPosts} />
9 </div>
10 );
11}

์ด์™ธ์—๋„ ํ–ˆ๋˜ ์‚ฝ์งˆ๋“ค์ด ์ •๋ง ๋งŽ๋‹ค. ๊ทธ๊ฑด ๋‹ค๋ฅธ ํฌ์ŠคํŠธ์—์„œ ๋‹ค๋ฃจ๋„๋ก ํ•˜๊ฒ ๋‹ค. ์ผ๋‹จ ์˜ค๋Š˜์€ ์—ฌ๊ธฐ๊นŒ์ง€! ๋‹ค๋“ค ๋‚˜์˜ ์ฒซ ๋ธ”๋กœ๊ทธ ๊ฐœ์„ค์„ ์ถ•ํ•˜ํ•ด์ค˜์„œ ์ •๋ง ๊ณ ๋ง™๋‹ค! Thank you guys~~~~~๐Ÿ˜