Laravel 8 Inertia HighCharts not being imported in the app.js - laravel

I am trying to integrate Highcharts with app.js in Laravel 8 with Vue and Inertia. I am trying to figure out how to pass HighchartsVue. I am trying to pass it to the use function for the createApp. However, I can't access it in the templates.
App.js
require("./bootstrap");
// Import modules...
import { createApp, h } from "vue";
import HighCharts from ""
import {
App as InertiaApp,
plugin as InertiaPlugin,
} from "#inertiajs/inertia-vue3";
const el = document.getElementById("app");
createApp({
render: () =>
h(InertiaApp, {
initialPage: JSON.parse(el.dataset.page),
resolveComponent: (name) => require(`./Pages/${name}`).default,
}),
})
.mixin({ methods: { route } })
.use(InertiaPlugin)
.mount(el);
My template that tries to access the Vue Template. I haven't included the entire template here.
Vue Template
<div>
<highcharts :options="indexOptions"></highcharts>
</div>

For a global registration:
After you have installed "highcharts-vue" using:
npm install highcharts-vue
Register it globally as a plugin in your app.js with:
import HighchartsVue from 'highcharts-vue'
Next register it as a plugin in your vue object with:
Vue.use(HighchartsVue)
Please see the documentation here for more detailed instructions (and how to register it locally in the component).
After installing, your app.js would look something like this:
require("./bootstrap");
// Import modules...
import { createApp, h } from "vue";
import HighchartsVue from 'highcharts-vue'
import {
App as InertiaApp,
plugin as InertiaPlugin,
} from "#inertiajs/inertia-vue3";
Vue.use(HighchartsVue);
const el = document.getElementById("app");
createApp({
render: () =>
h(InertiaApp, {
initialPage: JSON.parse(el.dataset.page),
resolveComponent: (name) => require(`./Pages/${name}`).default,
}),
})
.mixin({ methods: { route } })
.use(InertiaPlugin)
.mount(el);

Related

How to define globally external plugin with inertiajs + vue in laravel?

I want to use vue-device-detector in my project. in this plugin docs it says to register with Vue.use(device) so how am i supposed to do this with inertiajs createInertiaApp.
App Versions:
Laravel: 9.44.0
Vue: 3.2.31
inertiajs/inertia: 0.11.0
inertiajs/inertia-vue3: 0.6.0
I have tried .use(device) on createApp in app.js. getting this error in console
main.ts:87 Uncaught (in promise) TypeError: Cannot set properties of undefined (setting '$device').
Project is created with laravel jetstream starter kit.
EDIT 1:
Here is my app.js code. i am don't know how i can register plugin here. (Because inertia mount the app here so i suppose global plugin also needs to be registered here!!)
import './bootstrap';
import '../css/app.css';
import { createApp, h } from 'vue';
import { createInertiaApp } from '#inertiajs/inertia-vue3';
import { InertiaProgress } from '#inertiajs/progress';
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);
},
});
InertiaProgress.init({ color: '#4B5563' });
PS: Thank you for reading my question, and please excuse any errors

Default Persistent Layout In Laravel + Inertia + Vite

In the previous way of setting up inertia in a laravel app, I could tweak the resolve property in the `createInertiaApp function from:
{
...,
resolve: name => import("./Pages/${name}"),
...
}
To
{
...,
resolve: name => {
const page = require("./Pages/${name}").default
if(!page.layout) {
page.layout = DefaultLayoutFile
}
},
...
}
To allow me manually pass a default layout file to be used in pages.
But with Vite becoming the default asset bundler and according to the docs, I must use a resolvePageComponent function which takes in import.meta.glob as a second argument to instruct Vite which files to bundle.
Problem here is the import gets returned from this resolvePageComponent so I cannot access the default object like I normally will from a require function.
So I have not been able to attach a default layout file to imported pages.
Has anyone been able to find a workaround for this?
Assuming you imported your default layout file like this (remember to not use # in imports anymore as only relative paths work for static analysis reasons):
import DefaultLayoutFile from './Layouts/DefaultLayoutFile.vue'
You can use the following code to get default layout working with Inertia and Vite:
resolve: (name) => {
const page = resolvePageComponent(
`./Pages/${name}.vue`,
import.meta.glob("./Pages/**/*.vue")
);
page.then((module) => {
module.default.layout = module.default.layout || DefaultLayoutFile;
});
return page;
},
[UPDATE 2022-08-01]
Since this is still receiving views, I though it would be useful to show how to get the # working in imports in Vite.
Require path below your imports in vite.config.js
import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
import vue from '#vitejs/plugin-vue';
const path = require('path')
And then add resolve into your config below:
export default defineConfig({
resolve:{
alias:{
'#' : path.resolve(__dirname, './src')
},
},
})
Now # will point to your Laravel root and you can import components dynamically from anywhere:
For example import LayoutTop from '#/Layouts/LayoutTop.vue'
will now point to
/resources/js/Layouts/LayoutTop.vue
Remember that Vite needs the .vue extension when importing Vue SFC files.
The async await version of the accepted answer
resolve: async name => {
const page = await resolvePageComponent(`./Pages/${name}.vue`, import.meta.glob("./Pages/**/*.vue"));
page.default.layout ??= DefaultLayoutFile;
return page;
},
This worked from me using the vite with inertia preset
import { createApp, h } from 'vue'
import { createInertiaApp } from '#inertiajs/inertia-vue3'
import { resolvePageComponent } from 'vite-plugin-laravel/inertia'
import DefaultLayout from '#/views/layouts/default.vue'
import SimpleLayout from '#/views/layouts/simple.vue'
import UserLayout from '#/views/layouts/user.vue'
createInertiaApp({
resolve: (name) => {
const page = resolvePageComponent(
name,
import.meta.glob('../views/pages/**/*.vue'),
DefaultLayout
);
page.then((module) => {
if (name.startsWith('auth.')) module.layout = SimpleLayout;
if (name.startsWith('user.')) module.layout = [DefaultLayout, UserLayout];
});
return page
},
setup({ el, app, props, plugin }) {
createApp({ render: () => h(app, props) })
.use(plugin)
.mount(el)
},
})

How to add bootstrap-vue module Laravel Jetstream with InertiaJS?

How can I work with bootstrap-vue on Laravel, using Laravel 8, Jetstream and InertiaJS?
import Vue from 'vue'
import { BootstrapVue, IconsPlugin } from 'bootstrap-vue'
// Import Bootstrap an BootstrapVue CSS files (order is important)
import 'bootstrap/dist/css/bootstrap.css'
import 'bootstrap-vue/dist/bootstrap-vue.css'
// Make BootstrapVue available throughout your project
Vue.use(BootstrapVue)
// Optionally install the BootstrapVue icon components plugin
Vue.use(IconsPlugin)
I don't know where and how to add the app.js file.
app.js:
require('./bootstrap');
// Import modules...
import { createApp, h } from 'vue';
import { App as InertiaApp, plugin as InertiaPlugin } from '#inertiajs/inertia-vue3';
import { InertiaProgress } from '#inertiajs/progress';
const el = document.getElementById('app');
createApp({
render: () =>
h(InertiaApp, {
initialPage: JSON.parse(el.dataset.page),
resolveComponent: (name) => require(`./Pages/${name}`).default,
}),
})
.mixin({ methods: { route } })
.use(InertiaPlugin)
.mount(el);
InertiaProgress.init({ color: '#4B5563' });
This is my css.js.
Here add the CSS libraries.
#import 'tailwindcss/base';
#import 'tailwindcss/components';
#import 'tailwindcss/utilities';
#import 'bootstrap/dist/css/bootstrap.css';
#import 'bootstrap-vue/dist/bootstrap-vue.css';
As I can see from your configuration. You are using InertiaJS with Vue3. Right now, BootStrap-Vue components only works with Vue2 (info). So you need first to downgrade InertiaJS from Vue3 to Vue2. With npm
npm uninstall #inertiajs/inertia-vue3 vue #vue/compiler-sfc vue-loader
npm install #inertiajs/inertia-vue vue vue-template-compiler vue-loader
It seems weird to uninstall and reinstall vue and vue-loader, but is the easiest way to properly update the dependencies.
Now you need to put in your app.js.
import Vue from 'vue';
import { createInertiaApp } from '#inertiajs/inertia-vue';
import BootstrapVue from 'bootstrap-vue';
Vue.use(BootstrapVue);
createInertiaApp({
resolve: (name) => require(`./Pages/${name}`),
setup({ el, app, props }) {
new Vue({
render: (h) => h(app, props),
}).$mount(el);
}
});
The app.css does not need any modification. Unless you need to modify and theme Bootstrap, in that case you must change to SASS.

Ziggy - Inertia js vue app NOT mounted AT ALL if we import route from 'ziggy' in app.js

I am working on a projet where it uses Laravel , ziggy ,inertia and vue.
i can not use ziggy in vue as suggested by thier doc.
here is my complete app.js
NB i can see the expected Ziggy.js file in /js/ziggy.js
//___________app.js________________
require('./bootstrap')
import Vue from 'vue'
import VueMeta from 'vue-meta'
import PortalVue from 'portal-vue'
import { App, plugin } from '#inertiajs/inertia-vue'
import { InertiaProgress } from '#inertiajs/progress/src'
import { BootstrapVue, IconsPlugin } from 'bootstrap-vue'
Vue.use(BootstrapVue)
Vue.use(IconsPlugin)
import 'bootstrap/dist/css/bootstrap.css'
import 'bootstrap-vue/dist/bootstrap-vue.css'
import { mixins } from 'vue-chartjs'
import route from 'ziggy';// the vue app is not mounted at all if i import the route from 'ziggy' and there is no error in console.;
import { Ziggy } from './ziggy';
Vue.mixin({
methods: {
route: (name, params, absolute, config = Ziggy) => route(name, params, absolute, config),
},
});
//Vue.config.productionTip = false
//Vue.mixin({ methods: { route: window.route } })
Vue.use(plugin)
Vue.use(PortalVue)
Vue.use(VueMeta)
InertiaProgress.init()
let app = document.getElementById('app')
new Vue({
metaInfo: {
titleTemplate: (title) => title ? `${title} - SSSYT` : 'your partner'
},
render: h => h(App, {
props: {
initialPage: JSON.parse(app.dataset.page),
resolveComponent: name =>
import (`./Pages/${name}`).then(module => module.default),
},
}),
}).$mount(app)
and here is the error i get in colnsole
Uncaught TypeError: Cannot read property 'prototype' of undefined
at Object.inherits (app.js:124712)
at Object.<anonymous> (app.js:68991)
at Object../node_modules/irc/lib/irc.js (app.js:69342)
at __webpack_require__ (app.js:64)
at Object../node_modules/ziggy/index.js (app.js:140181)
at __webpack_require__ (app.js:64)
at Module../resources/js/app.js (app.js:141504)
at __webpack_require__ (app.js:64)
at Object.0 (app.js:142081)
at __webpack_require__ (app.js:64)
```
For import route from 'ziggy'; to work, you need to alias 'ziggy' to the correct location in your Mix file.
Add this to your webpack.mix.js:
const path = require('path');
// Mix v6
mix.alias({
ziggy: path.resolve('vendor/tightenco/ziggy/dist'),
});
// Or, for Mix v5
mix.webpackConfig({
resolve: {
alias: {
ziggy: path.resolve('vendor/tightenco/ziggy/dist'),
},
},
});
See the section about this in the Ziggy docs for more details.

Using jetstream inertia with laravel modules

I would like to use nwidart/laravel-modules and inertia together. The problem I'm having is that my Index.vue that is in my Users module isn't showing up and there is no errors.
When I have this line of code in my app.js
resolveComponent: (name) => require(`../../Modules/Users/Resources/assets/Pages/${name}`).default
then my Index.vue shows up, but when I try to loop through it so that I can make it dynamic nothing shows up and there is no errors
This is what I have in my app.js at the moment
require('./bootstrap');
require('moment');
import Vue from 'vue';
import { InertiaApp } from '#inertiajs/inertia-vue';
import { InertiaForm } from 'laravel-jetstream';
import PortalVue from 'portal-vue';
Vue.mixin({ methods: { route } });
Vue.use(InertiaApp);
Vue.use(InertiaForm);
Vue.use(PortalVue);
const app = document.getElementById('app');
const modulesJson = require("../../modules_statuses.json");
var modulesObject = Object.keys(modulesJson);
new Vue({
render: (h) =>
h(InertiaApp, {
props: {
initialPage: JSON.parse(app.dataset.page),
resolveComponent: (name) => {
// LOOP IS HERE
for(let i = 0; i < modulesObject.length; i++){
require('../../Modules/'+modulesObject[i]+'/Resources/assets/Pages/'+name).default
}
}
},
}),
}).$mount(app);
Write the path of a file in your module when you want to run it through inertia. Then put a condition in the app.js file that if it is sent through the module, this code will be executed, otherwise it will return to the desired pages in the folder pages.
Like the following code:
Route::get('test',function () {
return \Inertia\Inertia::render('modules/Faq/resources/js/Pages/Admin/Index');
});
createInertiaApp({
title: (title) => `${title} - ${appName}`,
resolve: (name) => name.toString().indexOf('modules') > -1 ? require(`../../${name}.vue`) : require(`./Pages/${name}.vue`),
});

Resources