I am trying to get a specific post appear by using its slug. I have sucessfully made this happen by setting the Route path to /journal:id and Link to={"/journal" + post.field.slug}. However this is not what I want the url to look like. Any guess why the Route won't recognize the added slash?
<Switch>
<Route path='/journal' component={Journal} />
<Route path='/journal/:id' component={SinglePost} />
<Route path='/shop' component={Shop} />
<Route path='/contact' component={Contact}/>
</Switch>
When I click on the Link inside of Journal that should display the SinglePost component, the URL changes but the view doesn't change and I still see the Journal. This is the Link:
<Link
className='posts__post'
key={post.fields.slug}
to={"/journal/" + post.fields.slug}
>
If you have multiple paths that have common parts like /journal and /journal/:id (common part is /journal) you should add attribute exact to shorter path to not stop searching for a route if only partially matched
<Switch>
<Route exact path='/journal' component={Journal} />
<Route path='/journal/:id' component={SinglePost} />
<Route path='/shop' component={Shop} />
<Route path='/contact' component={Contact}/>
</Switch>
Related
i have a react app in which i want that if user route start with admin it should have a different navbar
lets take example
normal page
<NormalNavbar/>
<NormalHeader/>
<NormalBody/>
<NormalFooter/>
But if i have the admin route
then i want to have
<AdminNavbar/>
<AdminHeader/>
<AdminBody/>
<AdminFooter/>
The issue is when we wind it inside the Routes then we decide the normal components which are loading i will paste the example below
return (
<div className="App">
<>
<Navbar />
<Routes>
<Route exact path="/" element={<HomePage />} />
<Route exact path="/product/:id" element={<ProductPage />} />
<Route exact path="sarangAdmin/create-product" element={<CreateProduct />} />
<Route exact path="login" element={<Login />} />
<Route exact path="profile" element={<Profile />} />
<Route exact path="register" element={<Register />} />
</Routes>
<Footer />
</>
</div>
);
You can see my current navbar and footer going to be same
you can put elements with conditions like that
{isAdmin? <AdminNavbar> : <NormalNavbar> }
OR
in the navbar component view different menu
See the above answers is good but its not the optimal solution I wanted so I get the solution by looking other git repository here is the repository that shows how you should do it in a perfect way make route component structure and then you can render them conditionally which I wanted in my case the most optimum solution to my question
Please help. I'm trying to make nested routes but here is a problem: if I use exact path, I can't have nested routes.
For example, I want to have one route that is nested and one individual. I have to use exact if I want to have an individual one. How can I have both?
<Route exact path="/projects" component={Projects} />
<Route path="/projects/individual" component={ProjectsList} />
<Route path="/projects/nested" component={ProjectsList} />
Here is codesandbox.
You are right, with an exact attribute you loose the flexibility to use nested routes. The solution here is to make use of Switch and order your routes such that the prefix paths are at the end
<Switch>
<Route path="/projects" component={Projects} />
<Route path="/" component={Home} />
</Switch>
and inside Projects you can write the nested paths
<Route path="/projects/individual" component={ProjectsList} />
<Route path="/projects/nested" component={ProjectsList} />
Update:
If however on ProjectsList component i.e paths "/projects/individual" and "/projects/nested" you do not want to render Projects component you would use them like
<Switch>
<Route path="/projects/individual" component={ProjectsList} />
<Route path="/projects/nested" component={ProjectsList} />
<Route path="/projects" component={Projects} />
<Route path="/" component={Home} />
</Switch>
I have a situation in my React app to look like something as follows using react-router. I want the index of the users/:userId endpoint to redirect to another endpoint that includes a :userId params. What is a good way to do this? Right now the user from currentUser will return null because the code is only executed once in the beginning when the App is loaded the user is not yet authenticated. I'm guessing I will need to force react-router to reload the history and certain variables, or change the order of when I do authentication?
routes.js
{ /* Routes requiring login */ }
<Route onEnter={requireLogin}>
<Route path="users" component={Users}>
<Route path=":userId" component={User}>
<IndexRedirect to={`/users/${currentUser().id}/profile`} />
<Route path="profile" component={UserProfile} />
<Route path="settings" component={UserSettings} />
<Route path="activity" component={UserActivity} />
</Route>
</Route>
</Route>
If I understand it correctly and you want to redirect from /users/1 to /users/1/profile and /users/2 to /users/2/profile, you can simply replace ${currentUser().id} with :userId.
So your code would looks like this:
<Route onEnter={requireLogin}>
<Route path="users" component={Users}>
<Route path=":userId" component={User}>
<IndexRedirect to="profile" />
<Route path="profile" component={UserProfile} />
<Route path="settings" component={UserSettings} />
<Route path="activity" component={UserActivity} />
</Route>
</Route>
</Route>
Because the redirect is in the context of the route :userId: you can simply define your target route relative.
I'm facing a situation where I have my router working fine with the following configuration:
<Route path="/" component={Blog}>
<Route path="list(/:category)(/:subcat)" component={ArticleList} />
<Route name="article/:category(/:subcat)/:id" component={ArticlePage} />
</Route>
But now I was asked to improve the URL and remove some "unecessary" prefixes from the URLs
Current URL -> Desired URL
blog/list/football/worldcup -> blog/football/worldcup
blog/list/football -> blog/football
blog/article/football/10 -> blog/football/10
So I tried unsuccessfully to change my route to keep all parameters optional
<Route path="/" component={Blog}>
<Route path="(/:category)(/:subcat)" component={ArticleList} />
<Route name=":category(/:subcat)/:id" component={ArticlePage} />
</Route>
Is there a way to match the urls as described using react router?
You can simply have it like this
<Route path="blog" component={Blog}>
<IndexRoute component={ BlogComponent } />
<Route path=":category" component={ ArticleCategoryList } />
<Route path=":category/:subcat" component={ ArticleSubCategoryList } />
</Route>
I have prefixed blog to the route.
IndexRoute will match /blog route, it acts as the index route.
:category will match blog/football or blog/any-sport
:category/:subcat will match both blog/football/worldcup and blog/football/10
You will have to be careful here as this will match for both subcategory and id.
You can write a function/middleware which can validate the type of route.. whether id or subcategory.
I have a web site with few ordinary pages and a page with Google Map. When map marker is clicked a panel with marker details is displayed next to the map. This detail has own URL so that users can link to it:
<Route path="/" component={App}>
<IndexRoute component={Welcome} />
<Route path="map" component={Map}>
{/* Detail is a child component of Map,
it only adds detail panel markup to Map. */}
<Route path="detail/:id" component={Detail} />
</Route>
<Route path="about" component={About} />
</Route>
This works fine. But let's get rid of Welcome page and display Map right on the web root so that:
/ renders App > Map components
/detail/:id renders App > Map > Detail components
/about renders App > About components
<Route path="/" component={App}>
{/* Map has to be IndexRoute so that it is displayed at root URL. */}
<IndexRoute component={Map}>
<Route path="detail/:id" component={Detail} />
</IndexRoute>
<Route path="about" component={About} />
</Route>
But this doesn't work because IndexRoute can't have subroutes.
This is the best solution I have found:
<Route path="/" component={App}>
<Route component={Map}>
<IndexRoute component={EmptyComponent} />
<Route path="detail/:id" compoent={Detail} />
</Route>
<Route path="about" component={About} />
</Route>
But I don't like the empty component.
Am I missing something? Am I doing something unusual? Why it is not possible to do it the first more intuitive way?
Move the / path
<Route component={App}>
<Route path="/" component={Map}>
<Route path="detail/:id" component={Detail}/>
</Route>
<Route path="/about"/>
</Route>
Your solution looks largely fine to me – the only caveat is that you don't need to specify the component in that case; just do <IndexRoute />.
By design, index routes terminate matching, but it's easy to insert trivial routes.
Maybe I am wrong but it seems as if your tried to set another route in:
<IndexRoute component={Map}>
<Route path="detail/:id" component={Detail} />
</IndexRoute>
So your basic structure is something like:
<IndexRoute>
<Route> </Route>
</IndexRoute>
According to your error it is not allowed that there is a <Route> inside of your <IndexRoute>... At the beginning you did not do that mistake because you closed the <IndexRoute> before you opened the next <Route>-Tag.
So if you want your code to work again you should not open another <Route> inside of your <IndexRoute>. You managed to fix this by adding an Dummy-IndexRoute. So if you want to set your Map component as IndexRoute you will have to change your HTML structure so that there is no Detail component inside of your map component because then you will have the same problem again that you got a <Route> inside your <IndexRoute>