Course outline · 0% complete

0/29 lessons0%

Course overview →

Folders become URLs

lesson 2-2 · ~12 min · 5/29

The routing rule

One rule covers almost everything:

Each folder under app/ is one URL segment, and the page.js inside it is the UI for that URL.

So:

  • app/page.js/
  • app/about/page.js/about
  • app/blog/drafts/page.js/blog/drafts

Nest folders and you nest URL segments, exactly like directories on disk. Compare this with Backend with Node.js, where you wrote app.get("/blog/drafts", handler) by hand. Next.js derives the same route table from your file system, which means the route list can never drift out of sync with the code.

Planning a bakery site from its URL list

This mapping is how working engineers plan a site: write the URL list first, and the folders fall out mechanically. Say a bakery wants four pages.

URL the customer typesFile you create
/app/page.js
/menuapp/menu/page.js
/menu/cakesapp/menu/cakes/page.js
/contactapp/contact/page.js

Two traps in that table

  • /menu and /menu/cakes are separate pages. Nesting the cakes folder inside menu does not remove the need for menu/page.js if /menu itself should render something.
  • Folder names become public URL segments, so name them the way users should read them: menu, not MenuStuff.
app/page.jsabout/page.jsblog/drafts/page.js//about/blog/draftsURLFiles
File-based routing: each folder under app/ is a URL segment, and page.js marks the UI rendered there.

Building the URL /shop/cart

That URL needs two folders and one page file: app/shop/cart/page.js.

The two folders, shop then cart, supply the two URL segments. The page.js inside the deepest folder supplies the UI rendered there. A file named cart.js sitting inside app/shop/ would not work, because it is just an ordinary module as far as the router is concerned, not a route.

routeFromPath: the mapping expressed as code

The folder-to-URL rule is mechanical enough to express as a plain JavaScript function, which is a good way to make it concrete. A function routeFromPath(filePath) receives a path like "app/blog/drafts/page.js", strips the leading "app" and the trailing "/page.js", and returns the URL. The homepage "app/page.js" is the one special case: after stripping both ends nothing is left, so it returns "/".

function routeFromPath(filePath) {
  let route = filePath.slice("app".length, filePath.length - "/page.js".length);
  return route === "" ? "/" : route;
}

console.log(routeFromPath("app/page.js"));
console.log(routeFromPath("app/about/page.js"));
console.log(routeFromPath("app/blog/drafts/page.js"));

Output

/
/about
/blog/drafts

How the slicing works

  • slice(start, end) cuts from both ends in one call: start after "app" (3 characters) and end before "/page.js" (8 characters).
  • After slicing, "app/page.js" leaves an empty string, so the ternary returns "/" for the homepage.
  • Nothing here is Next.js code. The framework does this same derivation internally, by reading your file tree at build time instead of parsing strings.

Adding a seasonal page deeper in the tree

The bakery wants a page at /menu/cakes/holiday. The file that makes it render is app/menu/cakes/holiday/page.js.

Each URL segment is one folder, so the URL needs the folder chain menucakesholiday, and the UI for the URL is always the page.js inside the deepest folder. Putting a file named holiday.js inside app/menu/cakes/ would not create the route, because the router treats it as ordinary importable code.