{"id":919,"date":"2026-05-20T09:57:02","date_gmt":"2026-05-20T01:57:02","guid":{"rendered":"https:\/\/junai.ai\/blog\/nextjs-mini-project-26\/"},"modified":"2026-05-20T09:57:02","modified_gmt":"2026-05-20T01:57:02","slug":"nextjs-mini-project-26","status":"publish","type":"post","link":"https:\/\/junai.ai\/blog\/nextjs-mini-project-26\/","title":{"rendered":"\uc2e4\uc804 \ubbf8\ub2c8 \ud504\ub85c\uc81d\ud2b8 \u2014 \ube14\ub85c\uadf8 \uc0ac\uc774\ud2b8 \uc644\uacb0"},"content":{"rendered":"\n<!-- WordPress REST API \ubc1c\ud589\uc6a9 HTML (\uc790\ub3d9 \uc0dd\uc131) -->\n<!-- WP-FEATURED-MEDIA-ID: 865 -->\n<div style=\"max-width:800px;margin:0 auto;\">\n<style>\n:root {--color-primary:#4f46e5;--color-accent:#6366f1;--color-bg:#fafbfc;--color-bg-card:#fff;--color-text:#1a202c;--color-text-muted:#64748b;--hero-start:#1e1b4b;--hero-end:#4338ca;}\n*{box-sizing:border-box;}\n.container{max-width:760px;margin:0 auto;padding:0 24px 80px;}\n.hero{background:linear-gradient(135deg,var(--hero-start) 0%,var(--hero-end) 100%);color:#fff;padding:80px 24px 60px;text-align:center;}\n.hero .eyebrow{display:inline-block;font-size:14px;color:#a78bfa;font-weight:700;letter-spacing:0.1em;text-transform:uppercase;margin-bottom:14px;}\n.hero h1{font-size:36px;margin:0 0 16px;line-height:1.3;font-weight:800;}\n.hero p{color:#c7d2fe;font-size:18px;max-width:640px;margin:0 auto;line-height:1.6;}\n.hero img{width:100%;max-width:640px;height:auto;margin:32px auto 0;border-radius:10px;display:block;}\narticle{padding-top:48px;}\narticle h2{font-size:26px;margin:56px 0 20px;padding-left:14px;border-left:5px solid var(--color-accent);line-height:1.4;}\narticle h3{font-size:19px;margin:32px 0 12px;color:var(--color-primary);}\narticle p{margin:16px 0;}\narticle strong{color:var(--color-primary);font-weight:700;}\narticle code{background:#eef2ff;padding:2px 8px;border-radius:4px;font-family:'SF Mono',Menlo,Consolas,monospace;font-size:14px;color:#4338ca;}\n.databox{background:#eef2ff;border-left:4px solid var(--color-accent);padding:16px 20px;margin:24px 0;border-radius:0 8px 8px 0;font-size:15.5px;}\n.databox strong{color:var(--color-primary);}\n.warnbox{background:linear-gradient(135deg,#fef3c7 0%,#fde68a 100%);padding:16px 20px;margin:24px 0;border-radius:8px;font-size:15.5px;}\n.tablewrap{overflow-x:auto;-webkit-overflow-scrolling:touch;margin:22px 0;}\ntable{width:100%;border-collapse:collapse;font-size:15px;background:var(--color-bg-card);}\nth,td{padding:11px 12px;text-align:left;border-bottom:1px solid #e2e8f0;vertical-align:top;}\nth{background:#f1f5f9;font-weight:700;color:#0f172a;}\ntd:first-child,th:first-child{font-weight:700;}\n@media (max-width:560px){.tablewrap table,.tablewrap thead,.tablewrap tbody,.tablewrap tr,.tablewrap th,.tablewrap td{display:block;width:auto;}.tablewrap thead{display:none;}.tablewrap tr{margin:0 0 14px;border:1px solid #e2e8f0;border-radius:10px;overflow:hidden;}.tablewrap td{border:none;border-bottom:1px solid #f1f5f9;padding:9px 14px;}.tablewrap td:first-child{background:#f1f5f9;font-weight:800;font-size:15.5px;}.tablewrap td:last-child{border-bottom:none;}.tablewrap td[data-label]::before{content:attr(data-label) \" \u2014 \";font-weight:700;color:var(--color-primary);}}\n.code-block{background:#0f172a;color:#e2e8f0;padding:16px 20px;border-radius:8px;font-family:'SF Mono',Menlo,Consolas,monospace;font-size:14px;line-height:1.6;margin:20px 0;overflow-x:auto;white-space:pre;}\n.cta{background:linear-gradient(135deg,#4f46e5 0%,#6366f1 100%);color:#fff;padding:28px 24px;border-radius:12px;margin:48px 0 0;text-align:center;}\n.cta h3{color:#fff;margin:0 0 8px;font-size:20px;}\n.cta p{color:#c7d2fe;margin:0;font-size:15.5px;}\n.footer-nav{margin-top:32px;padding-top:20px;border-top:1px solid #e2e8f0;font-size:14px;color:var(--color-text-muted);}\n.footer-nav a{color:var(--color-primary);text-decoration:none;}\n@media (max-width:480px){.hero h1{font-size:26px;}.hero p{font-size:16px;}article h2{font-size:21px;}article h3{font-size:17px;}body{font-size:16px;}}\n<\/style>\n<section class=\"hero\">\n  <span class=\"eyebrow\">Next.js \uad50\uc7ac \u00b7 26\ud3b8 \u00b7 \uc644\uacb0<\/span>\n  <h1>\uc2e4\uc804 \ubbf8\ub2c8 \ud504\ub85c\uc81d\ud2b8 \u2014 \ube14\ub85c\uadf8 \uc0ac\uc774\ud2b8 \uc644\uacb0<\/h1>\n  <p>25\ud3b8\uc758 \ubaa8\ub4e0 \uac1c\ub150\uc774 \ud55c \ud504\ub85c\uc81d\ud2b8\uc5d0\uc11c \ub9cc\ub09c\ub2e4. \ub05d\uae4c\uc9c0 \ub530\ub77c\uc628 \ubaa8\ub450\uc5d0\uac8c \ubc15\uc218.<\/p>\n  <img decoding=\"async\" src=\"https:\/\/junai.ai\/blog\/wp-content\/uploads\/2026\/05\/hero-5-96.jpg\" alt=\"\ube14\ub85c\uadf8 \uc0ac\uc774\ud2b8 \uc644\uc131 \ucee8\uc149 \uc77c\ub7ec\uc2a4\ud2b8\">\n<\/section>\n\n<div class=\"container\">\n<article>\n\n<p>25\ud3b8\uc744 \ucc28\ub840\ub85c \ubcf8 \uc0ac\ub78c\uc758 \ub2e4\uc74c \uc9c8\ubb38 \u2014 &#8220;\uc774\uac78 \ub2e4 \uc5b4\ub5bb\uac8c \ud55c \ud504\ub85c\uc81d\ud2b8\uc5d0 \ubb36\uc9c0?&#8221;. \ub9c8\uc9c0\ub9c9 \ucc55\ud130\ub294 \uadf8 \ub2f5. <strong>\uc778\uc99d \uc788\ub294 \ube14\ub85c\uadf8<\/strong>\ub97c \ucc98\uc74c\ubd80\ud130 \ub05d\uae4c\uc9c0 \ub9cc\ub4e4\uba74\uc11c \uc2dc\ub9ac\uc988 \ubaa8\ub4e0 \uac1c\ub150\uc744 \ud55c \ubc88 \ub354 \uc9da\ub294\ub2e4.<\/p>\n\n<p>\uc644\uc131 \ud6c4 \uacb0\uacfc\ub294 \u2014 \ub204\uad6c\ub098 \uac00\uc785\u00b7\ub85c\uadf8\uc778\ud560 \uc218 \uc788\uace0, \uae00\uc744 \uc4f0\uace0 \uc218\uc815\/\uc0ad\uc81c\ud560 \uc218 \uc788\uace0, SEO \uac00 \uc7a1\ud600 \uac80\uc0c9\uc5d0 \ub178\ucd9c\ub418\uba70, Vercel \uc5d0 \ubc30\ud3ec\ub41c \uc9c4\uc9dc \uc0ac\uc774\ud2b8. \ud68c\uc0ac \uba74\uc811 \ud3ec\ud2b8\ud3f4\ub9ac\uc624\uc5d0 \uadf8\ub300\ub85c \ub4e4\uc5b4\uac08 \uc218\uc900.<\/p>\n\n<h2>1. \uae30\ub2a5\uacfc \uae30\uc220 \uc2a4\ud0dd<\/h2>\n\n<p>\uc2a4\ud399\uc744 \uba3c\uc800 \uc815\ud55c\ub2e4.<\/p>\n\n<div class=\"tablewrap\">\n<table>\n<thead><tr><th>\uae30\ub2a5<\/th><th>\uae30\uc220<\/th><th>\ucc38\uc870 \ucc55\ud130<\/th><\/tr><\/thead>\n<tbody>\n<tr><td>\ud68c\uc6d0\uac00\uc785\u00b7\ub85c\uadf8\uc778<\/td><td data-label=\"\uae30\uc220\">Auth.js v5 (Google OAuth)<\/td><td data-label=\"\ucc38\uc870\">19<\/td><\/tr>\n<tr><td>\uae00 \ubaa9\ub85d\u00b7\uc0c1\uc138<\/td><td data-label=\"\uae30\uc220\">App Router\u00b7dynamic [slug]<\/td><td data-label=\"\ucc38\uc870\">3\u00b75<\/td><\/tr>\n<tr><td>\uae00 \uc4f0\uae30\u00b7\uc218\uc815\u00b7\uc0ad\uc81c<\/td><td data-label=\"\uae30\uc220\">Server Actions + Zod<\/td><td data-label=\"\ucc38\uc870\">9\u00b710<\/td><\/tr>\n<tr><td>DB<\/td><td data-label=\"\uae30\uc220\">PostgreSQL + Drizzle ORM<\/td><td data-label=\"\ucc38\uc870\">18 (Node)<\/td><\/tr>\n<tr><td>\uc774\ubbf8\uc9c0<\/td><td data-label=\"\uae30\uc220\">next\/image + Vercel Blob<\/td><td data-label=\"\ucc38\uc870\">15<\/td><\/tr>\n<tr><td>SEO<\/td><td data-label=\"\uae30\uc220\">generateMetadata + sitemap<\/td><td data-label=\"\ucc38\uc870\">7\u00b721<\/td><\/tr>\n<tr><td>\uc778\uc99d \uac00\ub4dc<\/td><td data-label=\"\uae30\uc220\">middleware<\/td><td data-label=\"\ucc38\uc870\">13<\/td><\/tr>\n<tr><td>\ubc30\ud3ec<\/td><td data-label=\"\uae30\uc220\">Vercel + Neon Postgres<\/td><td data-label=\"\ucc38\uc870\">20<\/td><\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n\n<h2>2. \ub514\ub809\ud1a0\ub9ac \uad6c\uc870<\/h2>\n\n<div class=\"code-block\">my-blog\/\n\u251c\u2500\u2500 app\/\n\u2502   \u251c\u2500\u2500 (marketing)\/\n\u2502   \u2502   \u251c\u2500\u2500 layout.tsx          \u2190 \ub9c8\ucf00\ud305 \ud398\uc774\uc9c0 layout\n\u2502   \u2502   \u251c\u2500\u2500 page.tsx            \u2190 \ud648 (\ub79c\ub529)\n\u2502   \u2502   \u2514\u2500\u2500 about\/page.tsx\n\u2502   \u251c\u2500\u2500 (app)\/\n\u2502   \u2502   \u251c\u2500\u2500 layout.tsx          \u2190 \uc571 \ud398\uc774\uc9c0 layout (\ud5e4\ub354\uc5d0 \uc0ac\uc6a9\uc790\uba85)\n\u2502   \u2502   \u251c\u2500\u2500 posts\/\n\u2502   \u2502   \u2502   \u251c\u2500\u2500 page.tsx        \u2190 \uae00 \ubaa9\ub85d\n\u2502   \u2502   \u2502   \u251c\u2500\u2500 [slug]\/page.tsx \u2190 \uae00 \uc0c1\uc138\n\u2502   \u2502   \u2502   \u2514\u2500\u2500 new\/page.tsx    \u2190 \uae00 \uc4f0\uae30\n\u2502   \u2502   \u2514\u2500\u2500 dashboard\/page.tsx  \u2190 \ub0b4 \uae00 \uad00\ub9ac\n\u2502   \u251c\u2500\u2500 api\/\n\u2502   \u2502   \u2514\u2500\u2500 auth\/[&#8230;nextauth]\/route.ts\n\u2502   \u251c\u2500\u2500 layout.tsx              \u2190 \ub8e8\ud2b8 layout (Inter + Noto KR)\n\u2502   \u251c\u2500\u2500 sitemap.ts\n\u2502   \u251c\u2500\u2500 robots.ts\n\u2502   \u2514\u2500\u2500 globals.css\n\u251c\u2500\u2500 lib\/\n\u2502   \u251c\u2500\u2500 auth.ts                 \u2190 Auth.js \uc124\uc815\n\u2502   \u251c\u2500\u2500 db\/\n\u2502   \u2502   \u251c\u2500\u2500 index.ts            \u2190 Drizzle \ud074\ub77c\uc774\uc5b8\ud2b8\n\u2502   \u2502   \u2514\u2500\u2500 schema.ts           \u2190 users\u00b7posts \ud14c\uc774\ube14\n\u2502   \u251c\u2500\u2500 actions.ts              \u2190 Server Actions\n\u2502   \u2514\u2500\u2500 env.ts                  \u2190 Zod \ud658\uacbd\ubcc0\uc218 \uac80\uc99d\n\u251c\u2500\u2500 components\/\n\u2502   \u251c\u2500\u2500 PostCard.tsx\n\u2502   \u251c\u2500\u2500 PostForm.tsx            \u2190 &#8216;use client&#8217;\n\u2502   \u2514\u2500\u2500 &#8230;\n\u251c\u2500\u2500 middleware.ts               \u2190 \/dashboard \uc778\uc99d \uac00\ub4dc\n\u2514\u2500\u2500 .env.local                  \u2190 \ube44\ubc00 (.gitignore)<\/div>\n\n<p>3\u00b74\ud3b8 \ud3f4\ub354 \uad6c\uc870 + 4\ud3b8 \ub77c\uc6b0\ud2b8 \uadf8\ub8f9 <code>(marketing)<\/code>\u00b7<code>(app)<\/code> \uc73c\ub85c layout \ubd84\ub9ac. \ub9c8\ucf00\ud305 \ud398\uc774\uc9c0\ub294 \ud070 hero, \uc571 \ud398\uc774\uc9c0\ub294 \uae54\ub054\ud55c \ud5e4\ub354.<\/p>\n\n<h2>3. \ud575\uc2ec \ud30c\uc77c 4\uac1c \ubbf8\ub9ac\ubcf4\uae30<\/h2>\n\n<h3>app\/posts\/[slug]\/page.tsx \u2014 \uae00 \uc0c1\uc138<\/h3>\n\n<div class=\"code-block\">import { notFound } from &#8216;next\/navigation&#8217;;\nimport { db } from &#8216;@\/lib\/db&#8217;;\nimport type { Metadata } from &#8216;next&#8217;;\n\nexport async function generateMetadata({ params }): Promise&lt;Metadata&gt; {\n  const { slug } = await params;\n  const post = await db.posts.findBySlug(slug);\n  if (!post) return {};\n  return {\n    title: post.title,\n    description: post.excerpt,\n    openGraph: { images: [post.coverImage] },\n  };\n}\n\nexport default async function PostPage({ params }) {\n  const { slug } = await params;\n  const post = await db.posts.findBySlug(slug);\n  if (!post) notFound();\n\n  return (\n    &lt;article&gt;\n      &lt;h1&gt;{post.title}&lt;\/h1&gt;\n      &lt;p className=&#8221;meta&#8221;&gt;{post.author.name} \u00b7 {post.publishedAt}&lt;\/p&gt;\n      &lt;div dangerouslySetInnerHTML={{ __html: post.bodyHtml }} \/&gt;\n    &lt;\/article&gt;\n  );\n}<\/div>\n\n<p>5\ud3b8 \ub3d9\uc801 \ub77c\uc6b0\ud305 + 7\ud3b8 generateMetadata + 8\ud3b8 async \ub370\uc774\ud130 \ud398\uce6d.<\/p>\n\n<h3>lib\/actions.ts \u2014 \uae00 \uc4f0\uae30 \uc561\uc158<\/h3>\n\n<div class=\"code-block\">&#8216;use server&#8217;;\nimport { z } from &#8216;zod&#8217;;\nimport { auth } from &#8216;@\/lib\/auth&#8217;;\nimport { db } from &#8216;@\/lib\/db&#8217;;\nimport { revalidatePath } from &#8216;next\/cache&#8217;;\nimport { redirect } from &#8216;next\/navigation&#8217;;\n\nconst PostSchema = z.object({\n  title: z.string().min(2),\n  body: z.string().min(10),\n});\n\nexport async function createPost(_prev, formData: FormData) {\n  const session = await auth();\n  if (!session) return { error: &#8216;\ub85c\uadf8\uc778 \ud544\uc694&#8217; };\n\n  const parsed = PostSchema.safeParse(Object.fromEntries(formData));\n  if (!parsed.success) return { errors: parsed.error.flatten().fieldErrors };\n\n  const post = await db.posts.create({\n    &#8230;parsed.data,\n    authorId: session.user.id,\n    slug: slugify(parsed.data.title),\n  });\n  revalidatePath(&#8216;\/posts&#8217;);\n  redirect(`\/posts\/${post.slug}`);\n}<\/div>\n\n<p>9\ud3b8 Server Action + 10\ud3b8 useActionState \ud328\ud134 + 19\ud3b8 \uc778\uc99d + 17\ud3b8 \uce90\uc2dc \ubb34\ud6a8\ud654.<\/p>\n\n<h3>middleware.ts \u2014 \uac00\ub4dc<\/h3>\n\n<div class=\"code-block\">import { auth } from &#8216;@\/lib\/auth&#8217;;\n\nexport default auth((req) =&gt; {\n  const isProtected = req.nextUrl.pathname.startsWith(&#8216;\/dashboard&#8217;) ||\n                      req.nextUrl.pathname.startsWith(&#8216;\/posts\/new&#8217;);\n  if (isProtected &#038;&#038; !req.auth) {\n    const url = req.nextUrl.clone();\n    url.pathname = &#8216;\/login&#8217;;\n    return Response.redirect(url);\n  }\n});\n\nexport const config = {\n  matcher: [&#8216;\/dashboard\/:path*&#8217;, &#8216;\/posts\/new&#8217;],\n};<\/div>\n\n<p>13\ud3b8 \ubbf8\ub4e4\uc6e8\uc5b4 + 19\ud3b8 Auth.js.<\/p>\n\n<h3>app\/sitemap.ts<\/h3>\n\n<div class=\"code-block\">import type { MetadataRoute } from &#8216;next&#8217;;\nimport { db } from &#8216;@\/lib\/db&#8217;;\n\nexport default async function sitemap(): Promise&lt;MetadataRoute.Sitemap&gt; {\n  const posts = await db.posts.findAll();\n  return [\n    { url: &#8216;https:\/\/my-blog.com&#8217;, priority: 1.0 },\n    { url: &#8216;https:\/\/my-blog.com\/posts&#8217;, priority: 0.8 },\n    &#8230;posts.map(p =&gt; ({\n      url: `https:\/\/my-blog.com\/posts\/${p.slug}`,\n      lastModified: p.updatedAt,\n    })),\n  ];\n}<\/div>\n\n<p>21\ud3b8 SEO \uc758 \uc790\ub3d9 sitemap.<\/p>\n\n<h2>4. \ubc30\ud3ec \u2014 Vercel + Neon<\/h2>\n\n<p>20\ud3b8\uc758 \ud750\ub984 \uadf8\ub300\ub85c.<\/p>\n\n<ol>\n<li><strong>GitHub push<\/strong> \u2192 <strong>vercel.com Import<\/strong>.<\/li>\n<li><strong>Neon<\/strong>(<code>neon.tech<\/code>) \uc5d0\uc11c \ubb34\ub8cc Postgres \uc778\uc2a4\ud134\uc2a4 \uc0dd\uc131 \u2192 \uc5f0\uacb0 \ubb38\uc790\uc5f4 \ubcf5\uc0ac.<\/li>\n<li>Vercel \u00b7 Settings \u00b7 Environment Variables \uc5d0 <code>DATABASE_URL<\/code>\u00b7<code>AUTH_SECRET<\/code>\u00b7<code>AUTH_GOOGLE_ID<\/code>\u00b7<code>AUTH_GOOGLE_SECRET<\/code> \uc785\ub825.<\/li>\n<li>Redeploy \u2192 <code>https:\/\/my-blog.vercel.app<\/code> \ub77c\uc774\ube0c.<\/li>\n<li><strong>\ub3c4\uba54\uc778 \uc5f0\uacb0<\/strong> \u2192 \ubb34\ub8cc SSL \uc790\ub3d9.<\/li>\n<li><strong>Search Console<\/strong> \uc5d0 sitemap.xml \ub4f1\ub85d.<\/li>\n<\/ol>\n\n<p>\ud55c \uc2dc\uac04 \uc548\uc5d0 \uc9c4\uc9dc \uc6b4\uc601\ub418\ub294 \ube14\ub85c\uadf8. \uce74\ud398\uc5d0\uc11c \uc790\ub791\ud560 \ub9cc\ud558\ub2e4.<\/p>\n\n<h2>5. \ud559\uc2b5 \uc5ec\uc815 \u2014 \ub2e4\uc74c \ub2e8\uacc4<\/h2>\n\n<p>26\ud3b8\uc744 \ub05d\ub0b8 \uc2dc\uc810\uc5d0\uc11c \ucd94\ucc9c \ub2e4\uc74c \uc9c4\ub85c 4\uac00\uc9c0.<\/p>\n\n<ul>\n<li><strong>React 25\ud3b8<\/strong>(\uac19\uc740 \uc2dc\ub9ac\uc988 React) \u2014 \uc548 \ubd24\ub2e4\uba74 \uac70\uafb8\ub85c \ubcf4\uae30. \ucef4\ud3ec\ub10c\ud2b8 \ubcf8\uccb4\ub97c \ub354 \uae4a\uac8c.<\/li>\n<li><strong>Node.js 26\ud3b8<\/strong>(\uac19\uc740 \uc2dc\ub9ac\uc988 Node) \u2014 \ubc31\uc5d4\ub4dc\ub97c \ubcf8\uaca9\uc801\uc73c\ub85c. JWT\u00b7DB\u00b7Express \ub2e4 \ubcc4\ub3c4 \ucc55\ud130.<\/li>\n<li><strong>TypeScript \uc2ec\ud654\u00b7React Native<\/strong> \u2014 \ubaa8\ubc14\uc77c\uae4c\uc9c0 \ud55c \uc5b8\uc5b4\ub85c.<\/li>\n<li><strong>\uc2e4\uc81c \uc11c\ube44\uc2a4 \uc6b4\uc601<\/strong> \u2014 \ubd80\uc871\ud55c \uac8c \uac00\uc7a5 \ube68\ub9ac \ubcf4\uc774\ub294 \uacf3. \uc0ac\uc774\ub4dc \ud504\ub85c\uc81d\ud2b8 \ud558\ub098 \ubc1c\ud589.<\/li>\n<\/ul>\n\n<div class=\"databox\">\n<strong>26\ud3b8\uc744 \ub05d\ub0b8 \ub2f9\uc2e0<\/strong> \u2014 React \uc758 \ucef4\ud3ec\ub10c\ud2b8 \ubaa8\ub378, Next.js \uc758 \ud480\uc2a4\ud0dd \ud750\ub984, App Router \uc758 \ubaa8\ub4e0 \ud2b9\uc218 \ud30c\uc77c, \ub370\uc774\ud130 \ud398\uce6d 4\uce35 \uce90\uc2dc, Server Actions\u00b7Auth.js\u00b7\ubbf8\ub4e4\uc6e8\uc5b4\u00b7SEO\u00b7\ubc30\ud3ec\uae4c\uc9c0 \u2014 \ud68c\uc0ac \uc2e0\uc785~\uc8fc\ub2c8\uc5b4 \ubc31\uc5d4\ub4dc\/\ud480\uc2a4\ud0dd\uc758 \ud45c\uc900 \uc5ed\ub7c9\uc744 \ub2e4 \uac16\ucdc4\ub2e4. \uba74\uc811\uc5d0\uc11c \ub2f5 \ubabb \ud560 \uc9c8\ubb38\uc774 \uac70\uc758 \uc5c6\ub2e4. \ub2e4\uc74c\uc740 <strong>\uc2e4\uc81c \uc0ac\uc6a9\uc790\uac00 \uc4f0\ub294 \uc11c\ube44\uc2a4<\/strong>\ub97c \ub9cc\ub4e4\uba74\uc11c \ubd80\uc871\ud568\uc744 \ubc30\uc6cc\uac00\ub294 \ub2e8\uacc4.\n<\/div>\n\n<h3>\ub9c8\uce58\uba70<\/h3>\n\n<p>26\ud3b8\uc744 \ub2e4 \ub530\ub77c\uc628 \ubaa8\ub450\uc5d0\uac8c \uc9c4\uc2ec\uc73c\ub85c \ubc15\uc218. \ud55c \ub2ec\uac04 \ub9e4\uc77c \ud55c \ucc55\ud130\uc529 \ubd24\ub2e4\uba74 \u2014 \uadf8 \uc790\uccb4\uac00 \ud754\uce58 \uc54a\uc740 \ub048\uae30\ub2e4. \uc774 \uc2dc\ub9ac\uc988\uac00 \ub204\uad70\uac00\uc758 \uccab \ud480\uc2a4\ud0dd \ud504\ub85c\uc81d\ud2b8\uc758 \uc2dc\uc791\uc810\uc774\uc5c8\uc73c\uba74 \uc88b\uaca0\ub2e4. <strong>\ucf54\ub4dc\ub294 \ub9cc\ub4e4\uc5b4\ubcf4\uba74 \ub298\uace0, \ub9cc\ub4e4\uc9c0 \uc54a\uc73c\uba74 \uc78a\ud78c\ub2e4<\/strong>. \uc624\ub298 <code>create-next-app my-first-real-site<\/code> \ubd80\ud130.<\/p>\n\n<div class=\"cta\">\n<h3>Next.js \uc2dc\ub9ac\uc988 26\ud3b8 \uc644\uacb0 \ud83c\udf89<\/h3>\n<p>\ub2e4\uc74c \uc2dc\ub9ac\uc988\ub294 \u2014 Node.js 26\ud3b8(\ubc31\uc5d4\ub4dc \ubcf8\uaca9). \ud568\uaed8 \ubcf4\uba74 \ud480\uc2a4\ud0dd \ud55c \ubb36\uc74c.<\/p>\n<\/div>\n\n<div class=\"footer-nav\">\n\uc2dc\ub9ac\uc988 \u00b7 <a href=\"https:\/\/junai.ai\/blog\/category\/nextjs\/\">\uc27d\uac8c \ubc30\uc6b0\ub294 Next.js (\uc644\uacb0)<\/a> \u00b7 \uc774\uc804: <a href=\"https:\/\/junai.ai\/blog\/nextjs-performance-25\/\">Ch.25 \uc131\ub2a5<\/a>\n<\/div>\n\n<\/article>\n<\/div>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Next.js \uc2dc\ub9ac\uc988 \ub9c8\uc9c0\ub9c9 \u2014 \ube14\ub85c\uadf8 \uc0ac\uc774\ud2b8 \ucc98\uc74c\ubd80\ud130 \ub05d\uae4c\uc9c0. 25\ud3b8 \uac1c\ub150\uc744 \ud55c \ud504\ub85c\uc81d\ud2b8\ub85c \uc5f0\uacb0, \ubc30\ud3ec\uae4c\uc9c0. \uad50\uc7ac 26\ud3b8(\uc644\uacb0).<\/p>\n","protected":false},"author":1,"featured_media":865,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[23],"tags":[],"class_list":["post-919","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-nextjs"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/junai.ai\/blog\/wp-json\/wp\/v2\/posts\/919","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/junai.ai\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/junai.ai\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/junai.ai\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/junai.ai\/blog\/wp-json\/wp\/v2\/comments?post=919"}],"version-history":[{"count":0,"href":"https:\/\/junai.ai\/blog\/wp-json\/wp\/v2\/posts\/919\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/junai.ai\/blog\/wp-json\/wp\/v2\/media\/865"}],"wp:attachment":[{"href":"https:\/\/junai.ai\/blog\/wp-json\/wp\/v2\/media?parent=919"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/junai.ai\/blog\/wp-json\/wp\/v2\/categories?post=919"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/junai.ai\/blog\/wp-json\/wp\/v2\/tags?post=919"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}