๐ Next.js Pages Router์์ App Router๋ก ๋ง์ด๊ทธ๋ ์ด์ ๊ฐ์ด๋
๐ Next.js Pages Router์์ App Router๋ก ๋ง์ด๊ทธ๋ ์ด์ ๊ฐ์ด๋
Next.js 13๋ถํฐ ๋์ ๋ App Router๋ ๊ธฐ์กด Pages Router๋ณด๋ค ๋ ๋ชจ๋ํ๋๊ณ ์ ์ฐํ ๊ตฌ์กฐ๋ฅผ ์ ๊ณตํฉ๋๋ค. ์ด ๊ฐ์ด๋๋ ๊ธฐ์กด ํ๋ก์ ํธ๋ฅผ App Router๋ก ์ ์ง์ ์ผ๋ก ์ด์ ํ๋ ๋ฐฉ๋ฒ์ ๋จ๊ณ๋ณ๋ก ์ค๋ช ํฉ๋๋ค.
โ 1๋จ๊ณ: app ๋๋ ํ ๋ฆฌ ์์ฑ
App Router๋ app/ ๋๋ ํ ๋ฆฌ๋ฅผ ์ค์ฌ์ผ๋ก ์๋ํฉ๋๋ค.
mkdir app
๋๋ src/ ๋๋ ํ ๋ฆฌ ๋ด์ ์์ฑ:
mkdir src/app
โ 2๋จ๊ณ: ๋ฃจํธ ๋ ์ด์์ ์์ฑ
๋ชจ๋ ํ์ด์ง์ ๊ณตํต์ผ๋ก ์ ์ฉ๋๋ app/layout.tsx๋ฅผ ์์ฑํฉ๋๋ค.
// app/layout.tsx
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="ko">
<body>{children}</body>
</html>
);
}
_app.tsx, _document.tsx๋ ์ด์ ์ฌ์ฉํ์ง ์์ต๋๋ค.
โ 3๋จ๊ณ: ํ์ด์ง ์ด์
๊ธฐ์กด pages ๋๋ ํ ๋ฆฌ์ ํ์ผ์ app ๋๋ ํ ๋ฆฌ๋ก ์ฎ๊น๋๋ค.
์ด์ ์์น ์๋ก์ด ์์น
pages/index.tsx | app/page.tsx |
pages/about.tsx | app/about/page.tsx |
ํด๋ ๊ตฌ์กฐ๊ฐ ๊ณง URL์ด ๋๋ฉฐ, ๊ฐ ๊ฒฝ๋ก์๋ page.tsx๊ฐ ํ์ํฉ๋๋ค.
โ 4๋จ๊ณ: ๋ฉํ๋ฐ์ดํฐ ์ค์
App Router์์๋ next/head ๋์ metadata ๊ฐ์ฒด๋ฅผ ์ฌ์ฉํฉ๋๋ค.
// app/page.tsx
export const metadata = {
title: 'ํํ์ด์ง',
description: 'Next.js App Router ์์ ',
};
export default function Page() {
return <h1>ํ์ํฉ๋๋ค!</h1>;
}
โ 5๋จ๊ณ: ๋ฐ์ดํฐ ํ์นญ ๋ณ๊ฒฝ
getStaticProps, getServerSideProps ๋์ **์๋ฒ ์ปดํฌ๋ํธ ๋ด fetch**๋ฅผ ์ง์ ์ฌ์ฉํฉ๋๋ค.
async function getPosts() {
const res = await fetch('https://api.example.com/posts');
return res.json();
}
export default async function PostsPage() {
const posts = await getPosts();
return (
- {posts.map(post =>
- {post.title} )}
);
}
โ 6๋จ๊ณ: ๋ผ์ฐํ ํ ๋ณ๊ฒฝ
next/router์์ ๊ฐ์ ธ์ค๋ useRouter ๋์ ์๋๋ฅผ ์ฌ์ฉํฉ๋๋ค.
import { useRouter } from 'next/navigation';
โ 7๋จ๊ณ: ์ ์ง์ ์ด์ ๊ฐ๋ฅ
App Router์ Pages Router๋ ๋์์ ๊ณต์กดํ ์ ์์ผ๋ฏ๋ก, ์ ์ฒด๋ฅผ ํ ๋ฒ์ ๋ง์ด๊ทธ๋ ์ด์ ํ ํ์๋ ์์ต๋๋ค. ์ค์ํ ํ์ด์ง๋ถํฐ ์์ฐจ์ ์ผ๋ก ์ด์ ํ์ธ์.
โ 8๋จ๊ณ: ์๋ฌ ํ์ด์ง ๊ตฌ์ฑ
- app/error.tsx → ๋ฐํ์ ์๋ฌ ์ฒ๋ฆฌ
- app/not-found.tsx → 404 ์ฒ๋ฆฌ
// app/error.tsx
'use client';
export default function Error() {
return <h2>์๋ฌ๊ฐ ๋ฐ์ํ์ต๋๋ค.</h2>;
}
// app/not-found.tsx
export default function NotFound() {
return <h2>ํ์ด์ง๋ฅผ ์ฐพ์ ์ ์์ต๋๋ค.</h2>;
}
โ 9๋จ๊ณ: API ๋ผ์ฐํธ ๋ณ๊ฒฝ
App Router์์๋ pages/api ๋์ app/api ๋๋ ํ ๋ฆฌ๋ฅผ ์ฌ์ฉํฉ๋๋ค.
// app/api/hello/route.ts
export async function GET() {
return new Response('์๋
ํ์ธ์!');
}
โ 10๋จ๊ณ: ๊ธ๋ก๋ฒ ์คํ์ผ ๋ฐ ์ํ๊ด๋ฆฌ
๊ธ๋ก๋ฒ CSS๋ globals.css๋ก ์ ์งํ๊ณ layout.tsx์์ importํฉ๋๋ค.
// app/layout.tsx
import './globals.css';
์ํ ๊ด๋ฆฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ use client๋ฅผ ๋ถ์ธ Provider๋ก wrapping ํฉ๋๋ค.
// app/providers.tsx
'use client';
import { Provider } from 'react-redux';
import { store } from './store';
export function Providers({ children }: { children: React.ReactNode }) {
return <Provider store={store}>{children}</Provider>;
}
๊ทธ๋ฆฌ๊ณ layout์์ ์ฌ์ฉ:
import { Providers } from './providers';
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="ko">
<body>
<Providers>{children}</Providers>
</body>
</html>
);
}
โ ์์ฝ ๋น๊ตํ
ํญ๋ชฉ Pages Router App Router
๋๋ ํ ๋ฆฌ ๊ตฌ์กฐ | pages/ | app/ |
๊ณตํต ๋ ์ด์์ | _app.tsx / _document.tsx | layout.tsx |
๋ฐ์ดํฐ ํ์นญ | getStaticProps ๋ฑ | fetch (์๋ฒ ์ปดํฌ๋ํธ) |
๋ฉํ๋ฐ์ดํฐ | next/head | metadata ๊ฐ์ฒด |
API ๋ผ์ฐํธ | pages/api/ | app/api/ (route.ts) |
์๋ฌ ํธ๋ค๋ง | _error.tsx / 404.tsx | error.tsx / not-found.tsx |
Next.js, App Router, ๋ง์ด๊ทธ๋ ์ด์ , pages ๋๋ ํ ๋ฆฌ, layout ๊ตฌ์ฑ, ์๋ฒ ์ปดํฌ๋ํธ, metadata ์ค์ , API route, ์๋ฌ ํ์ด์ง, ์ ์ญ ์ํ ๊ด๋ฆฌ, ๊ธ๋ก๋ฒ ์คํ์ผ๋ง, ์ ์ง์ ์ด์ , Next 13+ ๊ตฌ์กฐ