366
votes

I want to declare a path with an optional path parameter, hence when I add it the page to do something extra (e.g. fill some data):

http://localhost/app/path/to/page <= render the page http://localhost/app/path/to/page/pathParam <= render the page with some data according to the pathParam

In my react router I have the following paths, in order to support the two options (this is a simplified example):

<Router history={history}>    
   <Route path="/path" component={IndexPage}>
      <Route path="to/page" component={MyPage}/>
      <Route path="to/page/:pathParam" component={MyPage}/>
   </Route>    
</Router>

My question is, can we declare it in one route? If I add only the second row then the route without the parameter is not found.

EDIT#1:

The solution mentioned here about the following syntax did not work for me, is it a proper one? Does it exist in the documentation?

<Route path="/product/:productName/?:urlID?" handler={SomeHandler} />

My react-router version is: 1.0.3

6

6 Answers

747
votes

The edit you posted was valid for an older version of React-router (v0.13) and doesn't work anymore.


React Router v1, v2 and v3

Since version 1.0.0 you define optional parameters with:

<Route path="to/page(/:pathParam)" component={MyPage} />

and for multiple optional parameters:

<Route path="to/page(/:pathParam1)(/:pathParam2)" component={MyPage} />

You use parenthesis ( ) to wrap the optional parts of route, including the leading slash (/). Check out the Route Matching Guide page of the official documentation.

Note: The :paramName parameter matches a URL segment up to the next /, ?, or #. For more about paths and params specifically, read more here.


React Router v4 and above

React Router v4 is fundamentally different than v1-v3, and optional path parameters aren't explicitly defined in the official documentation either.

Instead, you are instructed to define a path parameter that path-to-regexp understands. This allows for much greater flexibility in defining your paths, such as repeating patterns, wildcards, etc. So to define a parameter as optional you add a trailing question-mark (?).

As such, to define an optional parameter, you do:

<Route path="/to/page/:pathParam?" component={MyPage} />

and for multiple optional parameters:

<Route path="/to/page/:pathParam1?/:pathParam2?" component={MyPage} />

Note: React Router v4 is incompatible with (read more here). Use version v3 or earlier (v2 recommended) instead.

88
votes

For any React Router v4 users arriving here following a search, optional parameters in a <Route> are denoted with a ? suffix.

Here's the relevant documentation:

https://reacttraining.com/react-router/web/api/Route/path-string

path: string

Any valid URL path that path-to-regexp understands.

    <Route path="/users/:id" component={User}/>

https://www.npmjs.com/package/path-to-regexp#optional

Optional

Parameters can be suffixed with a question mark (?) to make the parameter optional. This will also make the prefix optional.

Simple example of a paginated section of a site that can be accessed with or without a page number.

    <Route path="/section/:page?" component={Section} />
37
votes

Working syntax for multiple optional params:

<Route path="/section/(page)?/:page?/(sort)?/:sort?" component={Section} />

Now, url can be:

  1. /section
  2. /section/page/1
  3. /section/page/1/sort/asc
9
votes

for react-router V5 and above use below syntax for multiple paths

<Route
          exact
          path={[path1, path2]}
          component={component}
        />
2
votes

As with regular parameters, declaring an optional parameter is just a matter of the path property of a Route; any parameter that ends with a question mark will be treated as optional:

<Route path="to/page/:pathParam?" component={MyPage}/>
0
votes

If you are looking to do an exact match, use the following syntax: (param)?.

Eg.

<Route path={`my/(exact)?/path`} component={MyComponent} />

The nice thing about this is that you'll have props.match to play with, and you don't need to worry about checking the value of the optional parameter:

{ props: { match: { "0": "exact" } } }