7

I am using Ziggy for my Laravel, Vue.js and Inertia js project. In the view page source, I can clearly see all of the Laravel routes.

<script type="text/javascript">
    const Ziggy = {"url":"http:\/\/127.0.0.1:8787","port":8787,"defaults":{},"routes": 
    ......

"sup_finish_tt_order":{"uri":"front\/finishorder","methods":["POST"]},"assign__tt":{"uri":"front\/assigntt","methods":["POST"]},"technicians":{"uri":"technicians","methods":["GET","HEAD"]},"change-password":{"uri":"change-password","methods":["GET","HEAD"]},"reset.password":{"uri":"c
----------
</script>

Is there any way to relocate this Ziggy object in app.js or make it less obvious? Based on the Ziggy documentation and the answer attempted here I try importing it in app.js,a but it's not working.

Uncaught TypeError: Cannot read property 'prototype' of undefined at Object.inherits (app.js:124712) at Object. (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)

___________________________Set up ______________________________________

//Backend

$ php artisan ziggy:generate
File generated!

// sample /resources/js/ziggy.js file

const Ziggy = {"url":"http:\/\/127.0.0.1:8787","port":8787,"defaults":{},"routes":{"debugbar.openhandler":{"uri":"_debugbar\/open"  /*..... All named routes as expeted */


if (typeof window !== 'undefined' && typeof window.Ziggy !== 'undefined') {
    for (let name in window.Ziggy.routes) {
        Ziggy.routes[name] = window.Ziggy.routes[name];
    }
}

export { Ziggy };


// /resources/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'

// Ziggy start here
import route from 'ziggy';
import { Ziggy } from './ziggy';

Vue.mixin({
    methods: {
        route: (name, params, absolute, config = Ziggy) => route(name, params, absolute, config),
    },
});
// ziggy end here



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 TreeBrowser from './Pages/globalComponents/TreeBrowser.vue'
//Vue.config.productionTip = false
Vue.mixin({ methods: { route: window.route } })
Vue.use(plugin)
Vue.use(PortalVue)
Vue.use(VueMeta)
Vue.component('TreeBrowser', TreeBrowser)
InertiaProgress.init()

let app = document.getElementById('app')

new Vue({
    metaInfo: {
        titleTemplate: (title) => title ? `${title} - FNV` : 'FNV yours'
    },
    render: h => h(App, {
        props: {
            initialPage: JSON.parse(app.dataset.page),
            resolveComponent: name =>
                import (`./Pages/${name}`).then(module => module.default),
        },
    }),
}).$mount(app)

// /webpack.mix.js

const mix = require('laravel-mix');
const path = require('path');
mix.js('resources/js/app.js', 'public/js')
    .sass('resources/sass/app.scss', 'public/css');

mix.webpackConfig({
    resolve: {
        alias: {
            ziggy: path.resolve('vendor/tightenco/ziggy/dist'),
        },
    },
});

usage of ziggy ex in Login.vue

this.$inertia.post(this.route('login.attempt'), data, {
        onStart: () => this.sending = true,
        onFinish: () => this.sending = false,
      })
    ```

SeyT
  • 773
  • 1
  • 10
  • 23
  • 1
    may I ask "why"? One way or another your javascript code will have to know the routes so its exposed anyhow – Flame Feb 16 '21 at 22:58
  • 1
    Yet but they are not at least in the html. – SeyT Feb 17 '21 at 04:41
  • based on the accepted answers and by removing ``` Vue.mixin({ methods: { route: window.route } }) ``` it works – SeyT Feb 20 '21 at 16:54

3 Answers3

8

Maintainer of Ziggy here. FightInGlory's answer is correct.

Run php artisan ziggy:generate.

Then, in your webpack.mix.js file:

const path = require('path');

// Mix v6
mix.alias({
    ziggy: path.resolve('vendor/tightenco/ziggy/dist'),
});

// Or, Mix v5
mix.webpackConfig({
    resolve: {
        alias: {
            ziggy: path.resolve('vendor/tightenco/ziggy/dist'),
        },
    },
});

Then, in the file that you want to use Ziggy in:

import route from 'ziggy';
// Change './ziggy' to the relative path to the file generated above, usually resources/js/ziggy.js
import { Ziggy } from './ziggy';

// ...

route('posts.show', 1, undefined, Ziggy);

If you're using Vue, it can be helpful to create a global mixin so that you don't need to pass Ziggy in as the 4th argument every time. There is an example of how to set this up in the docs.

If that still doesn't work please feel free to submit an issue with a detailed explanation of your setup!

bakerkretzmar
  • 103
  • 2
  • 7
  • i am creating issue , FYI the detail is added to the Question . – SeyT Feb 17 '21 at 04:59
  • @bakerkretzmar I keep getting a 'TypeError: this.route is not a function. Any tips at all? – oluwatyson Apr 25 '21 at 09:35
  • TypeError: Cannot call a class as a function is also another error I keep getting. What am I doing wrong? – oluwatyson Apr 25 '21 at 10:08
  • @oluwatyson for the `TypeError` make sure you're making the route function available in all your Vue components with a mixin like `Vue.mixin({ methods: { route } })`. Are you using Ziggy v1? Feel free to file an issue in the repo and we can take a closer look! https://github.com/tighten/ziggy/issues – bakerkretzmar Apr 26 '21 at 14:01
5

If you are not using Blade, or would prefer not to use the @routes directive, Ziggy provides an artisan command to output its config and routes to a file: php artisan ziggy:generate

import route from 'ziggy';
import { Ziggy } from './ziggy';

Vue.mixin({
    methods: {
        route: (name, params, absolute, config = Ziggy) => route(name, params, absolute, config),
    },
});

You can optionally create a webpack alias to make importing Ziggy's core source files easier

// webpack.mix.js

// Mix v6
const path = require('path');

mix.alias({
    ziggy: path.resolve('vendor/tightenco/ziggy/dist'),
});

// Mix v5
const path = require('path');

mix.webpackConfig({
    resolve: {
        alias: {
            ziggy: path.resolve('vendor/tightenco/ziggy/dist'),
        },
    },
});

This mean that you should change path here '.ziggy'

import { Ziggy } from './ziggy';
FightInGlory
  • 448
  • 2
  • 6
  • App does not mounted due to import route from 'ziggy'; Uncaught TypeError: Cannot read property 'prototype' of undefined at Object.inherits (app.js:124712) at Object. (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) – SeyT Feb 15 '21 at 04:52
  • Did you changed path at this line? import { Ziggy } from './ziggy'; Or added for webpack alias? – FightInGlory Feb 15 '21 at 07:22
  • No ,nothing is changed , i copy the above answer /pee documentation as it is . – SeyT Feb 15 '21 at 08:07
  • I changed my answer, please check – FightInGlory Feb 15 '21 at 12:58
2

comment or delete ziggy array on Middleware/HandleInertiaRequests.php seem like below :

 public function share(Request $request)
    {
        return array_merge(parent::share($request), [
            'auth' => [
                'user' => $request->user(),
            ],
            // 'ziggy' => function () {
            //     return (new Ziggy)->toArray();
            // },
        ]);
    }
ferixio
  • 21
  • 2