How to use a generated page from Gatsby as a homepage? - node.js

I am having a page template, which creates multiple pages. One of them is my homepage and it has a slug "home". How can I set it to be the default page when I visit the site - example.com
Bonus: how to make it so when I visit example.com/home to redirect me to example.com

Gatsby integrates well with #reach/router. A Router redirect allows redirecting to any other route, no matter where it comes from. Apply it on src/pages/index.js
import React from "react"
import { Router, Redirect } from "#reach/router"
const IndexPage = () => (
<React.Fragment>
<Router>
<Redirect noThrow
from="/"
to="/whateverYourFrontpagesRouteIs"
/>
</Router>
</React.Fragment>
)
export default IndexPage
This also a valid answer to your bonus question.

Related

Serving react over static server without having people running into 404

I have a react site serving over: https://aero.mysite.com/profile, and I use router and history.push/replace in my react app, making it possible to have pathname such as https://aero.mysite.com/profile/path?query=number. However, say if someone copy and paste this url to another person, he or she would get 404 because https://aero.mysite.com/profile/path doesn't actually exist over the static server... (I am using koa + file serving middleware I made). What are the solutions to this challenge?
If you are using BrowserRouter or something similar, replace it with hash router which adds a "#" between the web server path and frontend route
Browser router looks like this
http://example.com/about
while the hash router looks like this
http://example.com/#/about
This will prevent the UI routing from being processed by the web server
For more info read this article
import { HashRouter as Router, Route } from 'react-router-dom';
import App from './components/App';
import Home from './components/Home';
import About from './components/About';
import Services from './components/Services';
render((
<Router>
<div>
<Route exact path="/" component={Home} />
<Route path="/about" component={About} />
<Route path="/courses" component={Services} />
</div>
</Router>
), document.getElementById('root'));

How does serving different pages in React works?

Let's say I have a react projects, and an Express server for serving my project, as follows(After building the project):
]
This way, only the index.html is served, isn't it? If the user routes to a different page, how is that page sent to him?
Routing in javascript is managed by using HTML5 push state. So every time you click a link and go to another route, the browser history and push state is being used. That's the basis for routing in almost of all the single page applications.
Until and unless you refresh the page, your request doesn't go to the server. Hence, index.html is served only once and after that the router (here the react-router) takes over and manages the routing in url using the history API of the browser.
Hope this helps !
That is done using react-router which manages the routing using the browser's History API.
This style of a website is called a single page application as opposed to a multi page application where the server sends different pages depending on the url you route to.
you can use react-router-dom like this
<Switch>
<Route exact path="/" component={Home}/>
<Route path="/someurl" component={ComponentForSomeUrl}
</Switch>
and render it with BrowserRouter
but you can use something like history.push, in my opinion react-router-dom is really simple and better than react-router
you don't need to send html file to specific route, in case of react express is used for building API (in most cases)
In you React folder you want to do npm install --save react-router-dom.
So inside the React Router family of libraries, there is a couple of different dependencies you can possibly install.
Ensure you never install React Router by itself.
The react-router library as it is published on npm is the core library of everything inside the React Router general project.
So react-router has some core navigational logic inside of it. It decides how to work with React, how to change content out depending on different rules and some other low-level logic.
To gain some actual implementation as it works specifically in the browser, install react-router-dom.
So anytime you want to use React Router on a project to handle navigation, always install react-router-dom, not react-router.
There are other similarly named projects that you might think you need as well, react-router-native for use inside of React Native projects.
In web applications we make use of react-router-dom, we are not making native mobile apps.
React-router-native is for native mobile applications only.
For the browser you always want react-router-dom as opposed to react-router-native
So perhaps in your App.js component you want to set something up that looks like this:
import React from "react";
import { BrowserRouter, Route } from “react-router-dom”;
const App = () => {
return <div>App</div>;
};
export default App;
I also recommend if you are new to React Router to get familiar with it by setting up something temporary like so:
import React from "react";
import { BrowserRouter, Route } from “react-router-dom”;
const PageOne = () => {
return <div>PageOne</div>;
};
const PageTwo = () => {
return <div>PageTwo<button>Click Me</button></div>;
};
const App = () => {
return (
<div>
<BrowserRouter>
<div>
<Route path=“/” exact component={PageOne} />
<Route path=“/pagetwo” component={PageTwo} />
</div>
</BrowserRouter>
</div>
);
};
Visit your localhost:3000 and then your localhost:3000/pagetwo, check out how all that is working.
When we visit a page called localhost:3000 and we type that address into the url it loads up the application.
React Router itself does not care about that entire url, instead React Router only cares about all the characters that are listed after the domain name or port definition.
Localhost:3000 is interpreted as being localhost:3000/
If I go to localhost:3000/ it still loads up my application.
Now I have other examples here if I go to localhost:3000/pageone, React Router only cares about everything after the port and domain
Same thing if I went to airbnb.com/listings/spain react router would only consider /listings/spain when deciding what content to render to the screen.
Notice in the example above I created an instance of BrowserRouter, well BrowserRouter creates an object of its own known as the history object.
This history object is going to look at the URL inside the address bar and extract just that portion of the URL that react router cares about.
The history object is then going to communicate that path over to BrowserRouter who communicates that path to both Route components and those Route components decide whether to show themselves or hide themselves depending on the path that the user is visiting and the path property that it was passed when it was created.

React routing with express is working on page refresh

My project using express for server and React for frontEnd. Routes are like this
<Router >
<Switch>
<Route exact path="/" component={HomeContainer} />
<Route path="/women" component={SectionContainer} />
</Switch>
</Router>
To serve these routes my server js has
server.get('*', function(request, response) {
response.sendFile(path.resolve(__dirname, '../public', 'index.html'));
});
Page url http://localhost:3000/women is working only on page refresh, first time click on url is just changing the browser url with no page update. But on page refresh it is working perfectly fine.
Please suggest what i am missing.
I was having similar issue. I found HashRouter helpful than the BrowserRouter:
import { HashRouter as Router } from 'react-router-dom'
Using HasRouter will be working fine as it keeps state on every history data changes.

react + routing + security

I am building a web application with React and react-router and I would like to protect some routes of my React application with an existing external access management infrastructure (OpenAM).
I would like to protect the http://web.example.com:8080/myapp/#/user-profile url which means that only logged users can have access to this route.
I have some other routes which are public and any user can open them, for example http://web.example.com:8080/myapp/#/welcome.
The Access Management protects urls and if a user wants to open a protected url then a login form is shown by Access Management and after a successful login the original requested url will be displayed.
The problem here is that react-router adds the routing info after the '#' character and the above mentioned two different urls are same from the access manager point of view because they refer to the same web resource (/myapp). The different between these two urls appear after the '#' character.
I need to have real urls without '#' chars like this:
http://web.example.com:8080/myapp/user-profile
http://web.example.com:8080/myapp/welcome
Is there any way to use real url mappings with React?
Do you guys have any idea or workaround how to use real url routes with react?
Thanks.
UPDATE:
This is my code. The urls in the web browser look nice but I get a "about did not match any routes" error. Requested url: http://web.example.com:8080/myapp/about
import {Router, Route, IndexRoute, useRouterHistory} from 'react-router';
import {createHistory} from 'history';
const browserHistory = useRouterHistory(createHistory) ({
basename: '/myapp/'
});
ReactDOM.render(
<Router history={browserHistory}>
<Route path="/" component={MainLayout}>
<IndexRoute component={Home} />
<Route path="about" component={About} />
</Route>
</Router>
)
You could use browserHistory, as suggested in the comments, to get rid of the #-sign. If you want the root of your react-application to be /myapp/ instead of / you can try:
import {Router, Route, useRouterHistory} from 'react-router';
import {createHistory} from 'history';
const browserHistory = useRouterHistory(createHistory)({basename: '/myapp/'});
ReactDOM.render(
<Router history={browserHistory}>
...
</Router>
)

Login/out react routing and expressjs routing

What im trying to do is Have a Log In page, a Sign up page. The login and signup work fine, they just perform whatever was written in express using passport. However what I want to do is make a route '/dashboard'. I did so and it's just a dashboard component made up of other components like a navbar and body/content. How do I write it in react router in such a way that it only allows me to access the route /dashboard if the user is authenticated. In express I would write a function like this :
function isLoggedIn(req, res, next) {
//if user is authenticated in the session, carry on
if (req.isAuthenticated())
return next(); //cuz we want to move on incase we're stuck here
//if they arent redirect them to the home page
res.redirect('/');
}
However I didn't even write in the dashboard route in express. I only did it in react-router. My component hierarchy is like this right now
<App/>
<Dashboard/>
<NavBar/>
<NavMenu/>
<Body/>
<Login/>
<Signup/>
<About/>
And my routing is like this :
<Route>
<Route name ="signup" path="/signup" handler={Signup} />
<Route name ="login" path="/" handler={Login} />
<Route name ="app" path="/dashboard" handler={App} >
<Route name ="logout" path="/logout" handler={NavMenu} />
</Route>
</Route>
I don't understand if i'm grasping the concept right, but from what the webpage is displaying it doesn't seem like it. So basically at localhost:3000/ comes up the log in page, and I can toggle between that and the signup page completely fine, when the log in button is hit it uses express to login (it can use react-router to do it as well correct?), on success it goes to /dashboard (res.redirect('/dashboard') in express). It also seems as routes handled by react router has that single page app feel, whereas express it feels like i'm going to a new webpage (I'm guessing that happens because of react-router just changing the url and rendering the component we want?). In my NavMenu component I link the logout button Logout however the url changes to localhost:3000/logout and nothing happens.
I nested it under login so to get to dashboard and it's routehandler it has to go through the login.
<Login>
<App>
<RouteHandler>
<dashboard../>
<data../>
<etc../>

Resources