react router hosting with sub folders issues - javascript

I am using react router with my application and everything works fine locally. Below is my code. The issue is when I host it online it is in a my-application subdirectory:
https://www.example.com/my-application
This is breaking the code and it is not functioning as it should.
can anyone advise how to fix this issue? If there is anything unclear please feel free to ask. I have tried countless approaches but cannot get it to work. One answer can be seen here.
the issue I am getting is that with the current code it navigates to https://www.example.com/test as opposed to https://www.example.com/my-application/test. I thought if I hardcoded in the url it would work but this also breaks the application.
The code below is slightly whittled down to remove superfluous code.
import React, { Component } from 'react';
import styled from 'styled-components'
import { Route, Switch } from 'react-router-dom'
const Home = ({ avatarUrl }) => {
return (
<div>
<Route exact path="/" component={Overview}/>
<Route path="/test" component={Test}/>
</div>
);
};
class App extends Component {
render() {
return (
<section>
<Nav avatarUrl={ this.props.avatarUrl }/>
<Switch>
<Route path="/example" component={Example}/>
<Route path="/" render={()=><Home
avatarUrl={ avatarUrl }
/>}/>
</Switch>
</section>
)
}
}
export default App

Apply config changes pacakage.json add homepage page as your folder name

To solve this I just did two things:
Added "hostname": "https://www.example.com/my-application" at the top of package.json.
Added basename="my-application" to the BrowserRouter e.g. <BrowserRouter basename="my-application">
Note: I created the project using create-react-app. I am using react version 18 and react-router version 6.

Related

React - React Router Dom, hashbang routing solution

How can I make routing in React, using react-router-dom, using hashbang?
Something like
http://somesite.com/#/home
http://somesite.com/#/about
is fine by me.
In Angular routing, I used { useHash: true } in RouterModule of angular/router to achieve that.
In Vue routing, I used history: createWebHashHistory() in createRouter method of vue-router to achieve that.
Is there a way I achieve that here?
If it's not - please suggest me some other solid routing libraries for React.
P.S. If you wonder why I need it, the answer is IIS. And I don't want to go through overcomplicated procedure of getting it to work on IIS.
You need to use a HashRouter: https://reactrouter.com/web/api/HashRouter
For example, you can do the following:
import { HashRouter as Router, Route, Switch } from 'react-router-dom';
const App = () => {
return (
<Router>
<Switch>
<Route exact path="/foo">
<Component1/>
</Route>
<Route exact path="/bar">
<Component2/>
</Route>
</Switch>
</Router>);
}
Use <HashRouter> instead of one of the other routers.

How to implement links with redirect in next.js?

I have the following react component which I am trying to implement in next.js.
React component:
import React from "react";
import { Route, Switch, Redirect, withRouter } from "react-router-dom";
import Dashboard from "../../pages/dashboard";
import Profile from "../../pages/profile";
function Layout(props) {
return (
<>
<Switch>
<Route
exact
path="/"
render={() => <Redirect to="/app/dashboard" />}
/>
<Route path="/app/dashboard" component={Dashboard} />
<Route path="/app/profile" component={Profile} />
</Switch>
</>
);
}
export default withRouter(Layout);
As I am very new to next. j's, I am not sure on, how can I handle the routes with redirect in next.js similar to above react component code.
Any help is appreciated?
You are using React-Router with NextJS which is possible but not the best practice.
NextJS router is a pretty complicated thing as it handles ClientSide and ServerSide routing simultaneously.
your /app/dashboard and /app/profile pages should render properly. If you want to redirect / to /app/dashboard you can use this trick inside the getInitialProps of the pages/index.js file.

Creating dynamic Link with some text before it

I was building a search engine for custom project.
There I have a search bar from where user can search.
When the user searches, I want the given link to work as it works in case of google
www.google.com/ search? queryRelatedInfo
Notice the search? and then whatever query/parameter/ID
for this I tried something like this in
import React, {Component} from 'react';
import {
BrowserRouter,
Route,
Switch,
Redirect,
} from 'react-router-dom';
import SearchScreen from "./container/searchScreen.js"
import HomeScreen from "./container/home.js";
class route extends Component {
render () {
return (
<BrowserRouter>
<div>
<Switch>
<Route path ="/" exact render ={(props) => <HomeScreen {...props}/>} />
<Route path ="/search?:id" exact render ={(props) => <SearchScreen {...props}/>} />
</Switch>
</div>
</BrowserRouter>
)
}
}
export default route
Notice, <Route path ="/search?:id" above.
Unfortunately this didn't worked out.
I understand that <Route path ="/:id" works but how can i make <Route path ="/search?:id to work i.e how can I make some link like http://localhost:3000/search?9e9e to work
I think this is related with historyApiFallback. That parameter;
(https://webpack.js.org/configuration/dev-server/#devserver-historyapifallback)
When using the HTML5 History API, the index.html page will likely have to be served in place of any 404 responses. devServer.historyApiFallback is disabled by default. Enable it by passing:
module.exports = {
//...
devServer: {
historyApiFallback: true
}
};
Your react app is a single page application. So all path except home path actually is an virtual path, they are not physically exist. The paths must routed to home path. So react-router can manage.
you don't need to put the path like this /search?:id, just put it search
<Route path ="/search" exact render ={(props) => <SearchScreen {...props}/>} />
then inside your SearchScreen component, get the value of search parameter from the URL, check this issue will help.
after the user make search, pass the value like this /search?s=value_here

React Router structuring - passing functions

I'm quite new to reactjs and was just wondering if there is any easy way to display information from the same component to different routes. In the following code as an example I have just two functions that are just returning divs full of text, and calling them and rendering them right away (in the class or in the router) would just have them be on the same "page".
I've tried passing the ref by props but they always ended up undefined. I figured a state change would be awkward since there is no real "event". I'm using create-react-app, react-routerv4, and react-bootstrap.
In App.js
import React, { Component } from 'react';
import './App.css';
import NavBar from './Components/NavBar/NavBar.js';
import Band from './Components/Text/Band.js';
import { Router, BrowserRouter, Link, Route } from 'react-router-dom';
class App extends Component {
render() {
return(
<div>
<BrowserRouter>
<div className="RenderRouter">
<Route exact path='/' component={NavBar}/>
<Route exact path='/' component={ControlledCarousel}/>
<Route exact path='/' component={Home}/>
//<Route exact path='/Artists/ArtistX' component={Band}/>
<Route exact path='/Artists/Artist1' component={NavBar}/>
<Route exact path='/Artists/Artist1' render={props => <Band band1text = {this.props.band1text} />}/>
<Route exact path='/Artists/Artist2' component={NavBar}/>
<Route exact path='/Artists/Artist2' render={props => <Band band2text = {this.props.band2text} />}/>
</div>
</BrowserRouter>
</div>
);
}
}
export default App;
In Band.js
import React, { Component } from 'react';
import './Band.css';
class Band extends Component {
//Constructor for state change would go here
band1text(props) {
return(
<div id="band1Text" className="BandText">
<h1>"The best riffs!</h1>
</div>
);
};
band2text(props) {
return(
<div id="band2Text" className="BandText">
<p>More info coming soon! Check out the interview!</p>
</div>
);
};
//Create handlers to call functions, and pass reference?
render() {
return(
<div className="BandDescription">
//calling in DOM render object, can't pass props from here?
//{this.props.band1text()} = compiler error
{this.band1text()}
{this.band2text()}
</div>
);
}
}
export default Band;
It would probably be easier to just have separate components and classes for every piece of each route (i.e, BandX.js, CarouselX.js) but that could get verbose and one would have to import many files. I'm using react to build a music player component for the app as well, that's why I'm not just using standard JS.
Try writing something like this in your Band component render:
render() {
return(
<div className="BandDescription">
{this.props.band1text && this.band1text()}
{this.props.band2text && this.band2text()}
</div>
);
}
This way it checks for the prop before running whichever method. If both methods are passed, both functions will return. And you shouldn't need to pass props to those methods. Try writing them as arrow functions so they will be bound band1text = () => { ... }, you will still be able to access this.props.band1text from inside the method.
The props would be undefined because there is no props with bandText being passed down to App component. Routes are nested in App component and this.props.band1Text means you are expecting to read from props passed to App. Try passing band1Text and band2Text as props to App component.
Also to read a props that's not a function just use {this.props.band1Text} in the Band.js component

Get React router to cause a re-render

I have mixed content on my homepage. The user specific content is an edit button next to their own content.
When the user logs out via a logout route this code gets executed:
import React from 'react'; // needed
import ReactDOM from 'react-dom';
import Home from './components/layout/Home.js';
import Login from './Login/Login';
import PollDetails from './components/layout/PollDetails.js';
import EditPoll from './components/presentation/EditPoll.js';
import CreatePoll from './components/presentation/CreatePoll';
import Container from './components/containers/Container.js';
import {Route,Router,browserHistory,IndexRoute} from 'react-router';
import Auth from './utils/Auth';
const mountNode = document.getElementById('root');
ReactDOM.render(
<Router history={browserHistory}>
<Route path="/" component={Container} >
<IndexRoute component={Home} />
<Route path="login" component={Login} />
<Route path="logout" onEnter={(nextState, replace) => {
Auth.deauthenticateUser();
console.log('Logging out src/app.js');
Auth.clearCookie();
// change the current URL to /
replace('/');}} />
<Route path="Polldetailfull/:id" component={PollDetails} />
<Route path="Editthepoll/:id" component={EditPoll} />
<Route path="createPoll" getComponent={(location, callback) => {
if (Auth.isUserAuthenticated()) {
callback(null, CreatePoll);
} else {
callback(null, Home);
}
}} />
</Route>
</Router>,mountNode);
However, the replace('/'); sends you back to the home page but doesn’t re-render any components. Note there is no state to change here. Do I need a state to force the re-render?
Note, if you press refresh on the browser the desired behaviour happens. I tried looking on React Router's code but could not find much about events. To be honest, I don't fully understand onEnter={(nextState, replace) =>
You could use location.reload() to cause it to re-render
onEnter -> this function use when component going to render on browser.
For your idea, You need to use route the component based log details in component life cycle of particular components.below code to be use in path component life cycle(componentWillMount or componentDidMount) and route the page as want .
browserHistory.push('/location-path-name');
call the component based log details in router like below sample
<Route path="createPoll" component={Auth.isUserAuthenticated() ? CreatePoll : Home}/>

Categories