Colocation in the App Router: Which Files Become Routes

Files inside app can sit right next to the routes that use them without becoming URLs. Learn exactly which file names Next.js treats as routable.

6 min read

Next.js colocation means placing a component, hook, or utility file directly inside a route's folder in the app directory, right next to the page that uses it. This works safely because only a specific set of file names actually becomes a route.

texttext
app/
  blog/
    page.tsx
    PostCard.tsx
    format-date.ts

page.tsx is the only file here that Next.js treats as routable. PostCard.tsx and format-date.ts sit in the exact same folder but never become URLs, because their names do not match a reserved convention.

The exact names that matter

A route becomes public and routable only when a folder contains one of a short list of reserved file names, matched exactly. Everything else, no matter what it contains or how it's organized, stays a private project file.

File nameMakes the folder routable
page.tsxYes
route.tsYes
layout.tsxWraps children, but adds no page of its own
Any other nameNo

A component named page-header.tsx is safe, since it does not match page.tsx exactly. The match is on the full file name, not a substring.

Only rendered content reaches the browser

Colocating a file inside a route folder does not automatically send it to the client. Only the output a page or route file actually returns, including anything it imports and renders, reaches the browser.

App.tsxApp.tsx
// app/blog/page.tsx
import { PostCard } from "./PostCard";
 
export default function BlogPage() {
  return <PostCard title="Hello" />;
}

PostCard.tsx ships to the client here because the page imports and renders it. A colocated file the page never imports stays on disk and never reaches a visitor at all, whether or not it sits inside the route folder.

When to reach for extra structure

Plain colocation already keeps non-routing files safe, so private folders and route groups are optional extras rather than requirements. Reach for a private folder, covered in private folders and the underscore convention, when a naming collision with a future Next.js convention feels like a real risk. Reach for a route group instead, covered in route groups in Next.js, when the goal is separating sections of the app rather than hiding individual files from routing.

Common mistake

Naming a component file after a reserved convention by accident is the most common mistake, such as calling a loading spinner component loading.tsx inside a route folder. Next.js treats that name as the route's actual loading UI, not as a reusable component, which produces confusing behavior that has nothing to do with a typo in the code itself.

The safest habit is checking a new file's name against the reserved list before saving it inside a route folder, especially for common UI terms like loading, error, or template that also happen to be routing conventions. A quick rename to something like LoadingSpinner avoids the collision entirely while keeping the file exactly where it is most convenient to find.

Rune AI

Rune AI

Key Insights

  • Only page, route, layout, and a handful of other reserved names are routable.
  • Any other file name inside app is safe to colocate next to the routes that use it.
  • Only the content a page or route file actually returns reaches the browser.
  • Colocation is optional, not a framework requirement.
  • A private folder or a folder outside app are both valid alternatives to colocation.
RunePowered by Rune AI

Frequently Asked Questions

Can I name a component file page.tsx if it isn't meant to be a route?

No. Any file named page, route, layout, or one of the other reserved conventions becomes routable wherever it sits, regardless of intent. Avoid those exact names for non-routing files.

Do I have to colocate files inside app?

No. Keeping all non-routing code outside app, in a top-level folder like components or lib, works just as well. Colocation is a choice, not a requirement.

Does colocation affect what gets sent to the browser?

No directly, but only the content actually returned by a page or route file is sent to the client. A colocated component only ships if something inside the route tree actually imports and renders it.

Conclusion

Colocation works because only a specific, short list of file names turns a folder into a route. Everything else, no matter how deeply nested inside app, stays a private project file unless something imports it.