Router & Route
라우트 매칭, 등록, 기본 옵션
<Router>는 루트 컨테이너예요. URL에 맞는 <Route>를 골라 렌더해요.
<Router>
<Route path="/" element={<Home />} />
<Route path="/posts/:slug" element={<Post />} />
</Router>경로 패턴
경로 매칭은 path-to-regexp v8을 그대로 써요.
"/"; // 정확 매칭
"/posts/:slug"; // 단일 파라미터
"/users/:id/posts/:p"; // 다중 파라미터
"/files/*splat"; // 와일드카드여러 경로를 한 컴포넌트에 매핑하려면 배열로 넘겨요.
<Route path={["/", "/home"]} element={<Home />} />타입 안전한 라우트
RegisterRoute를 augment 하면 navigate.push와 useParams가 모두 타입 검증돼요. 한 파일에
모아서 선언하든, 각 페이지 파일에서 자기가 쓰는 라우트만 선언하든 — TypeScript가 모든 선언을
합쳐서 보기 때문에 어느 쪽이든 동작해요. 보통 <Router>를 마운트하는 파일 하단에 같이 두면
편해요.
declare module "flemo" {
interface RegisterRoute {
"/": undefined;
"/posts/:slug": { slug: string };
"/users/:id": { id: string };
}
}파라미터가 없는 경로는 undefined, 있는 경로는 그대로 shape를 적어요.
navigate.push("/posts/:slug", { slug: "hello" }); // ✅
navigate.push("/posts/:slug", { id: "1" }); // ❌ 타입 에러
navigate.push("/unknown"); // ❌ 타입 에러Router 옵션
<Router initPath="/" defaultTransitionName="cupertino" transitions={[]} decorators={[]}>
{/* routes */}
</Router>| Prop | 기본값 | 설명 |
|---|---|---|
initPath | "/" | SSR에서 window.location이 없을 때 쓰는 경로 |
defaultTransitionName | "cupertino" | navigate.push가 전환을 지정하지 않았을 때의 기본 전환 |
transitions | [] | 등록할 커스텀 전환 |
decorators | [] | 등록할 커스텀 데코레이터 |
SSR
<Router>는 서버에서도 렌더링돼요. 다만 서버에는 window.location이 없어서 첫 렌더에 어떤
경로를 그릴지 직접 알려줘야 해요. 그게 initPath예요.
- 서버:
initPath에 해당하는 화면을 렌더해요. 지정하지 않으면"/"예요. - 클라이언트: 마운트되면
window.location.pathname을 읽어 그대로 이어받아요.
서버가 받은 요청 경로를 그대로 넘기면 hydration mismatch 없이 첫 화면이 맞아요. 예를 들어 Next.js App Router에서는:
export default async function Page({ params }: { params: Promise<{ slug?: string[] }> }) {
const { slug = [] } = await params;
const initPath = "/" + slug.join("/");
return <Router initPath={initPath}>{/* routes */}</Router>;
}서버 렌더가 필요 없는 SPA(Vite, CRA 등)라면 initPath는 신경 쓰지 않아도 돼요. 클라이언트에서
바로 window.location.pathname을 읽어요.