how to set up laravel-vue project using #vitejs/plugin-vue plugin - php

I have setup the laravel project with vuejs using #vitejs/plugin-vue plugin, The issue I'm facing is how to manage endpoints between client(vue 3) and backend (laravel 9).
When click register at first time it return the register.vue
When page refresh it returns back 404 error.
welcome.blade.php
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Laravel</title>
<!-- Fonts -->
<link href="https://fonts.bunny.net/css2?family=Nunito:wght#400;600;700&display=swap" rel="stylesheet">
#vite(['resources/js/app.js','resources/css/app.css'])
</head>
<body class="antialiased">
<div id="app"></div>
</body>
</html>
App.vue
<template>
<header>
<!-- load navbar here -->
<nav>
<RouterLink to="/register">Register</RouterLink>
<RouterLink to="/">Home</RouterLink>
</nav>
</header>
<main>
<RouterView/>
</main>
</template>
router.js
import {createRouter, createWebHistory} from "vue-router";
import Register from "../components/Register.vue";
import App from "../../views/App.vue";
const router = createRouter({
history: createWebHistory(),
routes: [
{
path: '/',
name: 'app',
component: App
},{
path: '/register',
name: 'register',
component: Register
}
]
})
export default router

Quick fix.
In routes/web.php
Route::get('/{any}', function () {
return view('welcome');
})->where("any",".*");
see here

Related

How comment script tag content in blade.php?

I try build a React Laravel webpage.
The main.blade.php responsible the layout and that pass data and React components to other blade
I test my app and make few blade.php
So I try comment out several way this line:
/* const data = {{ Illuminate\Support\Js::from($data)}};*/
but not work. It still perceives it as if it were there
I have to pass data for every route for testing because I can't comment the above line
Route::get('/react', function () {
$data = User::find(1);
return view('reactpractice', compact("data"));
})->name('react');
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">
<link rel="stylesheet" href="/css/app.css"/>
<title>#yield('title')</title>
<title>{{env('APP_NAME')}}</title>
</head>
<body>
<header>
Motto
</header>
<nav>
Index
About
React
Users
Login
Register
</nav>
#yield('contenttop')
#if(Session::has('successmessage'))
<div class="alert alert-success my-3">
{{Session::get('successmessage')}}
</div>
#endif
#yield('example')
<script>
const data = {{ Illuminate\Support\Js::from($data)}};
const token = '{{#csrf_token()}}'
</script>
<h2> React</h2>
<script src="js/app.js"></script>
</body>
</html>
So how comment script tag content in blade.php?
Rather than comment the line in JavaScript, why not make it conditional?
#if (isset($data))
const data = {{ Illuminate\Support\Js::from($data)}};
#endif
This way, if $data is provided, the JavaScript variable will be created. If $data is missing, it will be ignored and won't break your code.
<!-- Try like this -->
// or /* */
I hope it was helpfull.

Problem trying to render React Component in Laravel Project

I am having issues trying to render my React component within my 'login' view. I am using the Laravel Framework. The page is loaded, however I find no React component in my React Devtools. The Example component provided in the Laravel Project template renders fine. I could not find an error in my syntax, and I was hoping one of you could help me find my error.
My login.blade.php
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Laravel Login</title>
<!-- Fonts -->
<link href="https://fonts.googleapis.com/css2?family=Nunito:wght#200;600&display=swap" rel="stylesheet">
<link href="{{ URL::asset('public/css/app.css') }}">
</head>
<body>
<div id="login-form">
</div>
<script defer src='./js/app.js'> </script>
</body>
</html>
My LoginForm.js
import React from 'react';
import ReactDOM from 'react-dom';
function LoginForm() {
return (
<div class= "container">
Insert FORM here TEST
</div>
);
}
export default LoginForm;
if (document.getElementById('login-form')) {
ReactDOM.render(<LoginForm />, document.getElementById('login-form'));
}
My web.php
<?php
use Illuminate\Support\Facades\Route;
/*
|--------------------------------------------------------------------------
| 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('welcome');
});
Route::get('/login', function () {
return view('login');
});
My app.js
require('./bootstrap');
require('./components/Example');
require('./components/LoginForm');
I actually ended up solving this. I changed my LoginForm.js to look like this.
import React, {component} from 'react';
import ReactDOM from 'react-dom';
export default class LoginForm extends React.Component{
render(){
return (
<div class= "container">
Insert FORM here TEST
</div>
);
}
}
if (document.getElementById('login-form')) {
ReactDOM.render(<LoginForm />, document.getElementById('login-form'));
}

Loading a livewire component inside a modal

Description
I am trying to dynamically load a Livewire component inside a modal, using Livewire. I can successfully load the HTML content in the modal, but any Javascript on the "target" component is not executed.
Exact steps to reproduce
<!-- index.blade.php -->
<div>
<a onclick="showTask(1)">Open task #1</a>
#includeWhen($openTask, 'partials.tasks._task_modal')
</div>
//Index.php
function showTask(int $taskId){
$this->managingTask = true;
$this->openTask = Task::firstWhere('id', $taskId);
}
So in the above code, when a user clicks the a tag, it will open the modal, placed in:
<!-- _task_modal.blade.php -->
<x-jet-dialog-modal wire:model="managingTask">
<x-slot name="content">
#livewire('tasks.show', ['task' => $openTask])
</x-slot>
</x-jet-dialog-modal>
As you can see, the modal component simply refers to another Livewire component called tasks.show. Inside this, I have the following in the view file:
<!-- show.blade.php -->
<div>
<a onclick="test()">Test</a>
</div>
#push('scripts')
<script type="text/javascript">
function test(){
alert("It works!")
}
document.addEventListener('livewire:load', function () {
console.log("Livewire Loaded");
});
</script>
#endpush
This is my layout file:
<!-- app.blade.php -->
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="csrf-token" content="{{ csrf_token() }}">
<title>{{ config('app.name', 'Laravel') }}</title>
<!-- Styles -->
<link rel="stylesheet" href="{{ mix('css/app.css') }}">
#livewireStyles
<!-- Scripts -->
<script src="{{ mix('js/app.js') }}" defer></script>
</head>
<body class="font-sans antialiased" >
<div id="root" x-data>
{{$slot}}
</div>
#stack('modals')
#livewireScripts
#stack('scripts')
</body>
</html>
Now, when clicking on the a link inside the show.blade.php Livewire component, I get the following error:
Uncaught ReferenceError: test is not defined
Further, I do not see the "Livewire Loaded" in my console.
Context
Livewire version: 2.3.6
Laravel version: 8.12
Browser: Chrome

How to combine laravel and vue routes

I am creating a simple laravel and vuejs CRUD Application. Vue Routes are not working, I am pretty new to vuejs; please see the code
Below is the code for web.php
Route::get('/', function () {
return view('welcome');
});
Auth::routes();
Route::get('/home', 'HomeController#index')->name('home');
Route::get('/vue','Api\PostController#home');
Route::resource('/api','Api\PostController');
Following is the code for app.js
require('./bootstrap');
window.Vue = require('vue');
window.VueRouter=require('vue-router').default;
window.VueAxios=require('vue-axios').default;
window.Axios=require('axios').default;
let AppLayout = require('./components/App.vue');
const Posts = Vue.component('Posts',require('./components/Posts.vue'));
const EditPost =
Vue.component('EditPost',require('./components/EditPost.vue'));
const AddPost =
Vue.component('AddPost',require('./components/AddPost.vue'));
const DeletePost =
Vue.component('DeletePost',require('./components/AddPost.vue'));
const ViewPosts =
Vue.component('ViewPosts',require('./components/ViewPosts.vue'));
const ExampleComponent =
Vue.component('ViewPosts',require('./components/ExampleComponent.vue'));
// Registering routes
Vue.use(VueRouter,VueAxios,axios);
const routes = [
{
name: 'Posts',
path: '/posts',
component: Posts
},
{
name: 'AddPost',
path: '/add-posts',
component: AddPost
},
{
name: 'EditPost',
path: '/edit-post/:id',
component: EditPost
},
{
name: 'DeletePost',
path: '/delete-post',
component: DeletePost
},
{
name: 'ViewPosts',
path: '/view-post',
component: ViewPosts
},
{
name: 'ExampleComponent',
path: '/example-component',
component: ExampleComponent
},
];
const router = new VueRouter({mode: 'history', routes: routes});
new Vue(
Vue.util.extend(
{ router },
AppLayout
)).$mount('#app');
This is the code of my blade tamplate, when I browse http://localhost:8000/vue this view is being rendered. As you can see in the web.php code above.
I can also see the notification in console You are running Vue in development mode. Make sure to turn on production mode when deploying for production.
<!DOCTYPE html>
<html lang="{{ app()->getLocale() }}">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- CSRF Token -->
<meta name="csrf-token" content="{{ csrf_token() }}">
<title>{{ config('app.name', 'Laravel') }}</title>
<!-- Styles -->
<link href="{{ asset('css/app.css') }}" rel="stylesheet">
</head>
<body>
<div class="container">
<header class="page-header">
<div class="branding">
<img src="https://vuejs.org/images/logo.png" alt="Logo" title="Home page" class="logo"/>
<h1>Vue.js CRUD With Laravel 5 application</h1>
</div>
</header>
</div>
<section id="app">
</section>
<script>
window.Laravel = <?php echo json_encode([
'csrfToken' => csrf_token(),
]); ?>
</script>
<script src="{{ asset('js/app.js') }}"></script>
</body>
</html>
But when I run my application using
php artisan serve
and browse to
http://localhost:8000/posts
Application show a 404 error. Please help me with this problem.
You need to add a laravel route for the view where you are using the app.js (vuejs) in routes/web.php file.
Route::get('/route-name/?{name}', function(){
return redirect('vue_app');
})->where('name', '[A-Za-z]+');
and then you have to use the laravel route as a parent route for the vuejs's routes and use the url like below,
http://localhost:8000/laravel-route/view-route
in your case,
http://localhost:8000/route-name/posts
Or you can also use,
Route::get('{any}', function () {
return view('vue_app');
})->where('any', '.*');
and instead of previous use localhost:8000/posts
Try this to your web.php route
Route::get('/', function () {
return view('index');
});
Route::get('/{catchall?}', function () {
return response()->view('index');
})->where('catchall', '(.*)');
if with {any} did not work, you may also try adding ?
Route::get('/any-your-route/{any?}', function() {
return view('your-view');
})->where('any', '.*');
hope this help you. i just try this code and work on laravel blade template with vue router.
Tested on Laravel 8
For your second part of question,
You should use <div> instead of <section> and you have to bring the main/registered component inside of the html element selected by id="app" in blade file. in your case,
<div id="app">
<app-layout></app-layout>
</div>
Hope this help you. you can check this basic vuejs with laravel
PS: You should ask two different problem in two seperate posts.
you can do simply like this.
Route::get('/{vue_capture?}', function(){
return view('welcome');
})->where('vue_capture', '[\/\w\.-]*');

Vue.js not seo friendly

I'm trying to use vue.js. I have these Components named Home where I try to display a list of posts from a WordPress api.
<template>
<div class="hello">
<h1>{{ msg }}</h1>
<div v-for='post in posts'>
{{ post.title.cleared }}
</div>
</div>
</template>
<script>
export default {
name: 'Home',
data () {
return {
msg: 'Welcome to Mik Vue.js App',
posts: []
}
},
methods: {
},
created: function(){
this.$http.get('wp/v2/posts?per_page=6').then(response => {
this.posts=response.data;
console.log(this.posts);
}, error => {
alert("shit");
});
}
}
</script>
I understand that it works correctly.
But if I look "Page Source" this is the result
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>VueJS-Project</title>
</head>
<body>
<div id="app"></div>
<!-- built files will be auto injected -->
<script type="text/javascript" src="/app.js"></script></body>
</html>
How can I prerend this list and see it in page source? is there a way to do this without using PHP?
I want also to add meta informations.
thank you

Categories