44

I need to use React Router with a Laravel project.

But when I create a router on the React Router and try access, Laravel produces a "Route not exist" error.

How can I use React Router to manage Laravel project routes?

render((
    <Router history={browserHistory}>
        <Route path="/" component={App}/>
        <Route path="/profile" component={Profile}/> // this route I trying access
    </Router>
), document.getElementById('root'));

6 Answers 6

49

Create a route that maps everything to one controller, like so:

Route::get('/{path?}', [
    'uses' => 'ReactController@show',
    'as' => 'react',
    'where' => ['path' => '.*']
]);

Then in your controller, just show the HTML page that contains the react root document:

class ReactController extends Controller {
    public function show () {
        return view('react');
    }
}

Then do everything as normal with react router. Seems to work well for me.


Update for Laravel 5.5 If your controller only returns a view (like in the example above), you can replace all of the above code with this in your routes file:

Route::view('/{path?}', 'path.to.view')
     ->where('path', '.*')
     ->name('react');
Sign up to request clarification or add additional context in comments.

10 Comments

I thought it has something to do with laracasts.com/discuss/channels/javascript/…
For React-router v4 you can use the /somePath/{path?} and then in your React: <BrowserRouter basename="somePath"> This will enable you to have dynamically routed paths in react, but also directly link-able sub-paths.
how I can able to detect a path that doesn't exists ?
@Mr.Pyramid the {path?} part means it will match any URL. If you put that at the bottom of your routes file, anything that isn't matched to a previously defined URL will be matched at this one.
@JakeTaylor With this approach if you hit /bar/url, it would first be handle by Laravel, then React-router and show its respective component?
|
21

Based on Jake Taylor answer (which is correct, by the way) : it has a little mistake, is missing a quotation mark after '/{path?}' , just the last one.

Also, if you don't need to use a Controller and just redirect back to your view, you can use it like this:

Route::get( '/{path?}', function(){
    return view( 'view' );
} )->where('path', '.*');

Note: Just make sure to add this Route at the end of all of your routes in the routes file ( web.php for Laravel 5.4 ), so every existing valid route you have may be catched before reaching this last one.

1 Comment

Thanks! This works but I get a console error: DevTools failed to parse SourceMap: http://laravelreact.test/js/bootstrap.js.map
19

This seems works for me

For any react routes

Route::get('{reactRoutes}', function () {
    return view('welcome'); // your start view
})->where('reactRoutes', '^((?!api).)*$'); // except 'api' word

For laravel routes

Route::get('api/whatever/1', function() {
    return [
        'one' => 'two',
        'first' => 'second'
    ];
});

Route::get('api/something/2', function() {
    return [
        'hello' => 'good bye',
        'dog' => 'cat'
    ];
});

1 Comment

In order to get the above to work in api.php I had to remove api/ from the route::get. Laravel already includes it in api.php but not in web.php. Hope that makes sense.
12

EDIT in Feb 2022: I posted this solution when the latest Laravel was V5 and react-router was V4. There could be a better solution now, because both Laravel and react-router evolved a lot since then

==================================================

How about using <HashRouter>?

E.g.

import React from 'react';
import {
    HashRouter,
    Route,
    Link
}from 'react-router-dom';
import Profile from './Profile';

export default class App extends React.Component {
    constructor(props) {
        super(props);
    }

    render() {
        return (
            <HashRouter>
                <Link to="/profile" replace>Profile</Link>
                <Route path="/profile" component={Profile}/>
            </HashRouter>
        );
    }
}

In Laravel's router...

Route::get('/', function(){
    return view('index'); //This view is supposed to have the react app above
});

With HashRouter, your client side routing is done with # (Fragment Identifier), which is not read by Laravel's routing (i.e. server side routing)

Upon arriving this page, the URL is /.

Clicking the link will make the URL /#/profile and the component will appear.

After that, if you refresh the page, you wont' see the Route not exist error. This is because, from Laravel's perspective, the URL is still /. (The component Profile still remains there.)

https://reacttraining.com/react-router/web/api/HashRouter

Hope my explanation is clear.

4 Comments

But it's ugly as sin :(
@imperium2335 but it is much better than hitting the backend to return the same static view over and over again like all the other answers here.
@Julian The server side isn't called on every page change from react-router. A fresh load will hit the server which will return the static view, then any routing/url changes from there on is entirely client side.
Ugly indeed. However, I haven't been able to make it work by any other mean. Working will Laravel 8. Thanks.
4

You can return your index page and browserHistory of React will handle anything else.

Route::pattern('path', '[a-zA-Z0-9-/]+');
Route::any( '{path}', function( $page ){   
     return view('index');
});

Comments

0

Simple and organized Way to handle route in react with laravel:

Component file (CreateProduct.tsx):


import React from 'react';
import { Link } from '@inertiajs/react';

const CreateProduct = () => {
  return (
    <div>
      <h1>Create Product Page</h1>
      <Link href="/create">
        <button>Create New Product</button>
      </Link>
    </div>
  );
};

export default CreateProduct;

In web.php, set up a route:

use App\Http\Controllers\CreateProductController;

Route::get('/create',[CreateProduct::class, 'create'])->name('create');

Controller File (CreateProductController.php):

use Inertia\Inertia;

class CreateProductController extends Controller
{
    public function create()
    {
        return Inertia::render('create/CreateProduct');
    }
}

1 Comment

As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.