I am building a React-based website, started with create-react-app and using react-router-dom`. This is my structure:
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import registerServiceWorker from './registerServiceWorker';
ReactDOM.render(<App />, document.getElementById('root'));
registerServiceWorker();
App.js
import React, { Component } from 'react';
import { BrowserRouter, Route } from 'react-router-dom';
import { createStore } from 'redux';
import { Provider } from 'react-redux';
import reducers from './reducers';
import Menu from './components/Menu';
import Blog from './components/Blog';
import Books from './components/Books';
import Contact from './components/Contact';
import Curriculum from './components/Curriculum';
import Lectures from './components/Lectures';
import MainPage from './components/MainPage';
import Mathematics from './components/Mathematics';
import SocialNetworks from './components/SocialNetworks';
import Software from './components/Software';
export default class App extends Component {
render() {
return (
<Provider store={createStore(reducers)}>
<div className="contents">
<div className="banner-top shadowed-text">
<div className="my-name">
Ed de Almeida
</div>
<div className="my-professions">
Mathematician, Software Developer, Writer and Lecturer
</div>
<SocialNetworks />
</div>
<Menu />
<div className="page-area">
<BrowserRouter>
<div className="top-margin-area">
<Route exact path="/" component={MainPage} />
<Route path="/curriculum" component={Curriculum} />
<Route path="/math" component={Mathematics} />
<Route path="/software" component={Software} />
<Route path="/blog" component={Blog} />
<Route path="/books" component={Books} />
<Route path="/lectures" component={Lectures} />
<Route path="/contact" component={Contact} />
</div>
</BrowserRouter>
</div>
</div>
</Provider>
);
}
};
When I run it in my local server it works perfectly well. I may navigate to all URLs defined in the routes and I see exactly what is is expected.
The trouble starts when I do my git push heroku master. Although it builds perfectly at Heroku, with no error messages, I may only open the homepage ("/"). If I navigate to "/curriculum", for example, I get a 404 Not Found error message.
Important:
This is the Heroku URL: http://eddealmeida.herokuapp.com/
I am relatively new to React and this is my first time hosting React at Heroku. I created my Heroku app using this buildpack here.
Am I missing something?
Oh, before I forget... When I run locally using heroku local it also works perfectly well. It is only there at Heroku which things go wrong!
Based on the documentation of the buildpack you are using, you’ll need to configure the Heroku app for routing by creating a static.json file:
React Router (not included) may easily use hash-based URLs like https://example.com/index.html#/users/me/edit. This is nice & easy when getting started with local development, but for a public app you probably want real URLs like https://example.com/users/me/edit.
Create a static.json file to configure the web server for clean browserHistory with React Router v3 & BrowserRouter with v4:
{
"root": "build/",
"routes": {
"/**": "index.html"
}
}
Related
I've successfully deployed my react app on digital ocean as a static site. But when I click to see the live app the link only shows me a blank page, instead of show me the landing page (dashboard).
The command I used for the build
npm build
The code in my index.js file
import React from "react";
import ReactDOM from "react-dom";
import { createBrowserHistory } from "history";
import { Router, Route, Switch, Redirect } from "react-router-dom";
// core components
import Admin from "layouts/Admin.js";
import RTL from "layouts/RTL.js";
import "assets/css/material-dashboard-react.css?v=1.9.0";
import 'bootstrap/dist/css/bootstrap.min.css';
const hist = createBrowserHistory();
ReactDOM.render(
<Router history={hist}>
<Switch>
<Route path="/admin" component={Admin} />
<Route path="/rtl" component={RTL} />
<Redirect from="/" to="/admin/dashboard" />
</Switch>
</Router>,
document.getElementById("root")
);
my project structure
[1]: https://i.stack.imgur.com/JL2Yi.png
I found the solution. I just had to edit the package.json file and change the homepage attribute like this:
"homepage": ""
My backend is in django. I can get post data from there and also post list.
In reactjs, I am just displaying post details and lists (and some more details related to posts...)
In reactjs my index.js file is as below
import ReactDOM from "react-dom";
import App from "./App";
import * as serviceWorker from "./serviceWorker";
import React from "react";
import { BrowserRouter } from "react-router-dom";
import { GoogleReCaptchaProvider } from "react-google-recaptcha-v3";
ReactDOM.render(
<BrowserRouter>
<App />
</BrowserRouter>,
document.getElementById("root"),
);
serviceWorker.unregister();
My app.js file is as below
import React from "react";
import { Route, Switch } from "react-router-dom";
import HomePage from "./pages/HomePage";
import BlogPage from "./pages/BlogPage";
import "./css/styles.css";
import CategoryPostsPage from "./pages/CategoryPostsPage";
import SearchPage from "./pages/SearchPage";
import ContactPage from "./pages/ContactPage";
function App() {
return (
<main>
<Switch>
<Route path="/post/:slug/" component={BlogPage} />
<Route
path="/category/:slug/"
component={CategoryPostsPage}
/>
<Route
path="/query/:query/"
component={SearchPage}
/>
<Route path="/contact/" component={ContactPage} />
<Route path="/" component={HomePage} />
</Switch>
</main>
);
}
export default App;
I add new posts from backend (django admin panel).
And through API, react app gets data from backend.
I want to have all urls like
/post/some-slug
/post/some-slug-2
...
/
/contact/
...
This is for SEO purpose, When I search, it displays only homepage url and contact page url, not a single url for any post...
Please suggest, what should I do,
I have tried sitemap packages from npm, but doesn't seem working...
first of all i'd like to say that i'm a new developer of React and NodeJS.
I want use this technologies:
- React as a client
- NodeJS as a server
- Webpack for build my files.
My project structure is the follow:
my-application/
webpack.server.js
webpack.client.js
server.js
client/client.js
client/app.js
client/components/header.js
client/components/mainLayout.js
client/components/footer.js
The header and footer files are not important so i'm not writing here.
The important file are the following:
mainLayout.js
import React, { Component } from 'react';
// import component
import Header from './header';
import Footer from './footer';
class MainLayout extends React.Component {
constructor (props) {
super(props)
}
render() {
return (
<div className="App">
<Header />
{this.props.children}
<Footer />
</div>
);
}
}
export default MainLayout;
app.js
import React, { Fragment } from 'react';
import { Route, Switch } from 'react-router-dom';
import MainLayout from './components/mainLayout'
const AppComponent = () =>
<Switch>
<Route path="/" exact render={props => (
<MainLayout>
<h1>Hello World</h1>
</MainLayout>
)} />
</Switch>
;
export default AppComponent;
client.js
import 'babel-polyfill';
import React from 'react';
import ReactDOM from 'react-dom';
import {BrowserRouter} from 'react-router-dom';
import AppComponent from './app';
ReactDOM.hydrate(
<BrowserRouter>
<AppComponent />
</BrowserRouter>,
document.querySelector('#root')
);
server.js
import express from 'express';
import React from 'react';
import AppComponent from './client/app'
var app = express();
const PORT = 3000;
app.use("/", express.static("build/public"));
app.get("/", (req, res) => {
res.send(<AppComponent />)
});
app.listen(PORT, () => console.log('Now browse to localhost:3000'));
Run my project:
npm run build
npm run dev
but when i'm going at http://localhost:3000 my page response is
{"key":null,"ref":null,"props":{},"_owner":null,"_store":{}}.
I don't understand why i have the error, something probably escapes me but i don't what.
Can you help me please?
Thanks you in advance,
AS
You are running both front and back end on the same port. Go to package.json for your react app and replace your start script with the following script:
"scripts": {
"start": "set PORT=3007 && react-scripts start",
// the rest of your scripts
}
This will be the first step for resolving your issue. If you keep getting errors after that, let us know what are they.
I ran the application again using npm.
In the command I entered: npm start in the application folder after this it worked again.
In App.js, add Routes in the import. Use element instead of component.
For Example:
import {BrowserRouter, Routes, Route, Link, Switch} from 'react-router-dom'
<Navbar />
<BrowserRouter>
<Routes>
<Route path="/" exact element = {</>}/>
<Route path="/" exact element = {</>}/>
</Routes>
</BrowserRouter>
This can be from the browser you are using.
Copy the local host address on your address bar and paste on a different browser, Chrome recommended.
This is based on personal experience. It kept rolling on Opera browser until I opened it on Chrome.
I am attempting to serve a react app from the public folder of my rails app. I am building the js file and putting it in the public folder. When I go to the root of the app, I can see that the js and my index.html page have loaded. However, when I try to go to page, like /landing, I get a 404, route not found from Rails. I can't figure out why the react router is not kicking in. This all works on dev where I am serving the react app with a second server, I only get this issue in production. Any suggestions?
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import './index.scss';
ReactDOM.render(<App />, document.getElementById('root'));
App.js
import React from 'react';
import Auth from './util/auth';
import { Redirect, BrowserRouter as Router, Switch, Route } from 'react-router-dom';
import MyAccount from './components/my_account';
import MyListings from './components/my_listings';
import LoginPage from './components/login_page';
import LandingPage from './components/landing_page';
import RegistrationForm from './components/registration_form';
import PasswordResetForm from './components/password_reset_form';
import RequestPasswordResetForm from './components/request_password_reset_form';
import {FlashMessages} from './components/flash_messages';
import $ from 'jquery';
import popper from 'popper.js';
import './stylesheets/App.css';
window.Popper = popper;
window.jQuery = $;
window.$ = $;
global.jQuery = $;
require('bootstrap');
const App = appProps => (
<div>
<div id="flash-messages">
<FlashMessages />
</div>
<Router>
<div className="App">
<Switch>
<Route exact name="index" path="/landing" component={LandingPage} />
<Route exact name="login" path="/login" component={LoginPage} />
<Route exact name="register" path="/register" component={RegistrationForm} />
<Route exact name="reset_password" path="/reset_password" component={PasswordResetForm} />
<Route exact name="reset_password_request" path="/reset_password_request" component={RequestPasswordResetForm} />
<PrivateRoute path="/my_account" component={MyAccount}/>
<PrivateRoute path="/my_listings" component={MyListings}/>
</Switch>
</div>
</Router>
</div>
);
const PrivateRoute = ({ component: Component, ...rest }) => (
<Route {...rest} render={props => (
Auth.isAuthenticated() ? (
<Component {...props}/>
) : (
<Redirect to={{
pathname: '/login',
state: { from: props.location }
}}/>
)
)}/>
)
export default App;
A typical gotcha with React Router is that you need to return the same index.html page for all routes - be it /, /landing-page/ or /a/really/deep/route/.
You typically solve that by adding a catch-all route. I don't know rails all that well, but I think this answer might help you out.
The problem is that all routes handled first by rails and he redirects you to the page where your react routers are. And you have only one HTML page that contains your react.js code.
When you go to /login or any other page you get err 404 because you don't have a route in rails to handle it.
You need to add rails routes for all your pages and redirect them to the same index page
Or do a catch all routes to the same index page
There's some documentation for configuring your server. Basically you always need to return index.html with a 200 status code.
https://github.com/ReactTraining/react-router/blob/v3/docs/guides/Histories.md#configuring-your-server
I've installed react router and I'm trying to get the main page to render.
This is the current index.js
import React, { Component, PropTypes } from 'react';
import { Router, Route } from 'react-router';
import Layout from './components/Layout';
import NewsComponent from './components/NewsComponent';
<Router>
<div>
<Route exact path="/" component={Layout} />
<Route path="/news" component={NewsComponent} />
</div>
</Router>
const app = document.getElementById('app')
ReactDOM.render(
<Router history={hashHistory}>
<Route path="/" component={Layout} />
</Router>, app);
The Layout component contains the layout of the page.
What I'm I missing?
I'm I doing this wrong?
There are some references you are missing, I dont know if you have omitted them just for this example or you are really missing them. Try this:
import React from 'react';
import ReactDOM from 'react-dom'; //Missing in your example
import {
Router,
Route,
browserHistory //Missing in your example
} from 'react-router';
import Layout from './components/Layout';
ReactDOM.render(
<Router history={browserHistory}>
<Route path="/" component={Layout} />
</Router>,
document.getElementById('root')
)
Then in your component you can even navigate through history:
import { hashHistory } from 'react-router'
//Dont forget to bind this in the constructor
yourMethod (someParams) {
hashHistory.push(someUrl)
}
Try explicitly importing ReactDOM (import ReactDOM from 'react-dom'); it isn't automatically included when you import React.
In addition to modifying your code [missing imports, etc.], you'd want to specifically mention the version of the react-router you are using. Assuming that you are using NPM
Try:
npm remove react-router
Then:
npm install --save react-router#3.0.0
React-router V4, which is installed by default, is a complete re-envisioning of the react-router and is not compatible with the codes written for the previous versions of react-router.
If you haven't used React in a while, I suggest you use create-react-app. Starting from there will be quite straightforward:
https://github.com/facebookincubator/create-react-app