파일 시스템 라우팅 규칙. layout에 html/head/body 금지. app/ 폴더, page.tsx, route.ts, layout.tsx, [id] 작업 시 자동 호출.
Scanned 9/9/2026
Install to Claude Code
npx -y skills add konamgil/mandu --skill mandu-fs-routes --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Mandu Fs Routes?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/konamgil-mandu-fs-routes-mandu)More formats (shields.io, HTML) on the badges page.
---
name: mandu-fs-routes
description: |
파일 시스템 라우팅 규칙. layout에 html/head/body 금지.
app/ 폴더, page.tsx, route.ts, layout.tsx, [id] 작업 시 자동 호출.
---
# Mandu FS Routes
파일 시스템 기반 라우팅. `app/` 폴더의 파일 구조가 URL이 됩니다.
## File Naming Conventions
| File | Purpose | Export |
|------|---------|--------|
| `page.tsx` | Page component | `default` function component |
| `route.ts` | API handler | `default` Mandu.filling() chain |
| `layout.tsx` | Shared layout | `default` function with `children` prop |
| `loading.tsx` | Loading UI | `default` function component |
| `error.tsx` | Error UI | `default` function component |
## URL Mapping
| File Path | URL |
|-----------|-----|
| `app/page.tsx` | `/` |
| `app/about/page.tsx` | `/about` |
| `app/blog/[slug]/page.tsx` | `/blog/:slug` |
| `app/users/[id]/page.tsx` | `/users/:id` |
| `app/docs/[...path]/page.tsx` | `/docs/*` (catch-all) |
| `app/(auth)/login/page.tsx` | `/login` (grouped) |
| `app/api/users/route.ts` | `/api/users` |
| `app/api/users/[id]/route.ts` | `/api/users/:id` |
## Layout Rules (CRITICAL)
Layout MUST NOT include `<html>`, `<head>`, or `<body>` tags.
Mandu SSR generates these automatically.
```tsx
// app/layout.tsx - CORRECT
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<div className="min-h-screen bg-background font-sans antialiased">
{children}
</div>
);
}
```
```tsx
// app/layout.tsx - WRONG (causes double-wrapping)
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html> // <-- DO NOT include
<head /> // <-- DO NOT include
<body> // <-- DO NOT include
{children}
</body>
</html>
);
}
```
Nested layouts wrap child pages:
```
app/layout.tsx -> wraps ALL pages
app/dashboard/layout.tsx -> wraps /dashboard/* pages
```
## Page Components
```tsx
// app/dashboard/page.tsx
export default function DashboardPage() {
return (
<main>
<h1>Dashboard</h1>
</main>
);
}
```
Pages are server-rendered by default. No `"use client"` needed unless using Islands.
## API Routes
```typescript
// app/api/users/route.ts
import { Mandu } from "@mandujs/core";
export default Mandu.filling()
.get((ctx) => ctx.ok({ users: [] }))
.post(async (ctx) => {
const body = await ctx.body<{ name: string }>();
return ctx.created({ user: body });
});
```
API routes use `.ts` extension (NOT `.tsx`).
## Dynamic Routes
```tsx
// app/users/[id]/page.tsx
export default function UserPage({ params }: { params: { id: string } }) {
return <h1>User {params.id}</h1>;
}
// app/docs/[...path]/page.tsx
export default function DocsPage({ params }: { params: { path: string[] } }) {
return <h1>Doc: {params.path.join("/")}</h1>;
}
```
## Route Groups
Parenthesized folders create logical groups without affecting the URL:
```
app/(marketing)/about/page.tsx -> /about
app/(marketing)/pricing/page.tsx -> /pricing
app/(app)/dashboard/page.tsx -> /dashboard
```
## Common Mistakes
- Adding `<html>/<head>/<body>` in layout.tsx (SSR does this)
- Using `route.tsx` instead of `route.ts` for API handlers
- Forgetting to export default from page/layout files
- Mixing page.tsx and route.ts in the same directory
## See also
- `mandu-mcp-create-flow` — 라우트 추가 시 `mandu_add_route` + contract + generate 순서
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!