Comments (36)
What about using a dot instead of a colon?
pages/
users/
index.js
users.id/
index.js
friends/
index.js
friends.friendsid/
index.js
users.id.photoid/
index.js
from next.js.
The concept of a filesystem based router shows its limits when it comes to advanced routing with RegExps, conditional routes and alike.
@CompuIves, I think your suggestion is really elegant within those boundaries, but I also think the project ultimately needs more than the current filesystem based routing to cater to the requirements of larger web apps.
This is of course something for the Next.js team to decide; I'd appreciate some comments and am thrilled to see this discussion about routing evolve.
from next.js.
@kachkaev I think that's related to this: #291
from next.js.
I've written some code to have next routing behave similar to how .htaccess works in php. My routes file looks like this :
module.exports = [
{
test: /edit\/([0-9]+)/g,
redirect: "edit?id=$1"
}
];
and the interpretation code is done as so :
var server = http.createServer(function (req, res) {
var newUrl = routes.reduce(function (url, route) {
return url.replace(route.test, route.redirect);
}, req.url);
newReq = Object.assign(req, {url: newUrl});
handle(newReq, res);
});
I might spend some time trying to get this into a package but having moved from php to node and now to next, this is a pretty good solution for me
from next.js.
Ah, I now see that I created a duplicate PR 😅 .
How would this translate a path with nested params like so?
/users/:id/:photoid
It would have a folder structure like this:
pages/
users/
_id/
_photoid.js
But I do find that your structure feels more natural since it doesn't add a magical _
.
from next.js.
I commented elsewhere that APIs like this will be possible in userland, by using the programmatic API. Quoting:
Considering #291 (comment), I suggest you start looking into transforming this into an API like:
const nextRoutes from 'next-routes'
const app = next()
createServer(nextRoutes(app)).listen(process.env.PORT || 3000)
Users of this approach will have to use node server.js
instead of next start
.
Then you can extend next.config.js
with your routes
, and you can read the config from app.config
(cc @nkzawa).
This will give you the great expressiveness and ease-of-use, without us having to bloat the core :)
from next.js.
This idea is amazing.
from next.js.
How would you pass the parameter into the component? getInitialProps?
from next.js.
Thanks! I think the best way is to add it as an argument in getInitialProps
here: https://github.com/zeit/next.js/blob/master/server/render.js#L22.
So then you could have this for example with getInitialProps
:
getInitialProps(ctx, { id }) {
// Do request using id
}
from next.js.
How would this translate a path with nested params like so?
/users/:id/:photoid
Would it make more sense to use a structure like this?
pages/
users/
index.js
users:id/
index.js
friends/
index.js
friends:friendsid/
index.js
users:id:photoid/
index.js
The above would support routes for
/users/
/users/:id
/users/:id/friends
/users/:id/friends/:friendsid
/users/:id/:photoid
from next.js.
It's important to note that certain OS's will barf on the colons in directory names. In OSX, you can create a directory like :id
via terminal but if you try and view it in finder it shows as /id
and you won't be able to rename it with finder without breaking the filename
from next.js.
@nickdandakis @nmuth -1 for this solution since it's all index.js
from next.js.
@nodegin It could just as easily follow the existing convention of users.js
for pages with no children and users/index.js
otherwise.
pages/
users.id/
index.js
friends.js
friends.friendid.js
I think this fits in pretty well with how next
handles routing, but I don't like how non-obvious the dot syntax is.
from next.js.
I approached his problem differently, through configuration. Defining routes this way allows for more complex routing. It also allows the file system to maintain semantic meaning.
For instance, the route '/users/:id/friends/:id' could point to the file 'pages/users/friend', which avoids the use of overly complex hierarchies and naming conventions.
You can see my implementation in #59.
I'm still working out a few kinks, but I think it's a good solution to the problem.
from next.js.
@dstreet Question about your implementation. If I have a route configuration like this:
routes: {
'/posts/:id': 'arbitrary/directories/post'
}
Then navigating to /posts/1234
should render the component in arbitrary/directories/post.js
, correct? What should happen if I navigate to arbitrary/directories/post
directly? 404?
from next.js.
I think @Compulves' solution is the best one yet:
pages/
photos/
index.js
id.js
_id.js
share/
_action.js
which mapping to:
pages/photos
pages/photos/id
pages/photos/:id
pages/photos/share/:action
from next.js.
@nmuth That is one of the kinks that needs to be ironed out. Currently it will fall through to the default route, which maps directly to the filesystem, so arbitrary/directories/post
would be rendered
from next.js.
@nodegin how would you implement pages/photos/:id/share
or some other route that is a descendent of a single photo?
Something like this?
pages/
photos/
index.js
id.js
_id/
index.js
share/
index.js
_action.js
Also how would you handle more complex routes. For instance, routes with or regex?
from next.js.
@dstreet If we just use filesystem for the automatic routing then it must be limits, in this case we can use the solution which embedding the routes in the next section of package.json.
For pages/photos/:id/share
I think it is ok to change it to pages/photos/share/:id
thus:
pages/
photos/
index.js
_id.js
share/
_id.js
And in this case:
/users/:id/friends/:friendid
We can just change to:
/users/:id
/users/friends/:id
from next.js.
@dstreet It might be worth having two approaches: one based on the filesystem, like @Compulves suggested, and one based on a configuration file that can handle arbitrary routes and regexes.
@nodegin I get what you're saying, but I would rather not sacrifice expressiveness just to avoid using index.js
files, especially since that falls in line with how Next already works.
from next.js.
@nodegin Assuming /users/friends/:id
pull the friends of user with ID :id
, I can see how that would work, but what if you only wanted to display a single friend, with an ID of :friendid
, of the user? However, if in that example, :id
is the ID of the friend, then that would work, but only if :id
is a guid, otherwise you could run into conflicts.
On another note, and my solution exhibits the same problem, given the following filesystem, what component would render with the route /users/friends
?
pages/
users/
_id.js
friends/
index.js
That path would match two possible components: pages/users/_id.js
and pages/users/friends/index.js
from next.js.
@nmuth I too am leaning towards to dual approach. My only concern is that it opens up the framework to too much confusion, and how would conflicts between the two solutions be resolved?
from next.js.
@nmuth To solve the issue of the routes falling through to the filesystem paths, the implementation could be adjusted such that
routes: [
{ path: '/posts/:id', module: 'arbitrary/directories/post', accessDirect: false }
]
would disallow the default routing from matching on a route where accessDirect
is false.
from next.js.
if you only wanted to display a single friend, with an ID of :friendid
/users/:id
would do that since friend should be an user too
from next.js.
How about we don't use any folder:
/users
/users/:id
/users/:id/friends
/users/:id/share
/users/:id/share/:action
pages/
_users.js
_users_$id.js
_users_$id_friends.js
_users_$id_share.js
_users_$id_share_$action.js
where _
represents /
, $
represents :
from next.js.
Hah. I like the way you think, @nodegin
from next.js.
@nodegin, pretty sure $
are frowned upon within filenames. It may be interpreted as an environment variable in Unix.
from next.js.
@nickdandakis How about use @
instead?
users.js
[email protected]
users_@[email protected]
from next.js.
This syntax needed to solve this within the filesystem alone is awkward and extremely limiting.
from next.js.
Naive question (from someone unfamiliar with routing and the decision-making behind next
), in order to avoid doing all the hard work again, is there any possibility to use React-Router v4 directly, a subset of it, or some of its key decisions? It sounds like they learned a lot from their mistakes and it would be great not to reinvent the wheel. AFAIK, in v4 they made sure to only handle routing and everything else is externalized, so I guess it should be lightweight, and it has a huge community base.
Everything is provided as a component (so can use composability and the React component lifecycle): <Route>
, <ServerRouter>
, <Match>
, <Miss>
, etc. See new docs deployed with now
😉
from next.js.
Hi guys, please take a look at PR #147
from next.js.
We should try to keep keep the need of diving into configuration files to a minimum. Therefore I think we should have parameterized routing with just the file system if we can find a simple, not confusing implementation while also keeping the possibility to use your own system (eg with this exploration #25).
from next.js.
I'm a little late to the party, but you could use parameters in routes like swaggerize-express does it.
tl;dr
users.js
users/
|- {id}.js
|- friends.js
|- friends/
|- {friendId}.js
from next.js.
@ksmithut #147 has already been updated to use that syntax
from next.js.
lol, definitely late to the party :) Thanks @dstreet
from next.js.
@nodegin could you please share a couple of thoughts on when this feature may be delivered? Since #147 is now closed without merging, I guess you're working on some other approach.
Awesome framework - I'm very keen to try it out!
from next.js.
Related Issues (20)
- Docs:
- approuter app\default is ignored after build HOT 1
- app\default is ignored after build HOT 4
- Required AUTH_SECRET in latest version HOT 3
- Turbopack: "Cannot find module" when package `require()` a package installed via the `optionalDependencies` field in package.json HOT 1
- Invalid import alias being used in CLI (create-next-app)
- Parallel Routes not working as expected in the development HOT 3
- Jest/Vitest unit testing: TypeError: (0 , _reactdom.useFormStatus) is not a function HOT 1
- HookWebpackError in isInterceptionRouteRewrite() when rewrites has an empty `has` array
- unable to read cookie in a server action from client component call in chrome 56
- Bun and Turbopack print lots of warnings in v14.2.0-canary.48 HOT 2
- Docs: `aria-disabled` does not disable button. HOT 6
- NextJS Caching based on Get URL and not Tag HOT 2
- Unable to parse config export in source file HOT 1
- Unable to parse config export in source file HOT 1
- Unable to parse config export in source file HOT 8
- next/link leads to a cached page HOT 1
- While Scrolling back to top in mobile, Next app Breaks! HOT 5
- headers() fails to opt route into dynamic rendering if generateStaticParams for all params is defined in layout
- Using Link/Router with 'shallow' to navigate from pages to app router, when there is a top-level dynamic route under pages, lands on the dynamic route instead
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from next.js.