I have this below file saved as bbox.liquid.html in my public folder.
File : https://github.com/aws-samples/amazon-sagemaker-ground-truth-task-uis/blob/master/images/bounding-box.liquid.html
My goal is to either import the file as react component or redirect to the page and show it to user.
Method 1. import the file as react component
I tried this all answers, but its not working.
Method 2. redirect to the page
I tried to redirect it using router in app.js, after clicking it I see a empty page.
<Routes>
<Route exact path="/" element={<Home />} />
<Route path="/about" element={<About/>} />
<Route path="/bbox/" element={<Navigate to = {"/bbox.html"} replace />} />
</Routes>
[info] index.tsx:30 No routes matched location "/bbox.html"
Note: once after a reload it shows the expected page.
It would be great I get any working mechanism for method 1
I have installed "react-router-dom": "^6.0.0-beta.0" and created some page routes. Facing problems where the Page404 / NotFound component is not working if a page doesn't exist. For some reason when I am using dynamic page/post slug the component NotFound will not work if there is no page/post with this ID.
Is there an option inside React Router which solves this issue?
import { BrowserRouter as Router, Routes, Route } from "react-router-dom";
import AllPosts from "components/AllPosts";
import SinglePost from "components/SinglePost";
import NotFound from "components/Page404";
const App = () => (
<Router>
<Routes>
<Route element={<AllPosts />} path="/" exact />
<Route element={<SinglePost />} path="/:slug" />
<Route element={<NotFound />} path="*" />
</Routes>
</Router>
);
export default App;
The Routes and Route component can't possibly know ahead of time that some dynamic path, "/someUnsupportedIdValue" for example, isn't a valid path to be handled by SinglePost.
The options you have here are:
Conditionally render some alternative UI in SinglePost, something along the lines of "A page by this ID isn't found".
Check if a page with matching ID exists, conditionally render that page, or a redirect (Navigate component replaced Redirect in v6) to your more generic 404 page (actually, a redirect to any "throw away" path that isn't explicitly handled already will land you on your 404 page). Or you can imperatively redirect with a navigate(to, { replace: true }).
Try to remove exact because was removed from v6 and make sure Page404 is the correct component or create Notfound.jsx
Check if the post not exists then redirect to Notfound page.
I'm using React, React-router and Play Framework to serve and render an application.
This is what my Routes.jsx looks like:
const Routes = (
<Route path="/">
<Route component={App}>
<Route path="attributes/:itemId" component={AttributesContainer}/>
<IndexRoute component={ItemsContainer}/>
</Route>
</Route>
);
export default Routes
As you can see, path /attributes/:itemId renders a component called AttributesContainer.
This path is called from ItemsContainer in this function:
_onClickAttributes(itemId) {
browserHistory.push({pathname: '/attributes/' + itemId});
}
Everything works just fine there. But if I refresh the browser while in /attributes/:itemId, back-end returns
Action Not Found
For request 'GET /attributes/5'
instead of the front end component. I understand the browser is doing a get request and that's why I get this message.
So, what's the best technique to handle this?
Using this boilerplate as reference I created an Electron app. It uses webpack to bundle the scripts and express server to host it.
Webpack config is practically same as this and server this.
Electron's script loads:
mainWindow.loadURL('file://' + __dirname + '/app/index.html');
And index.html loads the script hosted by the server:
<script src="http://localhost:3000/dist/bundle.js"></script>
I run electron index.js to build the app and node server to start server which using webpack bundles the scripts.
It works fine, my React component App is mounted. But how I integrate react-router into this?
I implemented it the same way I would in a browser app. I get this error:
[react-router] Location "/Users/arjun/Documents/Github/electron-app/app/index.html" did not match any routes
It is taking file path as the route. Going through the boiler plate code did not help. What am I missing?
Had to Replace BrowserRouter with HashRouter.
import {
HashRouter,
Route
} from "react-router-dom";
And then in my index.js or the entry file of the Electron app I had something like this:
<HashRouter>
<div>
<Route path="/" exact component={ Home } />
<Route path="/firstPage" component={ FirstPage } />
<Route path="/secondPage" component={ SecondPage } />
</div>
</HashRouter>
And then everything just worked.
The reasoning: BrowserRouter is meant for request-based environments whereas HashRouter is meant for file-based environments.
Read more here:
https://github.com/ReactTraining/react-router/blob/master/packages/react-router-dom/docs/api/HashRouter.md
Another option would be to use hashHistory instead. Actually, in your referenced repo you can see that they're using hashHistory, how about trying that and posting back?
I'm using React Router v4 and didn't want to fallback to the HashRouter, so I solved it with something amongst the likes of:
import { Redirect, BrowserRouter } from 'react-router-dom';
const App = () => (
<BrowserRouter>
<div>
{window.location.pathname.includes('index.html') && <Redirect to="/" />}
</div>
</BrowserRouter>
);
Best option at the time of this answer is to use the MemoryRouter, worked for me :)
What about simply using Switch to default to "/" as follows:
<Switch>
<Route path="/" exact component={Home}/>
<Route path="/foo" component={Foo}/>
<Route path="/bar" component={Bar}/>
<Route render={() => <Redirect to="/"/>}/>
</Switch>
This way, "/index.html" will redirect to "/"
The (current) react-router docs say:
Generally speaking, you should use a <BrowserRouter> if you have a server that responds to requests and a <HashRouter> if you are using a static file server.
An Electron app is basically a static file server.
MemoryRouter can also work, so long as all routing originates from within the React part of the app. It only falls down when you want to navigate to a specific page from the Browser process, e.g. you want to pop up a new window and navigate directly to a "General Preferences" page. In that case, you can do this with HashRouter:
prefsWindow.loadURL(`file://${__dirname}/app/index.html#/general-prefs`);
I don't think there is a way to do that with MemoryRouter (from the Browser process).
Agree with Niekert.
But I believe it is better to handle like this before any route management.
if ( window.location.pathname.includes('index.html') ) {
location.pathname = ROUTES.ROOT;
}
It all depends on what kind of URL you pass to mainWindow.loadURL.
file://...
If you load index.html directly through the file:// protocol, such as
mainWindow.loadURL('file://' + path.join(__dirname, '../index.html#/home'))
then you need to use HashRouter:
<HashRouter>
<Routes>
<Route path='/home' element={<MyHomeScreen/>}>
</Routes>
</HashRouter>
Note that the # in index.html#/home is very important!
Why?
Think about what would happen if you wrote index.html/home. Your computer would try to retrieve a home file inside an index.html directory. The # prevents this, and thus we need to use HashRouter.
http://localhost:3000
If you load index.html from a server such as localhost:3000, then you have two options:
include the #, as in
mainWindow.loadURL('http://localhost:3000#/home')
and use HashRouter exactly as above,
OR
don't include the #, as in
mainWindow.loadURL('http://localhost:3000/home')
and use BrowserRouter like this:
<BrowserRouter>
<Routes>
<Route path='/home' element={<MyHomeScreen/>}>
</Routes>
</BrowserRouter>
Many people prefer to use BrowserRouter in this case because it avoids complicating the URL with a #.
In your main process:
mainWindow.loadURL(resolveHtmlPath('index.html'));
In your renderer process:
import { HashRouter as Router, Routes, Route } from 'react-router-dom';
//...
<Router>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/search" element={<Search />} />
<Route
path="/library"
element={<Library />}
/>
</Routes>
</Router>
The call to resolveHtmlPath removed the need for using hashtags for me. Using a BrowserRouter out of the box gave me the warning message in dev tools.
This function is in the Electron React Boilerplate project that you referenced:
import { URL } from 'url';
import path from 'path';
export function resolveHtmlPath(htmlFileName: string) {
if (process.env.NODE_ENV === 'development') {
const port = process.env.PORT || 1212;
const url = new URL(`http://localhost:${port}`);
url.pathname = htmlFileName;
return url.href;
}
return `file://${path.resolve(__dirname, '../renderer/', htmlFileName)}`;
}
My stack: Django app with React/react-router/flux frontend.
I'm managing some static pages (plus 404 page, etc) server-side, and want to configure my router to pass any undefined routes through to the server.
Here's how things are set up now:
let routes = (
<Route name="app" path="/" handler={ App }>
<Route name="register" handler={ Register }/>
<Route name="login" handler={ Login }/>
<Route name="refer" handler={ Refer }/>
<Route name="help" handler= { Help }/>
<Route name="list-property" handler= { ListProperty }/>
<DefaultRoute handler={ Home }/>
</Route>
);
router = Router.create({ routes, location });
router.run((Handler, state) => {
React.render(<Handler {...state} />, rootEl);
});
mysite.com/register will get routed through the react router to my Register page component, but I want mysite.com/thanks to hit my server (so django can manage the route). Right now I get a blank page.
I'm perusing the documentation here but can't find what I need: http://rackt.github.io/react-router/#NotFoundRoute
Maybe I'm overlooking something... thanks!
If you want certain paths to hit the server redirect to those paths using a standard anchor redirect or similar rather than use the Router.Link to navigate.