question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

How to use static routes with mix and Vuejs

See original GitHub issue

Just starting to use this, and I’m a bit confused about how to use the artisan command in my Vuejs project.

I run the command to generate resources/assets/js/ziggy.js, but then what? I’ve tried adding require('./ziggy'); to app.js, but do I still need the blade directive? I think I do in order for the route() helper function to exist in JS, but then I think all the routing info is duplicated (i.e. the blade directive and ziggy.js define all the route).

And does the artisan command support groups in my config/ziggy.php?

Thanks in advance!

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Comments:13 (5 by maintainers)

github_iconTop GitHub Comments

1reaction
agm1984commented, May 21, 2019

Ok, I think I figured it out. First, dumping all the named routes into a publically-available <script> tag and window.Ziggy is a leaky abstraction in my opinion. I do not like how implementation details about routes are leaked to public users; however, an alternate solution exists, which is to use whitelist and blacklist. You can read more here: https://github.com/tightenco/ziggy

The solution described in this thread is probably what you want to do with Laravel/Vue.

Here is what I am doing now:

  1. Run php artisan ziggy:generate "resources/js/ziggy.js" (this will generate the route list into the same folder as your app.js file, and this is what makes import { Ziggy } from './ziggy' work, assuming you import that into your app.js file.

  2. Continuing from step 1, add this to your app.js file:

import { Ziggy } from './ziggy';
import route from '../../vendor/tightenco/ziggy/src/js/route';

Your relative folder may vary. If you are using VS Code, I recommend the extension Path Autocomplete because it will give you typeahead suggestions while typing the path. I usually do something like import route from '../'; and then follow the dropdown suggestions. It makes it easy to see what folder you are in. Here is a screenshot: image

  1. Create a global mixin right below there in app.js:
Vue.mixin({
    methods: {
        route: (name, params, absolute) => route(name, params, absolute, Ziggy),
    },
});
  1. Now you can access this.route('some.name') from any Vue component.

  2. You will notice that you need to run php artisan ziggy:generate every time you change web.php. This is horrifically annoying. I tried in my own app to make laravel-mix run that command every time a file changed, but it ended up being very non-trivial.

The closest I got was to install webpack-shell-plugin and make it so it rebuilt the ziggy.js file, but because I am using Webpack V3 (for dynamic imports and bundle splitting, V4 is too buggy), I was encountering some infinite loops where Webpack was rebuilding every time it rebuilt, due to a change in public/css/app.css which is post-processed by SASS and Tailwind (in my case). I also could not stop it by using BrowserSync’s or Webpack’s ignore options.

Your milage will vary. Try it using onBuildEnd with webpack-shell-plugin. If you are using Webpack V4, you can probably use afterEmit (see: https://stackoverflow.com/questions/30312715/run-command-after-webpack-build).

As a stop-gap fix, I have done the following: layout.blade.php

@if (\App::environment() != 'production')
    @routes
@endif

app.js

import route from '../../vendor/tightenco/ziggy/src/js/route';
// ...

if (process.env.NODE_ENV === 'production') {
    const { Ziggy } = require('./ziggy'); // eslint-disable-line global-require
    Vue.mixin({
        methods: {
            route: (name, params, absolute) => route(name, params, absolute, Ziggy),
        },
    });
} else {
    Vue.mixin({
        methods: {
            route,
        },
    });
}

webpack.config.js

const plugins = [
    // you can ignore this plugin; it's not related to this Ziggy thread
    new PurgecssPlugin({
        // Specify the locations of any files you want to scan for class names.
        paths: glob.sync([
            path.join(__dirname, 'resources/views/**/*.blade.php'),
            path.join(__dirname, 'resources/js/**/*.vue'),
        ]),
        extractors: [
            {
                extractor: TailwindExtractor,

                // Specify the file extensions to include when scanning for
                // class names.
                extensions: ['html', 'js', 'php', 'vue'],
            },
        ],
    }),
];

if (mix.inProduction()) {
    plugins.push(new WebpackShellPlugin({
        onBuildStart: ['php artisan ziggy:generate resources/js/ziggy.js'],
    }));
}

mix.webpackConfig({
    plugins,
});

The important thing to note is that I am pushing the shell plugin only in production mode. Webpack did not like when the plugins array contained falsy and/or non-function values because it assumes fn.call() and fn.apply() can be used on every entry.

The only other thing to note is that maintaining a difference between production and non-production environments is probably sub-optimal and could cause bugs over the lifespan of your app. If ever your environment flags do not initialize correctly, your routes may malfunction.

1reaction
codytookercommented, Jun 19, 2018

@rodrigopedra thanks for the info. This should work for me. I’ll test it out when I get back to working on the project again.

I think some info like this should probably be added to the readme file around generating the Custom Ziggy file.

Read more comments on GitHub >

github_iconTop Results From Across the Web

How to use static routes with mix and Vuejs #154 - GitHub
The command should support your config file. You'll need to import the route command in your Vue components https://github.com/tightenco/ziggy/ ...
Read more >
Dynamic routing using Vue Router - LogRocket Blog
In this tutorial, we'll explore dynamic routing in Vue using Vue Router, learning how it can improve our app's performance.
Read more >
Routes' Matching Syntax - Vue Router
Routes' Matching Syntax #. Watch a free video lesson on Vue School. Most applications will use static routes like /about and dynamic routes...
Read more >
Vuejs : how to mix static and dynamic content in template?
You can use javascript in attribute binding: <a :href="`#fiche?username=${username}`">. Or <a :href="'#fiche?username=' + username">.
Read more >
Route Props - A Vue.js Lesson From our Vue.js Course
Setting the route records props property to a function is the most versatile. It allows you to cast parameters into other types, combine...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found