Folder-Based Routing

Folders inside src/app define URL segments. Each folder becomes a part of the URL path.

Overview

Bini.js uses folder-based routing - every folder inside src/app/ becomes a URL segment. Add page.tsx inside that folder to make the route accessible.

Folder names must be valid URL segments and the structure directly maps to the URL path.

Folder PatternURLType
app/about/page.tsx/aboutStatic folder - creates URL
app/blog/page.tsx/blogStatic folder - creates URL
app/dashboard/settings/page.tsx/dashboard/settingsNested folder - creates URL
app/(marketing)/about/page.tsx/aboutRoute group - folder ignored, no extra segment
app/_components/Header.tsx-Private folder _ - no URL
app/.internal/page.tsx-Private folder . - no URL

Basic Folder Routing

Every folder becomes a segment. Add page.tsx to expose it. index.tsx also maps to its parent.

app
page.tsx
about
page.tsx
blog
page.tsx
dashboard
page.tsx
settings
page.tsx
contact
page.tsx
/Routable
/aboutRoutable
/blogRoutable
/dashboardRoutable
/dashboard/settingsRoutable
/contactRoutable
app/about/page.tsx
export default function AboutPage() {
  return <h1>About</h1>
}
Every folder with a page.tsx creates a URL. This keeps layouts, loading, and error boundaries co-located per folder.

Nested Routes

Nest folders to create nested URL segments. Each nested folder adds a segment and creates a URL.

app
blog
page.tsx
authors
page.tsx
categories
page.tsx
dashboard
page.tsx
settings
page.tsx
profile
page.tsx
/blogRoutable
/blog/authorsRoutable
/blog/categoriesRoutable
/dashboardRoutable
/dashboard/settingsRoutable
/dashboard/settings/profileRoutable
app/blog/authors/page.tsx
export default function AuthorsPage() {
  return (
    <ul>
      <li>Alice</li>
      <li>Bob</li>
    </ul>
  )
}
Nested folders create nested URLs. Each level adds a segment. Layouts from parent folders wrap child routes.

Route Groups

(group) organizes folders without affecting URL. The group folder does not create a URL segment.

app
(marketing)
layout.tsx
page.tsx
about
page.tsx
pricing
page.tsx
(app)
layout.tsx
dashboard
page.tsx
layout.tsx
/Routable
/aboutRoutable
/pricingRoutable
/dashboardRoutable
app/(marketing)/layout.tsx
export default function MarketingLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <div>
      <nav>Marketing Nav</nav>
      <main>{children}</main>
    </div>
  )
}

URLs are /, /about, /pricing, /dashboard - the (marketing) and (app) folders don't create URL segments.

Route groups are folders wrapped in parentheses. They organize code without creating URLs. Perfect for applying different layouts to different sections.

Private Folders (Private Routes)

Private folders are folder-based private routes - prefix a folder with _ or . to exclude it from routing. They do not create URLs.

app
_components
Header.tsx
_lib
utils.ts
blog
page.tsx
_components
PostCard.tsx
dashboard
page.tsx
_components
Sidebar.tsx
/_components/HeaderNot Routable
/_lib/utilsNot Routable
/blogRoutable
/blog/_components/PostCardNot Routable
/dashboardRoutable
/dashboard/_components/SidebarNot Routable
Folder PatternCreates URL?Description
_componentsNoPrivate folder - _ prefix - no URL
_lib, _hooksNoPrivate folders - no URL
.hidden, .internalNoDot prefix - private - no URL
blog/_componentsNoPrivate inside route - no URL
(group)No extra segmentRoute group - folder ignored
blog, aboutYesPublic folder with page.tsx - creates URL
Private folders (_ or .) do not create URLs. Use them to keep components, utils, and hooks next to the route that uses them. Static and nested folders with page.tsx do create URLs.

Nearest Wins with Folders

loading.tsx, not-found.tsx, error.tsx use nearest-wins resolution for folder hierarchy. A file in a subfolder only affects that subfolder.

app
layout.tsx
page.tsx
loading.tsx
not-found.tsx
error.tsx
dashboard
layout.tsx
page.tsx
loading.tsx
error.tsx
settings
page.tsx
blog
page.tsx
loading.tsx
authors
page.tsx

Resolution: route's own folder → parent folders → built-in default.

app/dashboard/loading.tsx
export default function DashboardLoading() {
  return <p>Loading dashboard…</p>
}

Route Priority

In folder-based routing, static folders define exact routes and create URLs. Shorter paths are matched first.

  1. Static folders - exact matches like about/page.tsx → /about - creates URL
  2. Nested folders - blog/authors/page.tsx → /blog/authors - creates URL
  3. Route groups - (marketing)/about/page.tsx → /about - no extra segment
  4. Private folders - _components, .internal - no URL
app
about
page.tsx
blog
page.tsx
authors
page.tsx
(marketing)
pricing
page.tsx
_components
Header.tsx
/aboutRoutable
/blogRoutable
/blog/authorsRoutable
/pricingRoutable
/_components/HeaderNot Routable
Static and nested folders create URLs. Route groups and private folders do not create URLs or extra segments.

Complete Example

Complete folder-based routing example showing which folders create URLs and which don't.

app
(marketing)
layout.tsx
page.tsx
about
page.tsx
_components
Hero.tsx
_components
Button.tsx
blog
layout.tsx
page.tsx
loading.tsx
authors
page.tsx
dashboard
layout.tsx
page.tsx
settings
page.tsx
profile
page.tsx
layout.tsx
page.tsx
loading.tsx
error.tsx
not-found.tsx
/Routable
/aboutRoutable
/_components/HeroNot Routable
/_components/ButtonNot Routable
/blogRoutable
/blog/authorsRoutable
/dashboardRoutable
/dashboard/settingsRoutable
/dashboard/settings/profileRoutable
/Routable
Folder PathURLCreates URL?
app/page.tsx/Yes - creates URL
app/about/page.tsx/aboutYes - static folder creates URL
app/blog/page.tsx/blogYes - static folder creates URL
app/blog/authors/page.tsx/blog/authorsYes - nested folder creates URL
app/dashboard/settings/profile/page.tsx/dashboard/settings/profileYes - deeply nested creates URL
app/(marketing)/about/page.tsx/aboutYes, but group folder ignored
app/_components/Header.tsx-No - private folder, no URL
app/.internal/config.ts-No - private folder, no URL
app/blog/_components/PostCard.tsx-No - private inside route, no URL
Static folders and nested folders with page.tsx create URLs. Private folders (_ / .) and route groups (group) do not create extra URL segments. Private folders are for organizing code without creating URLs.
Was this helpful?