ziggy: Documentation is missing the requirement of `vendor/tightenco/ziggy/src/js/route.js`

Expected Behavior

Documentation should explain that the route.js file needs to be imported from vendor/tightenco/ziggy/src/js/route.js when using the ziggy:generate artisan command.

Current Behavior

Not documented.

I’ve put together an example for anyone that uses Laravel Mix and Vue (probably a lot of people who want to use Ziggy!)

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Comments: 21 (1 by maintainers)

Most upvoted comments

When using Vue.mixin(), you are essentially adding something to every component definition, so the following snippet:

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

adds a route() method to every component (accessible with this.route('route.name.here').

For your example, you don’t need to assign route at all in the data() { ... } portion of your component. You can fix your importUser() method by simply using axios.post(this.route('users.store')).

To use route() outside Vue components:

There are times where I need to use the route method outside of Vue components. For this, i use the following solution:

Make a separate route.js file that you can import wherever you need it:

// resources/js/route.js
import route from 'ziggy'
import { Ziggy } from './ziggy'

export default function (name, params, absolute) {
    return route(name, params, absolute, Ziggy)
}

Then you can import it into app.js to set up the global mixin:

// resources/js/app.js
import route from './route'

Vue.mixin({
    methods: {
        route,
    },
})

Or in any other module / js file e.g. a VueX store:

// resources/js/store/mymodule.js
import axios from 'axios'
import route from '../route'

// actions
const actions = {
    getExample({ state }) {
        return axios.get(route('my-route'))
    },
}

Depending on your Laravel version, you may need to change the path of the ziggy:generate command as it defaults to the ‘legacy’ resources/assets/js/ directory. Laravel >=5.8 (I think) uses resources/js/ instead.

I’ve just done a fresh Laravel install and these are the exact steps taken to get Ziggy to work with Vue:

Set up in terminal:

laravel new ziggy-laravel-test
cd ziggy-laravel-test
composer require laravel/ui --dev
composer require tightenco/ziggy
php artisan ui vue
yarn install

webpack.mix.js

const mix = require('laravel-mix');
const path = require('path');

/*
 |--------------------------------------------------------------------------
 | Mix Asset Management
 |--------------------------------------------------------------------------
 |
 | Mix provides a clean, fluent API for defining some Webpack build steps
 | for your Laravel application. By default, we are compiling the Sass
 | file for the application as well as bundling up all the JS files.
 |
 */

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

mix.js('resources/js/app.js', 'public/js')
   .sass('resources/sass/app.scss', 'public/css');

routes/web.php

<?php
Route::get('/', function () {
    return view('welcome');
})->name('welcome'); // Need at least one named route

Run Ziggy

php artisan ziggy:generate ./resources/js/ziggy.js

resources/js/app.js

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

/**
 * First we will load all of this project's JavaScript dependencies which
 * includes Vue and other libraries. It is a great starting point when
 * building robust, powerful web applications using Vue and Laravel.
 */

require('./bootstrap');

window.Vue = require('vue');

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

/**
 * The following block of code may be used to automatically register your
 * Vue components. It will recursively scan this directory for the Vue
 * components and automatically register them with their "basename".
 *
 * Eg. ./components/ExampleComponent.vue -> <example-component></example-component>
 */

// const files = require.context('./', true, /\.vue$/i)
// files.keys().map(key => Vue.component(key.split('/').pop().split('.')[0], files(key).default))

Vue.component('example-component', require('./components/ExampleComponent.vue').default);

/**
 * Next, we will create a fresh Vue application instance and attach it to
 * the page. Then, you may begin adding components to this application
 * or customize the JavaScript scaffolding to fit your unique needs.
 */

const app = new Vue({
    el: '#app',
});

** resources/js/components/ExampleComponent.vue **

<template>
    <div class="container">
        <div class="row justify-content-center">
            <div class="col-md-8">
                <div class="card">
                    <div class="card-header">Example Component</div>

                    <div class="card-body">
                        <!-- Using ziggy route helper here -->
                        <a :href="route('welcome')" class="btn">Go Home</a>
                    </div>
                </div>
            </div>
        </div>
    </div>
</template>

<script>
    export default {
        mounted() {
            console.log('Component mounted.')
        }
    }
</script>

Add built assets to your blade layout

<head>
    ...
   <script src="{{ mix('/js/app.js') }}" defer></script>
    <link href="{{ mix('/css/app.css') }}" rel="stylesheet">
</head>

Add Vue component to your blade view

<div id="app" class="content">
    <example-component/>
</div>

Build assets

yarn run dev

I haven’t used this package for a couple of years so something may have changed since my previous comments. I’m not sure without digging into it, but I don’t have time at the moment I’m afraid, sorry about that.

On Sat, 4 Dec 2021 at 05:46, Peter Weil @.***> wrote:

@markokeeffe https://github.com/markokeeffe I have been trying, without success, to get Ziggy to work with Vuex, and am applying the pattern you gave earlier in this thread. I’m not sure whether anything significant has changed in Ziggy since then, but I can’t seem to get “route” recognized. It keeps saying ReferenceError: route is not defined.

As for Mix aliases, the only one that allows Ziggy to work in Vue (v2) is

‘ziggy’: path.resolve(‘vendor/tightenco/ziggy/dist/vue.es.js’)

Of course this is different from your alias, and maybe that’s part of my problem. If you’re able to offer any suggestions, I’d be grateful.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/tighten/ziggy/issues/238#issuecomment-985783554, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAJHYAJIV2D5KASVQXQOBDDUPENCXANCNFSM4IXJDORQ . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

@aFluxx I haven’t had any issue using the file from dist.

If you reference the route.js file from the src directory, you will most likely have to update your webpack config to ensure the babel-loader will include that file to transpile the JS into a browser friendly ES5 syntax.

Requiring the route.js from the dist directory won’t have this problem as it’s already been transpiled.