Home > Net >  React router dynamic route with laravel
React router dynamic route with laravel

Time:10-04

I make React(17) Laravel(9.31) project.

I try implement routing in the frontend.("react-router-dom": "^5.0.0") but same result with 6. I used now one blade (index) and send everyting here. index and main blade have a connection(yield).

The main blade forms the skeleton of the page and load React. I add route also main.blade.php that be seen the difference between the routes.

The normal route work fine.

But the dynamic path not work.

For examples:

http://127.0.0.1:2432/something (This route not exist)

result:

Not Used Routes

My Routes

http://127.0.0.1:2432/test1

result:

Not Used Routes

My Routes

Teszt1

http://127.0.0.1:2432/test2

result:

Not Used Routes

My Routes

Teszt2

http://127.0.0.1:2432/book/1

Not Used Routes

Three links from php:test1,test2,book

and get error message: 1:29 GET http://127.0.0.1:8000/book/js/app.js net::ERR_ABORTED 404 (Not Found)

**if i delete from web.php this route **

Route::get('/{route}/{id}',function(){
    return view('index');
});

i get not found page from laravel

App.js

import React, { useState } from "react";
import ReactDOM from "react-dom";
import {
    BrowserRouter as Router,
    Route,
    Redirect,
    Switch,
} from "react-router-dom";
import Teszt1 from "./Teszt1";
import Teszt2 from "./Teszt2";
import Book from "./Book";
import "../../css/app.css";
import "../../css/index.css";

function App() {
    return (
        <>
            <h1>My routes</h1>
            <Router>
                <Switch >
                    <Route path="/test1">
                        <Teszt1 />
                    </Route>
                    <Route path="/test2">
                        <Teszt2 />
                    </Route>
                    <Route path="/book/:id">
                        <Book />
                    </Route>
                </Switch>
            </Router>
        </>
    );
}

export default App;

Book.js

import React from 'react'

export default function Book() {
    return (
        <div>
            <h1>Book</h1>
        </div>
    )
}

Teszt1.jsx

import React from 'react'

export default function Teszt1() {
    return (
        <div>
            <h1>Teszt1</h1>
        </div>
    )
}

Teszt2.jsx

import React from 'react'

export default function Teszt2() {
    return (
        <div>
            <h1>Teszt2</h1>
        </div>
    )
}

index.blade.php

@extends('layout.main')

@section('react-index')
<div id="react-index"></div>
@endsection

main.blade.php

<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Test</title>
</head>

<body>
  <h1>Not used Routes</h1>
  <nav>
    <ul>
        <li >
            <a  href="/test1">test1</a>
          </li>
          <li >
            <a  href="/test2">test2</a>
          </li>
          <li >
            <a  href="/book">Book</a>
          </li>
     </ul>
  </nav>
  @yield('react-index')
  <script>
      @if (isset($main))
    const main =  {{ Illuminate\Support\Js::from($main)}};
    @endif

    const token = '{{@csrf_token()}}'
  </script>
  <script src=" js/app.js">
  </script>
</body>
</html>

web.php

<?php

use Illuminate\Support\Facades\Route;
use App\Models\User;
use App\Http\Controllers\TaskController;
use App\Http\Controllers\ReactController;

/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/

Route::get('/', function () {
    return view('index');
});


Route::get('/{route}',function(){
    return view('index');
});

Route::get('/{route}/{id}',function(){
    return view('index');
});

package.json

{
    "private": true,
    "scripts": {
        "dev": "npm run development",
        "development": "mix",
        "watch": "mix watch",
        "watch-poll": "mix watch -- --watch-options-poll=1000",
        "hot": "mix watch --hot",
        "prod": "npm run production",
        "production": "mix --production"
    },
    "devDependencies": {
        "@babel/preset-react": "^7.18.6",
        "@popperjs/core": "^2.10.2",
        "@testing-library/react": "^12.1.2",
        "@vitejs/plugin-react": "^2.0.0",
        "axios": "^0.27",
        "bootstrap": "^5.2.1",
        "laravel-vite-plugin": "^0.6.0",
        "lodash": "^4.17.19",
        "postcss": "^8.1.14",
        "react": "^17.0.2",
        "react-dom": "^17.0.2",
        "resolve-url-loader": "^5.0.0",
        "sass": "^1.55.0",
        "sass-loader": "^13.0.2",
        "vite": "^3.0.0"
    },
    "dependencies": {
        "laravel-mix": "^6.0.49",
        "react-bootstrap": "^2.5.0",
        "react-router-dom": "^5.0.0"
    }
}


Thank you

CodePudding user response:

According to your code in main.blade.php the web.php should have two basic routes.

Route::get('/test1',function(){
    return view('index');
});

Route::get('/test2',function(){
    return view('index');
});

And you want the book to have an {id} so you need to change the href to the desired id (on main.blade.php) like:

<li >
    <a  href="/book/1">Book</a>
</li>

And then change the routes to recive that parameter.

Route::get('/book/{id}',function(){
    return view('index');
});

You can clear the laravel routes by php artisan route:clear and check if the route really exists by php artisan route:list.

CodePudding user response:

My mistake there was I manualy write the URL in browser. This was as if I would write a tag instead of NavLink.

So the page reload and ask Laravel again and again.

If use NavLink the routing work properly in React.

wrong:
 <a href="book/1">Click here</a>

good:
  <NavLink  to={`book/${id}`} className="btn btn-primary m-1 mt-auto">
   Click here             
  </NavLink>

In the backend unnecessary more route.

Enough this that react should be served once to the browser

Route::get('/', function () {
    return view('index');
});
  • Related