I receive error 404 on refreshing browser using React router in Laravel Mix
Asked Answered
M

6

6

I know there are several posts with similar questions but different approaches which do not seem understandable. I want to learn more and be able to develop several applications using React.js and Laravel.

Header.js: import files

import React, { Component } from 'react';
import {
    BrowserRouter as Router,
    Link,
    Switch,
    Route
} from 'react-router-dom';
import Home from './Home';
import About from './About';
import Dashboard from '../admins/Dashboard';
import Contact from './Contact';

The router (BrowserRouter)

<Router>
       <div>
            <nav className="navbar navbar-expand-lg  navbar-dark bg-dark navbar-fixed-top">
            <button className="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
                <span className="navbar-toggler-icon"></span>
            </button>

            <div className="collapse navbar-collapse" id="navbarSupportedContent">
                <ul className="navbar-nav mr-auto">
                    <li className="nav-item active">
                        <Link className="nav-link"  to="/" exact

                        >Home</Link>
                    </li>
                    <li className="nav-item">
                        <Link className="nav-link" to="/about">About Us</Link>
                    </li>

                    <li className="nav-item">
                        <Link className="nav-link" to="/contact">Contact</Link>
                    </li>
                </ul>
                <form className="form-inline my-2 my-lg-0">
                <input className="form-control mr-sm-2" type="search" placeholder="Search" aria-label="Search" />
                <button className="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button>
                </form>
            </div>
            </nav>
            <Switch>
                    <Route  exact path='/'  component={Home}/>
                    <Route  exact path="/about" component={About}/>
                    <Route  path='/contact' component={Contact}/>
                    <Route  path='/admins/dashboard' component={Dashboard}/>
            </Switch>
       </div>
       </Router>

When I click on the link, it displays the link but whenever I retry to refresh the page it displays error. I have tried possible example but nothing seems to be working. I don't know if I am doing it wrongly. I have been trying to see how to figure it out. I came across an article that says createBrowserHistory is deprecated and not supported on react-router v4, even I was struggling to implement the example. Is there a better away to handle this?

I have multiple pages (components).

Index.js

import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import {
    BrowserRouter as Router,

} from 'react-router-dom';
import Header from './Header';
import Footer from './Footer';



export default class Index extends Component {

    render() {
        return (
            <div>
                <Header />

                <Footer/>
            </div>
        );
    }
}

if (document.getElementById('app')) {
    ReactDOM.render(<Index />, document.getElementById('app'));
}

about.js

import React, { Component }from 'react';
import { Redirect } from 'react-router-dom';
class About extends Component {

    constructor(props)
    {
        super(props);
    }

    render(){
        return (
            <div className="jumbotron">
                <h2>About Us</h2>
            </div>
        );
    }
}



export default About;

app.js

/**
 * First we will load all of this project's JavaScript dependencies which
 * includes React and other helpers. It's a great starting point while
 * building robust, powerful web applications using React + Laravel.
 */

require('./bootstrap');

/**
 * Next, we will create a fresh React component instance and attach it to
 * the page. Then, you may begin adding components to this application
 * or customize the JavaScript scaffolding to fit your unique needs.
 */

require('./components/Index');

enter image description here

Modern answered 28/4, 2019 at 16:18 Comment(0)
I
9

For the knowledge sake, I think you are doing the whole thing wrong. Your index.js need to include import { BrowserRouter, Switch, Route } from 'react-router-dom' with your routes defined within the anchor tags of BrowswerRouter i.e. beneath the i.e.

import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter, Route, Switch } from 'react-router-dom'
import Header from './Header';
import Footer from './Footer';
import Home from './Home';
import About from './About';
import Dashboard from '../admins/Dashboard';
import Contact from './Contact';


    export default class Index extends Component {

        render() {
            return (
                <BrowserRouter>
                    <div>
                   <Header/>
                    <Switch>
                        <Route  exact path='/'  component={Home}/>
                        <Route  exact path='/about' component={About}/>
                        <Route  path='/contact' component={Contact}/>
                        <Route  path='/admins/dashboard' component={Dashboard}/>
                    </Switch>
                   <Footer/>
                </div>
                </BrowserRouter>

            );
        }
    }

    if (document.getElementById('app')) {
        ReactDOM.render(<Index />, document.getElementById('app'));
    }

Since this is a Laravel Mix, presetting reactjs, go to your web.php under your routes to change to Route::view('/{path?}', 'welcome'); which implies that you are restricting the view to a page but rendering several components from your view.

In your welcome.blade.php, ensure to avoid absolute paths, use something like this instead href="{{ asset('css/app.css') }}"

In your Header.js, remove unnecessary import files. import { Link } from 'react-router-dom';

If you are having any challenge understanding the arrangement, you can send your complete header.js, welcome.blade.php etc to help out

Imitate answered 1/5, 2019 at 18:54 Comment(1)
How this answer is accepted? It does not really answer to question.Refractometer
M
12

Set the basename attribute on the

<Router basename={'/directory-name'}>
    <Route path='/' component={Home} />
</Router>

Define Your laravel route like below

Route::view('/{path?}', 'welcome');
Mcintyre answered 3/4, 2020 at 15:31 Comment(1)
Thanks. It saved me.Kharif
I
9

For the knowledge sake, I think you are doing the whole thing wrong. Your index.js need to include import { BrowserRouter, Switch, Route } from 'react-router-dom' with your routes defined within the anchor tags of BrowswerRouter i.e. beneath the i.e.

import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter, Route, Switch } from 'react-router-dom'
import Header from './Header';
import Footer from './Footer';
import Home from './Home';
import About from './About';
import Dashboard from '../admins/Dashboard';
import Contact from './Contact';


    export default class Index extends Component {

        render() {
            return (
                <BrowserRouter>
                    <div>
                   <Header/>
                    <Switch>
                        <Route  exact path='/'  component={Home}/>
                        <Route  exact path='/about' component={About}/>
                        <Route  path='/contact' component={Contact}/>
                        <Route  path='/admins/dashboard' component={Dashboard}/>
                    </Switch>
                   <Footer/>
                </div>
                </BrowserRouter>

            );
        }
    }

    if (document.getElementById('app')) {
        ReactDOM.render(<Index />, document.getElementById('app'));
    }

Since this is a Laravel Mix, presetting reactjs, go to your web.php under your routes to change to Route::view('/{path?}', 'welcome'); which implies that you are restricting the view to a page but rendering several components from your view.

In your welcome.blade.php, ensure to avoid absolute paths, use something like this instead href="{{ asset('css/app.css') }}"

In your Header.js, remove unnecessary import files. import { Link } from 'react-router-dom';

If you are having any challenge understanding the arrangement, you can send your complete header.js, welcome.blade.php etc to help out

Imitate answered 1/5, 2019 at 18:54 Comment(1)
How this answer is accepted? It does not really answer to question.Refractometer
A
4

This way saved my day!

Route::view('{path}', 'Home')->where('path', '([A-z\d\-\/_.]+)?');
Arlenaarlene answered 16/6, 2021 at 16:36 Comment(1)
Please avoid the impression of saying "Thanks" for an existing answer.Salespeople
I
1

This helped me:

in your routes/web.php

Route::get("{path?}", "WebControllers\HomeController@index")->where('path', '.+');

Intensive answered 25/12, 2020 at 5:33 Comment(0)
E
1

if you use react with Laravel then you can use this on the Laravel web.php[router file]

Route::view('/{path?}', 'welcome');

Estellestella answered 6/8, 2021 at 11:6 Comment(1)
This works because there is an actual HTTP request sent to the server, so it loads the index.blade.php or welcome.blade.php or any other file. The server then returns the basic HTML page content along with the JS code and the requested path, which the react-router takes on and renders the appropriate page.Sal
M
1

Just parse a parameter like following way in your back-end route inside 'api.php' or 'web.php' whatever you are using.

Route::get('/{slag?}', function () {
     return view('index'); 
});
Multipartite answered 31/8, 2022 at 12:59 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.