사람함께에이전트▾
사람 — 직접 정하고 책임지는 비즈니스 규칙과 흐름. 직접 읽어보세요.
함께 — 개념은 알아두고, 세부 규칙은 에이전트가 따릅니다.
에이전트 — 에이전트가 따르는 규칙과 레퍼런스. 필요할 때 찾아보세요.
소개▾
튜토리얼▾
핵심 개념▾
시스템 아키텍처▾

파일 기반 라우팅

Akan은 파일 기반 라우팅을 사용합니다. page/ 아래에 파일을 만들면 폴더 구조가 페이지 URL이 됩니다. 모든 라우트는 Akan이 자동으로 주입하는 locale 세그먼트 아래에 놓이므로, 하나의 파일이 제공하는 모든 언어를 처리합니다.
폴더에서 URL까지
page/(user)/project/[projectId]/_index.tsx
(user)는 세그먼트를 더하지 않습니다
Akan이 locale을 주입합니다
/:lang/project/:projectId
파일 기반: 폴더와 파일이 URL 형태를 결정합니다.
다국어 지원: Akan이 locale 세그먼트를 자동으로 주입하고 모든 라우트에 lang으로 전달합니다.
명시적인 파일: 숨겨진 규칙보다 page와 layout 파일을 명시적으로 사용합니다.

파일 컨벤션

라우트 파일은 page, layout, overrides 매니페스트 중 하나입니다. page/ 아래에는 .tsx 라우트 모듈만 둘 수 있습니다. helper 파일도, 로직 파일도, 대문자로 시작하는 파일명도 허용되지 않습니다.
page/
folder/_index.tsx
자기가 놓인 폴더의 페이지입니다. project/_index.tsx는 /:lang/project를 제공합니다.
folder/_layout.tsx
자기 폴더 아래의 모든 페이지를 감쌉니다. root _layout.tsx는 rootLayout() 체인입니다.
folder/_overrides.tsx
하위 트리의 UI override를 적는 로직 없는 매니페스트입니다. export default override({ … }) 하나만 둡니다.
path.tsx
세그먼트를 파일 하나로 선언합니다. project.tsx는 /:lang/project를 제공하며, 대문자로 시작할 수 없습니다.
[param].tsx
동적 세그먼트를 파일 하나로 선언합니다. [projectId].tsx는 /:lang/:projectId를 제공합니다.
(group)/
URL 세그먼트를 더하지 않고 파일을 정리합니다. (user), (public) 같은 이름을 씁니다.
[lang]/
직접 쓰지 않습니다. Akan이 locale을 주입합니다.

페이지 파일 구성

페이지 파일은 page() 체인 하나만 export합니다. 라우트 설정은 각각 체인의 한 단계입니다. .param()과 .search()는 페이지가 읽는 값을 선언하고, .config()는 라우트 동작을 정하며, .head()와 .loading()은 head 태그와 로딩 화면을 설정하고, .render()가 컴포넌트를 반환합니다. render 콜백은 선언한 값을 이미 타입이 붙은 평탄한 형태로 받습니다.
page/(user)/project/[projectId]/_index.tsx
Static head example

체인 단계

단계는 모두 열다섯 개이고, 세 체인이 그 대부분을 공유합니다. page()는 .prompt()를, layout()은 .notFound()와 .error()를 더하며, rootLayout()은 앱 공통 단계까지 가진 layout입니다. 세 열은 각 단계를 어느 체인에서 쓸 수 있는지 표시합니다.
단계
page()
단계 7개
layout()
단계 8개
rootLayout()
단계 14개
모든 체인
.param(name, Type)
✓
✓
✓
경로의 [x] 세그먼트 하나를 타입과 함께 선언합니다. 타입이 거부하는 값은 not-found로 응답합니다.
.search(key, Type)
✓
✓
✓
선택 사항인 쿼리 키입니다. [String]은 목록을 읽고, 타입이 거부하는 값은 버려집니다.
.config({ … })
✓
✓
✓
transition·devOnly 같은 클라이언트 frame 동작입니다. 하위 페이지는 레이아웃의 값을 상속합니다.
.head(jsx | fn)
✓
✓
✓
라우트의 <head>를 JSX(title, meta, link)로 넘기거나, 인자를 받아 그 JSX를 반환하는 함수로 넘깁니다.
.loading(fn)
✓
✓
✓
라우트가 로딩되는 동안의 대체 UI입니다. 그 안에서 .search() 값은 모두 undefined입니다.
page() 전용
.prompt(name, desc)
✓
화면을 MCP prompt로 공개합니다. .param()은 필수 인자, .search()는 선택 인자가 됩니다.
layout()·rootLayout()
.notFound(fn)
✓
✓
하위 라우트가 없을 때 레이아웃 안에 그리는 404 UI입니다. 타입 인자가 아니라 원본 route props를 받습니다.
.error(fn)
✓
✓
하위 라우트가 SSR 중 에러를 던지면 가장 가까운 레이아웃 안에 그리는 UI입니다. 원본 props에 error와 digest가 더해집니다.
rootLayout() 전용
.fonts([…])
✓
앱 전체 폰트를 등록합니다. optimize를 켜면 subset해서 /_akan/fonts에서 제공합니다.
.manifest({ … })
✓
설치형 앱·PWA 동작에 쓰는 web app manifest입니다. name, startUrl, icons 등을 담습니다.
.theme(name)
✓
문서의 기본 테마(dark, light, system)입니다. 빈 문자열도 그대로 적용됩니다.
.reconnect(on)
✓
연결 끊김 오버레이만 켜며 재연결과는 무관합니다. 선언하지 않으면 꺼져 있습니다.
.wsConnect(on)
✓
로드 후 WebSocket을 연결합니다(기본값 true). false이면 fetch.instance.connect()를 기다립니다.
.layoutStyle(style)
✓
바깥 페이지 컨테이너 스타일이며 web 또는 mobile입니다. 앱 같은 화면에는 mobile을 씁니다.
체인의 끝
.render(fn)필수
✓
✓
✓
컴포넌트이자 체인의 끝입니다. lang과 선언한 인자, 레이아웃이면 children도 받습니다.
✓이 체인에서 사용 가능이 체인에는 없음

레이아웃 파일 구성

레이아웃 파일은 하위 페이지를 감쌉니다. 공통 헤더, 탭, 사이드바, 접근 제어, 페이지 껍데기 같은 UI를 둘 때 사용합니다. 자체 .head()는 head를 선언하지 않은 하위 페이지에 쓰이고, .notFound()와 .error()는 그 아래 전체의 fallback이 됩니다.
레이아웃이 페이지를 감쌉니다
root layout이 그 아래의 모든 layout을 감싸고, 각 layout은 자기 폴더 아래의 페이지를 감싸며, 페이지는 가장 안쪽에서 렌더링됩니다.
page/(user)/project/[projectId]/_layout.tsx

Root Layout 단계

앱 또는 basePath의 root _layout.tsx는 rootLayout() 체인입니다. 기본적으로는 layout이지만 font, manifest, theme, realtime connection, mobile-style rendering 같은 앱 공통 단계를 함께 가집니다. 스타일시트 import는 파일의 첫 줄에 그대로 둡니다.
page/_layout.tsx
여기 쓰인 단계는 모두 위의 Chain Stages 표에 한 행씩 있으며, 이 파일에만 있는 것은 .fonts(), .manifest(), .theme(), .reconnect(), .wsConnect(), .layoutStyle() 여섯 개뿐입니다. 나머지 .config(), .head(), .loading(), .notFound(), .error(), .render()는 일반 layout에도 있는 단계입니다.

Google Analytics

Akan에는 analytics 단계가 없습니다. 어떤 태그를 어느 환경에서, 어떤 동의 배너 뒤에서 불러올지는 앱이 정할 일이므로, 태그는 root layout이 렌더링하는 평범한 클라이언트 컴포넌트입니다. 아래 컴포넌트는 앱 전체에서 gtag.js를 한 번 불러옵니다.
ui/Analytics.tsx
page/_layout.tsx

검색엔진

모든 페이지는 서버에서 렌더링되고, 검색엔진·AI 크롤러·링크 미리보기 같은 크롤러는 모든 섹션이 제자리에 들어간 완성된 페이지를 받습니다. 크롤러가 찾는 파일 두 개도 함께 제공됩니다.
/robots.txt
AI 크롤러를 포함한 모든 크롤러에게 공개 페이지를 열고, API와 관리자 경로는 닫습니다.
/sitemap.xml
정적 페이지를 언어마다 모두 나열합니다. [param] 세그먼트가 있는 페이지는 빠집니다.
/robots.txt

Base Path

앱이 akan.config.ts에서 base path를 정의하면 page 파일은 해당 base path 폴더 아래에 있어야 합니다. 여러 서비스나 여러 도메인을 가진 앱의 라우트를 명확하게 나누기 위한 규칙입니다.
apps/myapp/akan.config.ts
page/

라이브러리 페이지

라이브러리도 자체 page 폴더에 라우트를 담을 수 있습니다. 앱이 syncPageLibs로 사용을 선언하면, 라이브러리 라우트는 자기 경로를 그대로 사용합니다.
apps/myapp/akan.config.ts
library route mapping

개발 전용 라우트

.config({ devOnly: true })를 켜면 해당 라우트가 akan build에서 제외됩니다. akan start에서는 그대로 동작하고 타입 검사도 계속 받지만, 번들에도 라우트 매니페스트에도 들어가지 않아 프로덕션에서는 존재하지 않습니다.
page/(dev)/playground/_index.tsx

MIT 라이선스 하에 배포되었습니다.

내 AI에 이 문서 연결하기

MCPhttps://akanjs.com/mcp
Copyright © 2026 Akan.js 모든 권리 보유.시스템 관리자bassman