Routing doesn't work in react when typing url in browser

10,146

Solution 1

Your server needs to deliver your app no matter what URL comes in, because your app, in the browser, is manipulating the URL. Our current server doesn't know how to handle the URL.

The Webpack Dev Server has an option to enable this. Open up package.json and add --history-api-fallback.

"start": "webpack-dev-server --inline --content-base . --history-api-fallback"

We also need to change our relative paths to absolute paths in index.html since the URLs will be at deep paths and the app, if it starts at a deep path, won't be able to find the files.

<!-- index.html -->
<!-- index.css -> /index.css -->
<link rel="stylesheet" href="/index.css">

<!-- bundle.js -> /bundle.js -->
<script src="/bundle.js"></script>

Configuring Your Server

As well you can also configure Webpack server inside webpack.config.js

 devServer: {
    historyApiFallback: true,
    contentBase: './',
    hot: true
  },

Try to use HashRouter from React Router Dom

import { HashRouter, Route } from "react-router-dom";



             <HashRouter>                          
                    <Route path="/login" component={LoginPage} />
                    <Route path="/administrate" component={AdministratePage} />     
                    <Route exact path='/' component={LoginPage} />  
             </HashRouter>

Solution 2

Wrapping your App under BrowserRouter in the index.js is missing as stated here.

index.js

 import { store } from './_helpers';
    import { App } from './App';
    import { BrowserRouter } from "react-router-dom";

    render(
        <Provider store={store}>
          <BrowserRouter>
            <App />
          </BrowserRouter>
        </Provider>,
        document.getElementById('root')
    ); 

A fully working example should be like this.

App.js

import React, { Component } from 'react';
import { Switch, Route } from 'react-router-dom';
import Login from '../../Components/Login/Login';
import Signup from '../../Components/Signup/Signup';
import classes from './Home.css';
import HomePage from '../HomePage/HomePage';


class Home extends Component {

    render() {
    return (
        <div className={classes.Container}>
          <Switch>
            <Route path="/" exact component={HomePage} />
            <Route path="/login" component={Login} />
            <Route path="/signup" component={Signup} />
          </Switch>
        </div>

    );
  }
}
Share:
10,146

Related videos on Youtube

Ole EH Dufour
Author by

Ole EH Dufour

An accomplishment-oriented, result-focused, Dutch, self-directed, web-savvy, hands-on, target-driven and Paris based freelance .Net developer.

Updated on June 21, 2022

Comments

  • Ole EH Dufour
    Ole EH Dufour almost 2 years

    I have the following routes in the below class:

    import { Router, Route } from 'react-router-dom';
    
    class App extends React.Component {
        constructor(props) {
            super(props); 
        }
    
        render() {
            const { alert } = this.props;
    
            return (
                <Router history={history}>
                    <div>                                  
                        <Route path="/login" component={LoginPage} />
                        <Route path="/administrate" component={AdministratePage} />     
                        <Route exact path='/' component={LoginPage} />   
                    </div>
                </Router>
            );
        }
    }
    

    For http://localhost:12345/ the login component displays properly.

    However when I'm typing in my browser http://localhost:12345/login or http://localhost:12345/administrate I'm getting 404's.

    Typing 'http://localhost:12345/administrate' in the navigator gives a 404 but If I put :

    this.props.history.push('/administrate');
    

    in the render method of the Login component it redirects properly, showing the administrate component.

    How come? I have no errors in my F12 console. Thank you very much.

    My webpack.config.js:

       module.exports = {
       devServer: {
            historyApiFallback: true
        },
            context: __dirname,
            entry: "./index.js",
            output: {
                path: __dirname + "/dist",
                filename: "bundle.js" // naam van de file die je genereert. die bundle.js include je in je cshtml. Wordt voortdurend geupdate als je programmeert
            },
            resolve: {
                extensions: ['.js', '.jsx']
            },
    
            watch: true, // dan hoef je niet telkens npm run webpack te draaien, je ziet dan in je cmd 'webpack is watching the files'
            module: {
                rules: [
                    {
                        test: /\.js$/,
                        exclude: /(node_modules)/,
                        use: {
                            loader: 'babel-loader',
                            options: {
                                presets: ['babel-preset-env', 'babel-preset-react'], // deze heb je met npm geinstalleerd
                                plugins: ["transform-object-rest-spread"] // voor het gebruik van de spread operator
                            }
                        }
                    },
                    {
                        test: /\.css$/,
                        use: ['style-loader', 'css-loader']
                    },
                    {             // Werkt niet
                        test: /\.jsx$/, loader: 'babel-loader', exclude: '/node_modules/'
                    }
                ]
            }
        };
    

    index.js :

    import { store } from './_helpers';
    import { App } from './App';
    
    render(
        <Provider store={store}>
            <App />
        </Provider>,
        document.getElementById('root')
    ); 
    

    History:

    import { History } from './index'; // history 4.6.2
    import { getConfirmation } from './DOMUtils';
    
    export interface BrowserHistoryBuildOptions {
      basename?: string;
      forceRefresh?: boolean;
      getUserConfirmation?: typeof getConfirmation;
      keyLength?: number;
    }
    
    export default function createBrowserHistory(options?: BrowserHistoryBuildOptions): History;
    
    • Liam
      Liam about 6 years
      Try to import BrowserRouter as Router import { BrowserRouter as Router, Route } from "react-router-dom";
  • Juan Camilo Giraldo Chaverra
    Juan Camilo Giraldo Chaverra about 6 years
    @OleEHDufour can you try again removing the Router wrapping over App.js I edited the response with a working example for you to try
  • Ole EH Dufour
    Ole EH Dufour about 6 years
    I did. Still 404's when I type the url in the navigation bar.BTW you index.js is duplicate