YouBothAgent▾
You — Business rules and flows you own. Read these yourself.
Both — Know the idea; your agent follows the details.
Agent — Conventions and references your agent follows. Look up as needed.
Introduction▾
Tutorials▾
Core Concepts▾
Architecture▾

File Based Routing

Akan uses file-based routing. You create files under page/, and the folder structure becomes the page URL. Every route also sits under a locale segment that Akan injects for you, so the same file serves every language you ship.
From folder to URL
page/(user)/project/[projectId]/_index.tsx
(user) adds no segment
Akan injects the locale
/:lang/project/:projectId
File-based: Folders and files decide the URL shape.
Locale-aware: Akan injects the locale segment automatically and hands it to every route as lang.
Explicit files: Use page and layout files instead of hidden magic.

File Convention

A route file is a page, a layout, or an overrides manifest. Everything under page/ must be a .tsx route module — no helper file, no logic file, no filename starting with an uppercase letter.
page/
folder/_index.tsx
The page for the folder it sits in: project/_index.tsx serves /:lang/project.
folder/_layout.tsx
Wraps every page below its folder. The root one is a rootLayout() chain.
folder/_overrides.tsx
A logic-free manifest of UI overrides for the subtree: one export default override({ … }).
path.tsx
A segment as one file: project.tsx serves /:lang/project. Never an uppercase first letter.
[param].tsx
A dynamic segment as one file: [projectId].tsx serves /:lang/:projectId.
(group)/
Organizes files without adding a URL segment, such as (user) or (public).
[lang]/
Never written: Akan injects the locale.

Page File Shape

A page file exports a single page() chain and nothing else. Each route setting is one stage of the chain: .param() and .search() declare the values the page reads, .config() tunes the route, .head() and .loading() set the head tags and the loading fallback, and .render() returns the component. The render callback receives the declared values flat, already typed.
page/(user)/project/[projectId]/_index.tsx
Static head example

Chain Stages

There are fifteen stages, and the three chains share most of them. page() adds .prompt(); layout() adds .notFound() and .error(); rootLayout() is a layout that also carries the app-wide stages. The three columns mark which builder each stage is legal on.
Stage
page()
7 stages
layout()
8 stages
rootLayout()
14 stages
Every chain
.param(name, Type)
✓
✓
✓
Declares one [x] path segment, typed; a value the type refuses answers not-found.
.search(key, Type)
✓
✓
✓
An optional query key; [String] reads a list, and a value the type refuses is dropped.
.config({ … })
✓
✓
✓
Client frame behaviour such as transition and devOnly; child pages inherit a layout's.
.head(jsx | fn)
✓
✓
✓
The route's <head> as JSX (title, meta, link), or a function of the args that returns it.
.loading(fn)
✓
✓
✓
Fallback UI while the route loads; every .search() value reads undefined inside it.
page() only
.prompt(name, desc)
✓
Publishes the screen as an MCP prompt: .param() args are required, .search() optional.
layout() and rootLayout()
.notFound(fn)
✓
✓
404 UI rendered inside the layout when a child route is missing; takes raw route props.
.error(fn)
✓
✓
SSR error UI under the nearest layout when a child throws; raw props, error and digest.
rootLayout() only
.fonts([…])
✓
Registers app-wide fonts; optimize subsets a font and serves it from /_akan/fonts.
.manifest({ … })
✓
The web app manifest (name, startUrl, icons…) for installable, PWA-like behaviour.
.theme(name)
✓
The document's default theme (dark, light, system); an empty string is honoured.
.reconnect(on)
✓
The connection-lost overlay only, not reconnection; off unless you set it.
.wsConnect(on)
✓
Connects the WebSocket on load (default true); false waits for fetch.instance.connect().
.layoutStyle(style)
✓
The outer page container style, web or mobile. Use mobile for app-like shells.
Ends the chain
.render(fn)required
✓
✓
✓
The component, ending the chain; gets lang, the declared args, and children on a layout.
✓Available on this chainNot on this chain

Layout File Shape

A layout file wraps child pages. Use it for shared headers, tabs, sidebars, guards, or page-level shells. Its own .head() covers child pages that declare none, and its .notFound() and .error() are the fallback for everything below it.
Layouts wrap the page
The root layout wraps every layout below it, each layout wraps the pages under its folder, and the page renders innermost.
page/(user)/project/[projectId]/_layout.tsx

Root Layout Stages

The root _layout.tsx of an app, or of a basePath, is a rootLayout() chain. It is still a layout, but it also carries the app-wide stages for fonts, manifest, theme, realtime connection, and mobile-style rendering. The stylesheet import stays the first line of the file.
page/_layout.tsx
Each of these is one row of the Chain Stages table above, and only .fonts(), .manifest(), .theme(), .reconnect(), .wsConnect() and .layoutStyle() are exclusive to this file. Everything else here — .config(), .head(), .loading(), .notFound(), .error(), .render() — is the ordinary layout surface.

Google Analytics

Akan has no analytics stage. Which tags load, in which environment and behind which consent banner are the app's decisions, so a tag is an ordinary client component that the root layout renders. The one below loads gtag.js once for the whole app.
ui/Analytics.tsx
page/_layout.tsx

Search Engines

Every page renders on the server, and a crawler — a search engine, an AI crawler or a link preview — gets it whole, with every section already in place. The two files crawlers look for are served as well.
/robots.txt
Opens public pages to every crawler, AI crawlers included, and closes the API and admin paths.
/sitemap.xml
Lists every static page once per locale; a page with a [param] segment is left out.
/robots.txt

Base Paths

When an app defines base paths in akan.config.ts, page files must live under one of those base path folders. This keeps multi-service or multi-domain apps explicit.
apps/myapp/akan.config.ts
page/

Library Pages

A library can ship routes from its own page folder. An app opts in with syncPageLibs, and a library route keeps its own path.
apps/myapp/akan.config.ts
library route mapping

Dev Only Routes

.config({ devOnly: true }) keeps a route out of akan build. It still serves under akan start and is still typechecked, but nothing about it reaches production: no bundle, no route manifest entry, no URL.
page/(dev)/playground/_index.tsx

Released under the MIT License

Connect your AI to these docs

MCPhttps://akanjs.com/mcp
Copyright © 2026 Akan.js All rights reserved.System managed bybassman