I'm using react-router-dom to create client-side pages within a React site. This extension is working fine but I'm wondering if there is a way I can hide the URL extensions from appearing within the browser navigation bar.
Here is my code:
class App extends Component {
render() {
return (
<div>
<ul>
<li><Link to="/">Home</Link></li>
<li><Link to="/airports">Airports</Link></li>
<li><Link to="/cities">Cities</Link></li>
<li><Link to="/courses">Courses</Link></li>
</ul>
<Route path="/" exact component={Home}/>
{/* You don't always have to render a whole component */}
<Route path="/airports" render={() => (<div> This is the airport route </div>)}/>
<Route path="/cities" component={City}/>
<Route path="/courses" component={Courses}/>
</div>
);
}
}
So clicking on Airports will show www.myurl.com/airports, clicking on Cities shows www.myurl.com/cities. Since these pages are created client-side and not server-side, I'd really like to hide these extensions so that whenever I click on these links, it will just show the host name of www.myurl.com.
Hopefully there is an easy way of accomplishing this. Any help is greatly appreciated!
There are two ways to do this:
Using Memory History
From the docs:
Memory history doesn't manipulate or read from the address bar. This
is how we implement server rendering. It's also useful for testing and
other rendering environments (like React Native).
Use one like so:
const history = createMemoryHistory(location)
render(
<Router history={history}>
<Route path='/' component={App}>
<IndexRoute component={Home} />
<Route path='about' component={About} />
<Route path='features' component={Features} />
</Route>
</Router>,
document.getElementById('app')
)
Using MemoryRouter
From the docs:
A Router that keeps the history of your "URL" in memory (does not
read or write to the address bar). Useful in tests and non-browser
environments like React Native.
import { MemoryRouter } from 'react-router'
<MemoryRouter>
<App/>
</MemoryRouter>
Related
So here is a snippet of code from my App.js,
return (
<div className="app">
<Router>
{!user ? (
<LoginScreen />
) : (
<Switch>
<Route path='./profile'>
<ProfileScreen />
</Route>
<Route exact path="/">
<HomeScreen />
</Route>
</Switch>
)}
</Router>
</div>
Now when I click on the profile button, it takes me to a blank profile page and there are no errors, and everything compiles. Here is the ProfileScreen page code,
import React from 'react'
import './ProfileScreen.css'
function ProfileScreen() {
return (
<div className='profileScreen'>
<h1>
this is the profile screen
</h1>
</div>
)
}
console.log("hello")
export default ProfileScreen
Now the issue here is that every time I refresh the page the console.log("hello") (a test) shows up in developer tools! It also shows up in the main page before I am taken to the profile page. Also in the css file, I can change the entire background color using
* {
background-color:black;
}
So something is clearly working as I can change the background of the profile page but whenever I target the profileScreen class nothing shows up and my h1 never shows up even without styling when there should be text showing up. I am very new to reactJS and react-router-dom so I would appreciate any help! thank you.
I'm certain your profile path is incorrect. AFAIK react-router-dom v5 doesn't use relative path routing, it uses absolute path routing, so "./profile" is an invalid path. Update it to be "/profile".
<Switch>
<Route path="/profile">
<ProfileScreen />
</Route>
<Route exact path="/">
<HomeScreen />
</Route>
</Switch>
Recently I've tried building a web platform trough React. Everything's fine, everything's work ecc.
But I've run in many problems when I tried to create a different page for the user login:
I already had Routes in my code, so when I tried to add other Routes to another js file they simply didn't work.
I have no clue how to do the authentication in react router, I've tried in many ways, followed many tutorials but nothing worked out.
<Switch>
<Route exact path='/' component={Feed}/>
<Route path="/user" component={Profilo}/>
<Route path='/explore-page' component={ExplorePage} />
<Route path='/events-page' component={EventsPage} />
<Route path='/calendar-page' component={CalendarPage} />
<Route path='/stats-page' component={StatsPage} />
<Route path='/form' component={FormPage}/>
<Route path="/user" component={Profilo}/>
<Route path="/user/:userId" component={Profilo} />
</Switch>
This is all the routes I'm currently using inside a div to get the react component rendered.
As I said before adding other routes in an upper file wouldn't give me a response.
So, in the end, I'm gonna ask you where should I put the route for the login and the home? In there or I should just moving everything?
Thank you in advance.
One simple way is adding the logic to handle authentication in your render function.
If the user is not authenticated. Redirect to the login page. Otherwise, go to your component
render() {
if (!this.props.isAuth) {
return (
<Switch>
<Route exact path="/" component={Login} />
<Redirect to="/" />
</Switch>
);
}
return (<Switch>
<Route
// your router
/>
</Switch>);
}
When I try to have nested routes on my root route I run into a problem.
I have 3 "main" routes:
<Switch>
<Route path="/" component={Home} />
<Route path="/login" component={Login} />
<Route path="/logout" component={Logout} />
</Switch>
On my Home component I have a nested router like this:
<div>
<Route path="/" render={() => <div>Home</div>} />
<Route path="/test" render={() => <div>Test Route</div>} />
</div>
The Home component has a sidebar HOC which contains the Links.
<Sidebar>
<Link to="/">Home</Link>
<Link to="/test">Test</Link>
<Link to="/logout">Logout</Link>
</Sidebar>
When Im on my Root component and click the Test link, the route on the nested router changes to the Test component which is correct. Whenever I go the login and/or logout route it tries to display that in the nested router in the Home component
Any idea what is going wrong?
EDIT: I've tried the example #Tholle provided. Unfortunately it still doesn't work the way I want to. See this CodeSandBox I made to reproduce my problem.
your links need to point to "/home/testX" and the nested routes need to handle "/home/testX". Also you will need a route for "/home" in the root. I don't believe the Link component is scoped to the route in which it is called. Meaning that to link to "/test1" assumes that is the base route. However, the rendering of test1 actually takes place in the home component.
To put it another way: In order to get to /home/test1 you must first get the home component (/home) to render which can then render the route for test1 (/home/test1)
Here's the codesandbox
Here is an example that provides a bit more flexibility codesandbox. This one will require a redirect of "/" because it depends on the path being used and it needs to be "/home" not "/".
Hope this helps. Hope I got it all right.
The Switch component makes sure that only the first Route that matches is rendered. To stop <Route path="/" component={Home} /> from always being rendered, you can set the exact prop to true.
Example (CodeSandbox)
<Switch>
<Route exact path="/" component={Home} />
<Route path="/login" component={Login} />
<Route path="/logout" component={Logout} />
</Switch>
I am creating an application using ReactJS. I am using react router v4 from react-router-dom.
I have written routes in index.js file.
<BrowserRouter>
<Switch>
<Route exact path="/" component={Login} />
<Route exact path='/dashboard' component={Viewport} />
</Switch>
</BrowserRouter>
Rest of the application in Viewport.js file.
return (
<div className="">
<Sidebar navigation={this.viewport} />
<HeaderBanner user={this.props.user} />
<div className="center-panel">
//todo
//Can I use router here?
</div>
</div>
)
After user login's, I am rendering Viewport which contains Sidebar and header bar by default. Based on the item click in the sidebar navigation, I need to render components dynamically. As of now, if I write anything in the place of todo, it renders only that component for the complete browser window.
Is there any way to use routers in multiple places of the application? If yes, how can I implement it? If no, what's the best solution?
As far as I have seen, routers will be stacked at one place in the application.
Thanks in advance.
I followed a tutorial on youtube recently which was very useful
So I took some of it and applied it to your setup
<BrowserRouter>
<div>
<Route exact path="/" component={Login} />
<Route exact path='/dashboard' component={Viewport} />
</div>
</BrowserRouter>
import { NavLink, Route } from 'react-router-dom';
class Viewport extends Component {
constructor(props) {
super(props);
}
render() {
return (
<div>
<div className="Side-bar">
<NavLink
activeClassName="active"
to={`${this.props.match.url}/sub-page-name-1`}>Sub Page 1</NavLink>
<NavLink
activeClassName="active"
to={`${this.props.match.url}/sub-page-name-2`}>Sub Page 2</NavLink>
<NavLink
activeClassName="active"
to={`${this.props.match.url}/sub-page-name-3`}>Sub Page 3</NavLink>
</div>
<HeaderBanner user={this.props.user} />
<div className="center-panel">
<Route path={`${this.props.match.url}/sub-page-name-1`} component={SubPagePanel1} />
<Route path={`${this.props.match.url}/sub-page-name-2`} component={SubPagePanel2} />
<Route path={`${this.props.match.url}/sub-page-name-3`} component={SubPagePanel3} />
</div>
</div>
)
}
}
I removed Switch as well because I didn't use it for my sub pages... :-S
Update: Have created a repo showing a working example of sub page content
https://github.com/PocketNinjaDesign/so-sub-routes-answer
Yes you can use <Routes> in as many places as you want. <Router> components are the ones you can only use once.
I am very new to react and and the router and bootstrap libraries I chose to use. They are basically just react-router-bootstrap. I am just getting a feel for things and I want to make a web app that has some basic url navigation. I have 4 parts, home browse add and about, clicking on the links works well, and so do the routes, but when navigate to the default route the handler works okay in that it shows the Home component, but does not make the home button active in the nav. I am a bit stuck and wondering if anyone can help me out? I would like to make that home part active at the '/ ' default route, and was thinking I could just redirect to '/home' and let the rest take care of it, however it doesn't look like I can add a path prop to DefaultRoute. So I was curious if anyone had any ides? Also curious if this looks like the right way to build something like I am building.
I made a gist that is HERE
Thanks to all ahead of time!!!
The only change that I made was to your routes, they used to look like this:
var routes = (
<Route handler={App} >
<DefaultRoute handler={Home}/>
<Route name="home" handler={Home} path="/home">
</Route>
<Route name="browse" handler={Browse} path="/browse">
</Route>
<Route name="add" handler={Add} path="/add">
</Route>
<Route name="about" handler={About} path="/about">
</Route>
</Route>
);
and I changed them to this:
var routes = (
<Route handler={App} >
<DefaultRoute name="home" path="/" handler={Home}/>
<Route handler={Home} path="/home">
</Route>
<Route name="browse" handler={Browse} path="/browse">
</Route>
<Route name="add" handler={Add} path="/add">
</Route>
<Route name="about" handler={About} path="/about">
</Route>
</Route>
);
I tested it and it works as expected. When you visit the home page the url only has the /#/ and is not suffixed like /#/home, I don't think that is an issue.