Pages & Routing
NukeJS maps your file system directly to URL routes — no router config, no imports required.
File → URL mapping
Every .tsx file inside app/pages/ that exports a default component becomes a route.
| File | URL |
|---|---|
| app/pages/index.tsx | / |
| app/pages/about.tsx | /about |
| app/pages/blog/index.tsx | /blog |
| app/pages/blog/[slug].tsx | /blog/:slug |
| app/pages/docs/[...path].tsx | /docs/* (catch-all) |
| app/pages/files/[[...path]].tsx | /files or /files/* (optional catch-all) |
Basic page
Pages can be async — async code runs on the server before the HTML is sent:
app/pages/index.tsxtypescript
export default async function Home() {
const posts = await db.getPosts() // runs on server, no JS sent to browser
return (
<main>
<h1>Blog</h1>
{posts.map(p => (
<article key={p.id}>
<h2>{p.title}</h2>
<p>{p.excerpt}</p>
</article>
))}
</main>
)
}Dynamic routes
Wrap a segment in [brackets]. The segment name becomes a prop on the component:
app/pages/blog/[slug].tsxtypescript
export default async function BlogPost({ slug }: { slug: string }) {
const post = await fetchPost(slug)
if (!post) {
// handle 404 however you like
return <h1>Post not found</h1>
}
return (
<article>
<h1>{post.title}</h1>
<p>{post.content}</p>
</article>
)
}Catch-all routes
Use [...param] to match one or more path segments. The value is a string[]:
app/pages/docs/[...path].tsxtypescript
export default function Docs({ path }: { path: string[] }) {
// /docs/getting-started/installation → path = ['getting-started', 'installation']
return <DocViewer segments={path} />
}Use [[...param]] (double brackets) to also match the route with no trailing segments.
Route specificity
When multiple files could match, the most specific one wins:
/users/profile → pages/users/profile.tsx (static — wins)
/users/42 → pages/users/[id].tsx (dynamic)
/users/a/b/c → pages/users/[...rest].tsx (catch-all)layout.tsx is never a routeFiles named
layout.tsx are always treated as layout wrappers, never as routes. Visiting /blog/layout will not match app/pages/blog/layout.tsx.