How to install Vuetify in Laravel 8 with jetstream-inertia? - laravel

I'm trying to install Vuetify on the latest Laravel versione (8) but I cannot do it. Seems it doesn't work even if the console doesn't show me any error.
That's my resource/plugins/vuetify.js
import Vue from 'vue'
// import Vuetify from 'vuetify'
import Vuetify from 'vuetify/lib'
// import 'vuetify/dist/vuetify.min.css'
Vue.use(Vuetify)
const opts = {}
export default new Vuetify(opts)
My webpack.mix.js :
const mix = require('laravel-mix')
const VuetifyLoaderPlugin = require('vuetify-loader/lib/plugin')
mix
.js('resources/js/app.js', 'public/js')
.postCss('resources/css/app.css', 'public/css', [
require('postcss-import'),
require('tailwindcss'),
])
.webpackConfig({
plugins: [
new VuetifyLoaderPlugin()
],
})
.browserSync('tb8.test');
The app.js
import PortalVue from 'portal-vue';
Vue.use(InertiaApp);
Vue.use(InertiaForm);
Vue.use(PortalVue);
Vue.use(vuetify);
const app = document.getElementById('app');
new Vue({
vuetify,
render: (h) =>
h(InertiaApp, {
props: {
initialPage: JSON.parse(app.dataset.page),
resolveComponent: (name) => require(`./Pages/${name}`).default,
},
}),
}).$mount(app);
and the 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.googleapis.com/css2?family=Nunito:wght#400;600;700&display=swap" rel="stylesheet">
<style>
body {
font-family: 'Nunito';
}
</style>
</head>
<body class="antialiased">
<div class="relative flex items-top justify-center min-h-screen bg-gray-100 dark:bg-gray-900 sm:items-center sm:pt-0">
#if (Route::has('login'))
<div class="hidden fixed top-0 right-0 px-6 py-4 sm:block">
#auth
Dashboard
#else
Login
#if (Route::has('register'))
Register
#endif
#endif
</div>
#endif
<v-app>
<v-main>
Hello World
</v-main>
</v-app>
</div>
</body>
</html>
Can anyone help me to find where is the mistake?
Thank you in advance
Valerio

Fresh Laravel 8.12 + Jetstream + Inertia + VueJs + Vuetify
add to header the string of style in /resources/views/app.blade.php
<link href="https://cdn.jsdelivr.net/npm/#mdi/font#4.x/css/materialdesignicons.min.css" rel="stylesheet">
add to /resources/js/app.js
import Vuetify from 'vuetify';
import 'vuetify/dist/vuetify.min.css';
Vue.use(Vuetify)
and
vuetify: new Vuetify(), after 'new Vue({' like this:
require('./bootstrap');
import Vue from 'vue';
import Vuetify from 'vuetify';
import { InertiaApp } from '#inertiajs/inertia-vue';
import { InertiaForm } from 'laravel-jetstream';
import PortalVue from 'portal-vue';
import 'vuetify/dist/vuetify.min.css';
Vue.mixin({ methods: { route } });
Vue.use(InertiaApp);
Vue.use(InertiaForm);
Vue.use(PortalVue);
Vue.use(Vuetify)
const app = document.getElementById('app');
new Vue({
vuetify: new Vuetify(),
render: (h) =>
h(InertiaApp, {
props: {
initialPage: JSON.parse(app.dataset.page),
resolveComponent: (name) => require(`./Pages/${name}`).default,
},
}),
}).$mount(app);
After that, for example, you can create your vuetify component like this:
/resources/js/Components/NavigationDrawers.vue with code from Vuetify labrory
init this vue-component in /resources/js/Pages/Dashboard.vue like
<navigation-drawers/>
with call
import NavigationDrawers from '#/Components/NavigationDrawers'
and
NavigationDrawers
in <script>
Example:
<template>
<app-layout>
<navigation-drawers/>
....
....
</app-layout>
</template>
<script>
import NavigationDrawers from '#/Components/NavigationDrawers'
import AppLayout from '#/Layouts/AppLayout'
import Welcome from '#/Jetstream/Welcome'
export default {
components: {
AppLayout,
Welcome,
NavigationDrawers,
},
}
</script>
It is help you for setting vuetify to your project.
Sass and other config you can config self.
a screenshot example Navigation Drawer
a screenshot example Navigation Drawer two

Currently Vuetify does not work with vue 3, so to install vuetify you have to go with vue 2. to do so:
we can install jetstream 2.1 which comes with vue 2. I have described installation process below:
Youtube video: https://youtu.be/V8_yLfNhg2I
To install laravel
composer create-project laravel/laravel project_name
Now go to composer.json file and inside require:{} add just one line and rest of composer file should be same.
"laravel/jetstream": "2.1",
after adding that "require" section of composer.json would look something like this:
"require": {
"php": "^7.3|^8.0",
"fideloper/proxy": "^4.4",
"fruitcake/laravel-cors": "^2.0",
"guzzlehttp/guzzle": "^7.0.1",
"laravel/framework": "^8.40",
"laravel/tinker": "^2.5",
"laravel/jetstream": "2.1",
},
Now run composer update
Now run php artisan jetstream:install inertia
Now run npm install
Now run npm install vuetify
Go to resources/css/app.css and add following
#import url('https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900');
#import url('https://cdn.jsdelivr.net/npm/#mdi/font#5.x/css/materialdesignicons.min.css');
#import "vuetify/dist/vuetify.min.css";
Now go to resources/js/app.js and add following code:
require('./bootstrap');
// Import modules...
import Vue from 'vue';
import { App as InertiaApp, plugin as InertiaPlugin } from '#inertiajs/inertia-vue';
import PortalVue from 'portal-vue';
//add these two line
import Vuetify from 'vuetify'
import 'vuetify/dist/vuetify.min.css'
Vue.mixin({ methods: { route } });
Vue.use(InertiaPlugin);
Vue.use(PortalVue);
//also add this line
Vue.use(Vuetify);
const app = document.getElementById('app');
new Vue({
//finally add this line
vuetify: new Vuetify(),
render: (h) =>
h(InertiaApp, {
props: {
initialPage: JSON.parse(app.dataset.page),
resolveComponent: (name) => require(`./Pages/${name}`).default,
},
}),
}).$mount(app);
Now run npm run dev
At this moment your vuetify will work!
To check whether vuetify with inertia js is working or not please follow:
Go to resources/js/Pages and create new file name test.vue
Add following code to test.vue
<template>
<v-app>
<v-container>
<v-btn>Click Me!</v-btn>
</v-container>
</v-app>
</template>
Now run npm run dev
Now go to route/web.php and add
Route::get('/', function () {
return Inertia::render('test');
});
Now php artisan serve to run in browser. and don't forget to add migrate and add database to .env

Vuetify now has a Vue 3 branch (at the time of writing still in beta) The point about the clash with tailwind still stands although the problem is mostly manifests its self in terms of file size (of the css) Anyway to get things working in an install of Laravel (9) and Jetstream with Inertia you need to add vuetify
npm install vuetify#^3.0.7 --save
Then edit resources/js/app.js
by adding:
// Vuetify
import 'vuetify/styles'
import { createVuetify } from 'vuetify'
import * as components from 'vuetify/components'
import * as directives from 'vuetify/directives'
const vuetify = createVuetify({
components,
directives,
})
and in the same file amending the createInertiaApp function set up so that Vue uses Vuetify
createInertiaApp({
title: (title) => `${title} - ${appName}`,
resolve: (name) => resolvePageComponent(`./Pages/${name}.vue`, import.meta.glob('./Pages/**/*.vue')),
setup({ el, app, props, plugin }) {
return createApp({ render: () => h(app, props) })
...
.use(vuetify)
...
},
});
You will then be able to use Vuetify components. You will probably want to set your own colours. There are two options SASS or javascript
here is an example of the Javascript option
const vuetify = createVuetify({
theme: {
themes: {
light: {
dark: false,
colors: {
primary: "#415e96",
secondary: "#b89acc"
}
},
},
},
components,
directives,
}
)
More on this here
Here is an (untested by me) article on removing the collisions between tailwind and Vuetify

Related

Creating a layout file in Laravel, Vue, Inertia Js

I'm new to Vue and Inertia Js, so far I understand that in Inertia, u can call Vue components with layouts, like navbar and sidebar etc.
but what I'm trying to achieve is to create a layout of the whole app, that consists of multiple vue files for example like this,
<template>
<NavbarVue/>
<Home/>
<Kenapa/>
<Cerita/>
<Karir/>
<Lowongan/>
<Media/>
<Gabung/>
<Mitra/>
<Download/>
<Footer/>
</template>
<script setup lang="ts">
import NavbarVue from '../components/Navbar.vue';
import Home from '../pages/Home.vue';
import Media from '../pages/Media.vue';
import Kenapa from '../pages/Kenapa.vue';
import Cerita from '../pages/Cerita.vue';
import Lowongan from '../pages/Lowongan.vue';
import Karir from '../pages/Karir.vue';
import Gabung from '../pages/Gabung.vue';
import Mitra from '../pages/Mitra.vue';
import Download from '../pages/Download.vue';
import Footer from '../components/Footer.vue';
</script>
In vue.js, I can create a layout for the app like that, by creating a template for different vue files like Home page, Kenapa page etc.
But in Inertia Js, this is the app.js file
import './bootstrap';
import '../css/app.css';
import { createApp, h } from 'vue';
import { createInertiaApp } from '#inertiajs/vue3';
import { resolvePageComponent } from 'laravel-vite-plugin/inertia-helpers';
import { ZiggyVue } from '../../vendor/tightenco/ziggy/dist/vue.m';
const appName = window.document.getElementsByTagName('title')[0]?.innerText || 'Laravel';
createInertiaApp({
title: (title) => `${title} - ${appName}`,
resolve: (name) => resolvePageComponent(`./Pages/${name}.vue`, import.meta.glob('./Pages/**/*.vue')),
setup({ el, App, props, plugin }) {
return createApp({ render: () => h(App, props) })
.use(plugin)
.use(ZiggyVue, Ziggy)
.mount(el);
},
progress: {
color: '#4B5563',
},
});
What should I do to achieve that ?
You must use a persistent layout for that.
Layout.vue
<template>
<div>
<Navbar />
<slot /> <!-- Don't forget this -->
<Footer />
</div>
</template>
<script setup lang="ts">
import Navbar from '../components/Navbar.vue';
import Footer from '../components/Footer.vue';
</script>
MyPage.vue
<script>
import Layout from './Layout'
export default {
layout: Layout,
}
</script>
<script setup>
defineProps({ user: Object })
</script>
<template>
<H1>My Page</H1>
<p>Hello {{ user.name }}, welcome to my page!</p>
</template>

Laravel + Inertia + Vue 2 Server side rendering - Styles not working

I have an application that I developed with Laravel vue2. My app works fine when I run it with npm run prod. Since I want to do SSR, I added inertia and edited the codes below, but styles are not working in my application and I cannot import anything.
My steps to start the project;
npm run prod
npx mix --mix-config=webpack.ssr.mix.js
node public/js/ssr.js
Error in browser -
Error in console
app.blade.php
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0" />
<script src="{{ asset('js') }}/manifest.js" type="text/javascript"></script>
<script src="{{ asset('js') }}/vendor.js" type="text/javascript"></script>
<script src="{{ asset('js') }}/app.js" type="text/javascript"></script>
#inertiaHead
</head>
<body>
#inertia
</body>
</html>
app.js
import Vue from "vue";
import App from "./App.vue";
import router from "./router";
import VueSweetalert2 from 'vue-sweetalert2';
import 'sweetalert2/dist/sweetalert2.min.css';
import 'bootstrap';
import 'bootstrap/dist/css/bootstrap.min.css';
import MaterialKit from "./plugins/material-kit";
import VueParticles from 'vue-particles'
Vue.use(VueParticles)
Vue.use(MaterialKit);
Vue.use(VueSweetalert2);
Vue.config.productionTip = false;
import('./assets/css/style.css');
const NavbarStore = {
showNavbar: false
};
Vue.mixin({
data() {
return {
NavbarStore
};
}
});
new Vue({
router,
render: h => h(App)
}).$mount("#app");
ssr.js
import Vue from 'vue'
import { createRenderer } from 'vue-server-renderer'
import { createInertiaApp } from '#inertiajs/inertia-vue'
import createServer from '#inertiajs/server'
createServer((page) => createInertiaApp({
page,
render: createRenderer().renderToString,
resolve: name => require(`./views/${name}`),
setup({ app, props, plugin }) {
console.log(page)
console.log(plugin)
console.log(props)
Vue.use(plugin)
return new Vue({
render: h => h(app, props),
})
},
}))
webpack.mix.js
const mix = require('laravel-mix');
mix.js('resources/js/app.js', 'public/js')
.vue()
.disableSuccessNotifications()
.extract(['vue', 'vue-router', 'axios', 'vue-sweetalert2', 'vue-lazyload', 'vue-carousel', 'vue-material']);
webpack.ssr.mix.js
const path = require('path')
const mix = require('laravel-mix')
const webpackNodeExternals = require('webpack-node-externals')
mix
.options({ manifest: false })
.js('resources/js/ssr.js', 'public/js')
.vue({ version: 2, options: { optimizeSSR: true }, useVueStyleLoader: true},)
.alias({ '#': path.resolve('resources/js') })
.webpackConfig({
target: 'node',
externals: [webpackNodeExternals()],
}).extract(['vue', 'vue-router', 'axios', 'vue-sweetalert2', 'vue-lazyload', 'vue-carousel', 'vue-material']);
Try add to .webpackConfig({... , useVueStyleLoader: true})

Default route is not working with laravel and vue

I am creating a single page application using laravel and vue. it's not loading index component on page load.
web.php
Route::get('{any}', function () {
return view('welcome');
})->where('any', '.*');
Welcome.blade.php
<body>
<div id="app">
<router-view></router-view>
</div>
<script src="{{asset('js/app.js')}}"></script>
</body>
router.js file
import Vue from 'vue';
import VueRouter from 'vue-router';
Vue.use(VueRouter)
const routes = [
{ path: '/', component: require('./components/IndexComponent.vue') },
{ path: '/login', component: require('./components/LoginComponent.vue') }
]
const router = new VueRouter({
routes:routes,
mode:'history'
})
export default new VueRouter({router})
app.js file
require('./bootstrap');
window.Vue = require('vue');
import vuetify from './vuetify';
import router from './router';
import Index from './components/IndexComponent';
import Login from './components/LoginComponent';
var app = new Vue({
el: '#app',
router,
vuetify,
components: {
'index-component':Index,
'login-component':Login
}
});
Index Component (IndexComponent.vue)
<template>
<router-link to="/" class="nav-item nav-link">Home</router-link>
<router-link to="/login" class="nav-item nav-link">Login</router-link>
<router-view></router-view>
</template>
I had the same problem. Open your project in chrome and press Ctrl + Shift + I (Open console). Now after the login you can see that there is a warning which says: No match for favicon.ico. To solve this problem you go to your routes file and define a redirect:
{
path: '/favicon.ico',
redirect: '/user/dashboard'
}

How to use Vuetify (VAutocomplete) with Laravel

I'm trying to use VAutocomplete within a vue component in my laravel project.
I installed vuetify like this:
npm install vuetify
The .js with which I load the component looks like this:
import Vue from 'vue'
import Vuetify from 'vuetify'
Vue.use(Vuetify)
import 'vuetify/dist/vuetify.min.css';
import MyComponent from './components/MyComponent.vue';
const app = new Vue({
el: '#my-component,
components: {
MyComponent
},
render: h => h(MyComponent)
});
MyComponent.vue:
<template>
<div>
<v-autocomplete
label="Components"
:items="components"
></v-autocomplete>
</div>
</template>
<script>
export default {
name: "MyComponent",
data: function () {
return {
components: [
'Autocompletes', 'Comboboxes', 'Forms', 'Inputs', 'Overflow Buttons', 'Selects', 'Selection Controls', 'Sliders', 'Textareas', 'Text Fields',
],
}
},
}
</script>
I see the following error in the browsers console:
[Vue warn]: Error in render: "TypeError: undefined is not an object (evaluating 'this.$vuetify.lang.t')"
found in
---> <VAutocomplete>
Laravel is 5.6
Vue 2.9.6
Vuetify 2.0.2
Can someone please give me a hint to get started with vuetify? Thanks!
I had the same problem. Here is how you could solve it:
Make sure to add the correct vue and vue-template-compiler versions to your package.json.
Then remove your 'node_modules' folder and reinstall it:
npm install
You also should import the VueLoaderPlugin in you webpack.mix.js.
const VueLoaderPlugin = require('vue-loader/lib/plugin')
Your mix call should look something like this:
mix.js('resources/assets/js/app.js', 'public/js').extract(['vue'])
.js('resources/assets/js/mycomponent.js', 'public/js')
.sass('resources/assets/sass/app.scss', 'public/css').webpackConfig({
plugins: [
new VueLoaderPlugin()
]
}).sourceMaps();
.sourceMap() to avoid missing vuetify.js.map error.
Error is because you missed a "
const app = new Vue({
el: '#my-component', <=here
components: {
MyComponent
},
render: h => h(MyComponent)
});
The other error is that you don't have ID in your template.
It should work in this way:
<div id="my-component">
<v-app id="inspire">
<div>
<v-autocomplete
label="Components"
:items="components"
></v-autocomplete>
</div>
</v-app>
</div>
Script:
new Vue({
el: '#my-component',
vuetify: new Vuetify(),
data () {
return {
components: [
'Autocompletes', 'Comboboxes', 'Forms', 'Inputs', 'Overflow Buttons', 'Selects', 'Selection Controls', 'Sliders', 'Textareas', 'Text Fields'],
}
},
})

How correctly include VueRouter in Laravel Project?

I try to implement VueRouter in Laravel project but arreas error Vue warn]: Unknown custom element: - did you register the component correctly? For recursive components, make sure to provide the "name" option.
app.js
import Vue from 'vue'
import VueRouter from 'vue-router'
import App from './components/App'
import ExampleComponent from './components/ExampleComponent'
import ExampleComponent1 from './components/ExampleComponent1'
Vue.use(VueRouter)
const router = new VueRouter({
routes: [
{
path: '/',
component: ExampleComponent
},
{
path: '/example',
component: ExampleComponent1
}
]
})
const app = new Vue({
el: '#app',
router,
template: `<app></app>`,
components: {
App
}
})
components/App.vue
<template>
<div>
<div>
<router-link :to="'/'"></router-link>
<router-link :to="'/example'"></router-link>
</div>
<div>
<router-vue></router-vue>
</div>
</div>
</template>
<script>
export default {
}
</script>
how can I connect correctly vue-router?
I see that you've misspelled <router-view /> in App.vue which is probably causing the warning.

Resources