Code Monkey home page Code Monkey logo

Comments (36)

beepboopitschloe avatar beepboopitschloe commented on April 27, 2024 11

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.

dlindenkreuz avatar dlindenkreuz commented on April 27, 2024 7

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.

arunoda avatar arunoda commented on April 27, 2024 3

@kachkaev I think that's related to this: #291

from next.js.

doodiosie avatar doodiosie commented on April 27, 2024 2

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.

CompuIves avatar CompuIves commented on April 27, 2024 1

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.

rauchg avatar rauchg commented on April 27, 2024 1

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.

mmmeff avatar mmmeff commented on April 27, 2024

This idea is amazing.

from next.js.

mmmeff avatar mmmeff commented on April 27, 2024

How would you pass the parameter into the component? getInitialProps?

from next.js.

CompuIves avatar CompuIves commented on April 27, 2024

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.

nickdandakis avatar nickdandakis commented on April 27, 2024

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.

mmmeff avatar mmmeff commented on April 27, 2024

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.

nodegin avatar nodegin commented on April 27, 2024

@nickdandakis @nmuth -1 for this solution since it's all index.js

from next.js.

beepboopitschloe avatar beepboopitschloe commented on April 27, 2024

@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.

dstreet avatar dstreet commented on April 27, 2024

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.

beepboopitschloe avatar beepboopitschloe commented on April 27, 2024

@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.

nodegin avatar nodegin commented on April 27, 2024

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.

dstreet avatar dstreet commented on April 27, 2024

@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.

dstreet avatar dstreet commented on April 27, 2024

@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.

nodegin avatar nodegin commented on April 27, 2024

@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.

beepboopitschloe avatar beepboopitschloe commented on April 27, 2024

@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.

dstreet avatar dstreet commented on April 27, 2024

@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.

dstreet avatar dstreet commented on April 27, 2024

@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.

dstreet avatar dstreet commented on April 27, 2024

@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.

nodegin avatar nodegin commented on April 27, 2024

@dstreet

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.

nodegin avatar nodegin commented on April 27, 2024

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.

dstreet avatar dstreet commented on April 27, 2024

Hah. I like the way you think, @nodegin

from next.js.

nickdandakis avatar nickdandakis commented on April 27, 2024

@nodegin, pretty sure $ are frowned upon within filenames. It may be interpreted as an environment variable in Unix.

from next.js.

nodegin avatar nodegin commented on April 27, 2024

@nickdandakis How about use @ instead?

users.js
[email protected]
users_@[email protected]

from next.js.

dstreet avatar dstreet commented on April 27, 2024

This syntax needed to solve this within the filesystem alone is awkward and extremely limiting.

from next.js.

sedubois avatar sedubois commented on April 27, 2024

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.

nodegin avatar nodegin commented on April 27, 2024

Hi guys, please take a look at PR #147

from next.js.

CompuIves avatar CompuIves commented on April 27, 2024

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.

ksmithut avatar ksmithut commented on April 27, 2024

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.

dstreet avatar dstreet commented on April 27, 2024

@ksmithut #147 has already been updated to use that syntax

from next.js.

ksmithut avatar ksmithut commented on April 27, 2024

lol, definitely late to the party :) Thanks @dstreet

from next.js.

kachkaev avatar kachkaev commented on April 27, 2024

@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)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.