Skip to content

RFC: Relative Links and Routes #5127

@ryanflorence

Description

@ryanflorence

We intend to ship Relative Routes and Relative Links soon. I'd like to hear people's comments on something I'm not totally sure about yet.

What are Relative Links and Routes?

Instead of <Route path={match.path + '/more/stuff'}/> you could simply do <Route path="more/stuff"/> and Router will use the lack of / at the start of your path as a hint that you want to just use whatever path is above you. Relative!

Same with links. Instead of <Link to={match.url + '/more/stuff'}/> you can just do <Link to="more/stuff"/>.

The Problem

Going "down" as shown in the quick example up there is easy. But we're not sure what ".." should mean. There are two options for what it means: go up a URL segment, or go up a matched route.

Go up a URL segment

With plain anchors tags, .. means "up a URL segment". Given the following URL, an anchor tag with the following HREFs results in the following URLs:

/clients/invoice/123
href url
payments /clients/invoice/123/payments
/clients/invoice/123
. /clients/invoice/123
.. /clients/invoice
../ /clients/invoice
../.. /clients
../../ /clients

(As far as I can tell, feel free to double check!)

So I think everybody's intuition around this is to just do exactly that and be done with it. Ship it.

However, I have this gut instinct that our intuition right now might be keeping us from a better meaning of ".." in a React Router app?

Go up a matched Route

Maybe your app is something like this:

  <Switch>
    <Route exact path="/" component={Home}/>
    <Route path="/clients" render={() => (
      <Clients>
        <Switch>
          <Route exact path="." component={ClientList}/>
          <Route path="invoice/:invoiceId" component={Invoice}/>
        </Switch>
      </Clients>
    )}/>
  </Switch>

Maybe we want ".." to mean "go up a matched route" rather than "go up some url segments".

So now the "relative" portion of the Link's to prop is the parent Route's path, not the current location.

to prop link's url
.. /clients
../.. /

Notice .. doesn't go to "invoice" because that's not a route that will ever match.

Pros

  • When you change a parent Route's path prop, the relative links below don't need to be updated
  • You can't link to something that doesn't have UI (probably, see cons*)

Cons

  • *Since any ol' route can match a location w/o a relationship with other Route's that match, a Link in one place can potentially have a completely different href than a link somewhere else--even though they have the same to prop 😬. It all depends on the Route's path the Link is rendered within.
  • It's against most people's intuition

What do you think?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions