Filesystem Routers & Indexes
Soon, Next.js will support FS-based routes, like
and my own
But, there’s one design decision I’ve made that differs from the rest:
all routes are
A lot of engineers work from the bottom up.
“I’ll connect to the DB, query for the data I need, expose it as an API, then wire it up to the HTML.”
But, I’ve found it more intuitive to work from the user down. (Because, ultimately, the implementation details don’t matter).
/some/url, hit an API, then return a query from the DB”.
Maybe we can call this approach
Since Cool URIs don’t change, designing URL structure is good design.
The File system Looks Like a URL
Even when I
git clone a project, I have a habit of making the file system look like a URL.
For example, my
~/Projects directory looks like my GitHub repos:
$ tree -L2 . ├── ericclemmons │ ├── mdx-site │ ├── medium-to-markdown │ ├── node-recorder │ ├── polydev │ └── ... ├── webpack-contrib │ └── npm-install-webpack-plugin └── zeit └── next.js
So it makes sense that projects like UmiJS
would find a way to map
/users/:id to the file system:
+ pages/ + $post/ - index.js - comments.js + users/ $id.js - index.js
In my projects, however, I whitelist
index.* files for route creation.
Why Indexes Matter
For a small project, this seems fine:
pages/ index.js about.js contact-us.js
But, as complexity grows, you’ll find yourself with an underscore smell:
pages/ _app.js _document.js _layout.js _fetchFromDB.js ... index.js about.js contact-us.js
Because every file under
pages/ automatically becomes a page,
we have to find ways to get these files blacklisted.
When designing URL structure upfront, a whitelist allows our app to grow without side effects.
For comparison, my suggested structure is:
pages/ index.js about/ index.js contact-us/ index.js
Benefits to Index-based Routes
about/index.htmlis well-supported by many static servers at the URL
index.jscan be called whatever you’d like, without accidentally generating new pages for each file.
Customizing the extension allows for more functionality in the future:
post/:id/index.POST.jscould handle updating
post/:id/index.*.jscould be a fallback for
/post/123/*& show a custom
Of course, what people choose for denoting parameters (e.g.
has to be a valid filename,
but the most important goal is to provide a quick, intuitive path from the URL in the browser to the file serving it.