1![Ziggy - Use your Laravel named routes in JavaScript](https://raw.githubusercontent.com/tightenco/ziggy/master/ziggy-banner.png?version=3)
2
3# Ziggy – Use your Laravel named routes in JavaScript
4
5[![GitHub Actions Status](https://img.shields.io/github/workflow/status/tightenco/ziggy/Tests?label=tests&style=flat)](https://github.com/tightenco/ziggy/actions?query=workflow:Tests+branch:master)
6[![Latest Version on Packagist](https://img.shields.io/packagist/v/tightenco/ziggy.svg?style=flat)](https://packagist.org/packages/tightenco/ziggy)
7[![Downloads on Packagist](https://img.shields.io/packagist/dt/tightenco/ziggy.svg?style=flat)](https://packagist.org/packages/tightenco/ziggy)
8[![Latest Version on NPM](https://img.shields.io/npm/v/ziggy-js.svg?style=flat)](https://npmjs.com/package/ziggy-js)
9[![Downloads on NPM](https://img.shields.io/npm/dt/ziggy-js.svg?style=flat)](https://npmjs.com/package/ziggy-js)
10
11Ziggy creates a Blade directive that you can include in your views. It will export a JavaScript object of your application's named routes, keyed by their names (aliases), as well as a global `route()` helper function which you can use to access your routes in your JavaScript.
12
13Ziggy supports all versions of Laravel from `5.4` to `7.x`.
14
15## Contents
16
17- [Installation](#installation)
18- [Usage](#usage)
19    - [Examples](#examples)
20    - [Default Values](#default-values)
21- [Filtering Routes](#filtering-routes)
22    - [Basic Whitelisting & Blacklisting](#basic-whitelisting--blacklisting)
23    - [Basic Whitelisting & Blacklisting using Macros](#basic-whitelisting--blacklisting-using-macros)
24    - [Advanced Whitelisting using Groups](#advanced-whitelisting-using-groups)
25- [Other Useful Methods](#other-useful-methods)
26    - [`current()`](#current)
27    - [`url()`](#url)
28- [Artisan Command](#artisan-command)
29- [Using with Vue Components](#using-with-vue-components)
30- [Other](#other)
31- [Contributing](#contributing)
32- [Credits](#credits)
33- [Security](#security)
34- [License](#license)
35
36## Installation
37
381. Install Ziggy using Composer: `composer require tightenco/ziggy`.
391. If using Laravel 5.4, add `Tightenco\Ziggy\ZiggyServiceProvider::class` to the `providers` array in your `config/app.php`.
401. Include our Blade directive (`@routes`) somewhere in your template before your main application JavaScript is loaded—likely in the header somewhere.
41
42## Usage
43
44This package uses the `@routes` directive to inject a JavaScript object containing all of your application's routes, keyed by their names. This collection is available at `Ziggy.namedRoutes`.
45
46The package also creates an optional `route()` JavaScript helper that functions like Laravel's PHP `route()` helper, which can be used to retrieve URLs by name and (optionally) parameters.
47
48#### Examples
49
50Without parameters:
51
52```js
53route('posts.index'); // Returns '/posts'
54```
55
56With required parameter:
57
58```js
59route('posts.show', { id: 1 }); // Returns '/posts/1'
60route('posts.show', [1]); // Returns '/posts/1'
61route('posts.show', 1); // Returns '/posts/1'
62```
63
64With multiple required parameters:
65
66```js
67route('events.venues.show', { event: 1, venue: 2 }); // Returns '/events/1/venues/2'
68route('events.venues.show', [1, 2]); // Returns '/events/1/venues/2'
69```
70
71With query parameters:
72
73```js
74route('events.venues.show', { event: 1, venue: 2, page: 5, count: 10 }); // Returns '/events/1/venues/2?page=5&count=10'
75```
76
77If whole objects are passed, Ziggy will automatically look for an `id` primary key:
78
79```js
80let event = { id: 1, name: 'World Series' };
81let venue = { id: 2, name: 'Rogers Centre' };
82
83route('events.venues.show', [event, venue]); // Returns '/events/1/venues/2'
84```
85
86Practical AJAX example:
87
88```js
89let post = { id: 1, title: 'Ziggy Stardust' };
90
91return axios.get(route('posts.show', post))
92    .then((response) => {
93        return response.data;
94    });
95```
96
97_Note: If you are using Axios and making requests that require CSRF verification, use the [`url()` method](#url) on the route (documented below). This will ensure that the `X-XSRF-TOKEN` header is sent with the request._
98
99#### Default Values
100
101See the [Laravel documentation on default route parameter values](https://laravel.com/docs/urls#default-values).
102
103Default values work out of the box for Laravel versions >= 5.5.29, for previous versions you will need to set the default parameters by including this code somewhere in the same page as Ziggy's `@routes` Blade directive.
104
105```js
106Ziggy.defaultParameters = {
107    // example
108    locale: 'en',
109};
110```
111
112## Filtering Routes
113
114Filtering routes is _completely optional_. If you want to pass all of your routes to your JavaScript by default, you can carry on using Ziggy as described above.
115
116#### Basic Whitelisting & Blacklisting
117
118To take advantage of basic whitelisting or blacklisting of routes, you will first need to create a config file in your Laravel app at `config/ziggy.php` and define **either** a `whitelist` or `blacklist` setting as an array of route name patterns.
119
120**Note: You have to choose one or the other. Setting `whitelist` and `blacklist` will disable filtering altogether and simply return the default list of routes.**
121
122Example `config/ziggy.php`:
123
124```php
125return [
126    // 'whitelist' => ['home', 'api.*'],
127    'blacklist' => ['debugbar.*', 'horizon.*', 'admin.*'],
128];
129```
130
131As shown in the example above, Ziggy can use asterisks as wildcards in route filter patterns. `home` will only match the route named `home`, whereas `api.*` will match any route whose name begins with `api.`, such as `api.posts.index` and `api.users.show`.
132
133#### Basic Whitelisting & Blacklisting using Macros
134
135Whitelisting and blacklisting can also be achieved using the following macros.
136
137Example whitelisting:
138
139```php
140Route::whitelist(function () {
141    Route::get('...')->name('posts');
142});
143
144Route::whitelist()->get('...')->name('posts');
145```
146
147Example blacklisting:
148
149```php
150Route::blacklist(function () {
151    Route::get('...')->name('posts');
152});
153
154Route::blacklist()->get('...')->name('posts');
155```
156
157#### Advanced Whitelisting using Groups
158
159You may also optionally define multiple whitelists using a `groups` key in your `config/ziggy.php`:
160
161```php
162return [
163    'groups' => [
164        'admin' => [
165            'admin.*',
166            'posts.*',
167        ],
168        'author' => [
169            'posts.*',
170        ],
171    ],
172];
173```
174
175In the above example, you can see we have configured multiple whitelists for different user roles. You may expose a specific whitelist group by passing the group key into the `@routes` directive in your Blade view:
176
177```php
178@routes('author')
179```
180
181If you want to expose multiple groups you can pass an array of group names:
182
183```php
184@routes(['admin', 'author'])
185```
186
187**Note: Passing group names to the `@routes` directive will always take precedence over your other `whitelist` and `blacklist` settings.**
188
189## Other Useful Methods
190
191#### `current()`
192
193To get the name of the current route based on the browser's `window.location`, you can use:
194
195```js
196route().current();
197// returns 'events.index'
198```
199
200To check whether you are currently on a specific route, you can pass the route name to `current()`:
201
202```js
203route().current('events.index');
204// returns true
205```
206
207You can even use wildcards to check if you're on any of the routes in a given 'group':
208
209```js
210route().current('events.*');
211// returns true
212```
213
214#### `url()`
215
216Ziggy returns a wrapper of the JavaScript [String primitive](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String), which behaves exactly like a string in almost all cases. In rare cases, such as when third-party libraries use strict type checking, you may need an actual string literal.
217
218To achieve this you can call `url()` on your route:
219
220```js
221route('home').url();
222// returns 'https://ziggy.test/'
223```
224
225## Artisan Command
226
227Ziggy registers an Artisan console command to generate a `ziggy.js` routes file, which can be used as part of an asset pipeline such as [Laravel Mix](https://laravel.com/docs/mix).
228
229You can run `php artisan ziggy:generate` in your project to generate a static routes file in `resources/assets/js/ziggy.js`. You can optionally include a second parameter to override the path and file name (you must pass a complete path, including the file name):
230
231```sh
232php artisan ziggy:generate "resources/foo.js"
233```
234
235Example `ziggy.js`, where the named routes `home` and `login` exist in `routes/web.php`:
236
237```php
238// routes/web.php
239
240Route::get('/', function () {
241    return view('welcome');
242})->name('home');
243
244Route::get('/login', function () {
245    return view('login');
246})->name('login');
247```
248
249```js
250// ziggy.js
251
252var Ziggy = {
253    namedRoutes: {"home":{"uri":"\/","methods":["GET","HEAD"],"domain":null},"login":{"uri":"login","methods":["GET","HEAD"],"domain":null}},
254    baseUrl: 'http://ziggy.test/',
255    baseProtocol: 'http',
256    baseDomain: 'ziggy.test',
257    basePort: false
258};
259
260export {
261    Ziggy
262};
263```
264
265Importing the `route()` helper and generated `ziggy.js`
266
267```js
268// webpack.mix.js
269const path = require('path');
270
271mix.webpackConfig({
272    resolve: {
273        alias: {
274            ziggy: path.resolve('vendor/tightenco/ziggy/src/js/route.js'),
275        },
276    },
277});
278```
279
280```js
281// app.js
282
283import route from 'ziggy';
284import { Ziggy } from './ziggy';
285```
286
287## Using with Vue Components
288
289If you want to use the `route()` helper in a Vue component, add this to your `app.js` file:
290
291```js
292// app.js
293
294import route from 'ziggy';
295import { Ziggy } from './ziggy';
296
297Vue.mixin({
298    methods: {
299        route: (name, params, absolute) => route(name, params, absolute, Ziggy),
300    },
301});
302```
303
304Then you can use the method in your Vue components like so:
305
306```html
307<a class="nav-link" :href="route('home')">Home</a>
308```
309
310Thanks to [Archer70](https://github.com/tightenco/ziggy/issues/70#issuecomment-369129032) for this solution.
311
312## Other
313
314**Environment-based loading of minified route helper file**
315
316When using the `@routes` Blade directive, Ziggy will detect the current environment and minify the output if `APP_ENV` is not `local`. In this case, `ziggy.min.js` will be loaded—otherwise, `ziggy.js` will be used.
317
318**Disabling the `route()` helper**
319
320If you only want to use the `@routes` directive to make your app's routes available in JavaScript, but don't need the `route()` helper function, you can set `skip-route-function` to `true` in your config:
321
322```php
323// config/ziggy.php
324
325return [
326    'skip-route-function' => true,
327];
328```
329
330## Contributing
331
332To get started contributing to Ziggy, check out [the contribution guide](CONTRIBUTING.md).
333
334## Credits
335
336- [Daniel Coulbourne](https://twitter.com/DCoulbourne)
337- [Jake Bathman](https://twitter.com/jakebathman)
338- [Matt Stauffer](https://twitter.com/stauffermatt)
339- [Jacob Baker-Kretzmar](https://twitter.com/bakerkretzmar)
340- [All contributors](https://github.com/tightenco/ziggy/contributors)
341
342Thanks to [Caleb Porzio](http://twitter.com/calebporzio), [Adam Wathan](http://twitter.com/adamwathan), and [Jeffrey Way](http://twitter.com/jeffrey_way) for help solidifying the idea.
343
344## Security
345
346If you discover any security related issues, please email <hello@tighten.co> instead of using the issue tracker.
347
348## License
349
350Ziggy is open source software licensed under the MIT license. See [LICENSE.md](LICENSE.md) for more information.
351