'How to use React Router with Laravel?
I needing use React Router
with a Laravel
project.
But when I create router on the React Router
and try access, Laravel
accuse Route not exist error.
How to can I use React Router
to manager 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'));
Solution 1:[1]
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');
Solution 2:[2]
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.
Solution 3:[3]
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'
];
});
Solution 4:[4]
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.
Solution 5:[5]
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');
});
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | SalemC |
Solution 2 | MiKE Zamora |
Solution 3 | Andrey Kudriavtsev |
Solution 4 | |
Solution 5 | nickb |