MCPcopy
hub / github.com/tighten/ziggy

github.com/tighten/ziggy @v2.6.3 sqlite

repository ↗ · DeepWiki ↗ · release v2.6.3 ↗
43 symbols 71 edges 13 files 19 documented · 44%
README

Ziggy - Use your Laravel routes in JavaScript

Ziggy – Use your Laravel routes in JavaScript

GitHub Actions Status Latest Version on Packagist Downloads on Packagist Latest Version on NPM Downloads on NPM

Ziggy provides a JavaScript route() function that works like Laravel's, making it a breeze to use your named Laravel routes in JavaScript.

Installation

Install Ziggy in your Laravel app with Composer:

composer require tightenco/ziggy

Add the @routes Blade directive to your main layout (before your application's JavaScript), and the route() helper function will be available globally!

By default, the output of the @routes Blade directive includes a list of all your application's routes and their parameters. This route list is included in the HTML of the page and can be viewed by end users. To configure which routes are included in this list, or to show and hide different routes on different pages, see Filtering Routes.

Usage

route() function

Ziggy's route() function works like Laravel's route() helper—you can pass it the name of a route, and the parameters you want to pass to the route, and it will generate a URL.

Basic usage

Route::get('posts', fn (Request $request) => /* ... */)->name('posts.index');
route('posts.index'); // 'https://ziggy.test/posts'

Parameters

Route::get('posts/{post}', fn (Post $post) => /* ... */)->name('posts.show');
route('posts.show', 1);           // 'https://ziggy.test/posts/1'
route('posts.show', [1]);         // 'https://ziggy.test/posts/1'
route('posts.show', { post: 1 }); // 'https://ziggy.test/posts/1'

Multiple parameters

Route::get('venues/{venue}/events/{event}', fn (Venue $venue, Event $event) => /* ... */)
    ->name('venues.events.show');
route('venues.events.show', [1, 2]);                 // 'https://ziggy.test/venues/1/events/2'
route('venues.events.show', { venue: 1, event: 2 }); // 'https://ziggy.test/venues/1/events/2'

Query parameters

Ziggy adds arguments that don't match any named route parameters as query parameters:

Route::get('venues/{venue}/events/{event}', fn (Venue $venue, Event $event) => /* ... */)
    ->name('venues.events.show');
route('venues.events.show', {
    venue: 1,
    event: 2,
    page: 5,
    count: 10,
});
// 'https://ziggy.test/venues/1/events/2?page=5&count=10'

If you need to pass a query parameter with the same name as a route parameter, nest it under the special _query key:

route('venues.events.show', {
    venue: 1,
    event: 2,
    _query: {
        event: 3,
        page: 5,
    },
});
// 'https://ziggy.test/venues/1/events/2?event=3&page=5'

Like Laravel, Ziggy automatically encodes boolean query parameters as integers in the query string:

route('venues.events.show', {
    venue: 1,
    event: 2,
    _query: {
        draft: false,
        overdue: true,
    },
});
// 'https://ziggy.test/venues/1/events/2?draft=0&overdue=1'

Default parameter values

Ziggy supports default route parameter values (Laravel docs).

Route::get('{locale}/posts/{post}', fn (Post $post) => /* ... */)->name('posts.show');
// app/Http/Middleware/SetLocale.php

URL::defaults(['locale' => $request->user()->locale ?? 'de']);
route('posts.show', 1); // 'https://ziggy.test/de/posts/1'

Examples

HTTP request with axios:

const post = { id: 1, title: 'Ziggy Stardust' };

return axios.get(route('posts.show', post)).then((response) => response.data);

Router class

Calling Ziggy's route() function with no arguments will return an instance of its JavaScript Router class, which has some other useful properties and methods.

Check the current route: route().current()

// Laravel route called 'events.index' with URI '/events'
// Current window URL is https://ziggy.test/events

route().current();               // 'events.index'
route().current('events.index'); // true
route().current('events.*');     // true
route().current('events.show');  // false

route().current() optionally accepts parameters as its second argument, and will check that their values also match in the current URL:

// Laravel route called 'venues.events.show' with URI '/venues/{venue}/events/{event}'
// Current window URL is https://myapp.com/venues/1/events/2?hosts=all

route().current('venues.events.show', { venue: 1 });           // true
route().current('venues.events.show', { venue: 1, event: 2 }); // true
route().current('venues.events.show', { hosts: 'all' });       // true
route().current('venues.events.show', { venue: 6 });           // false

Check if a route exists: route().has()

// Laravel app has only one named route, 'home'

route().has('home');   // true
route().has('orders'); // false

Retrieve the current route params: route().params

// Laravel route called 'venues.events.show' with URI '/venues/{venue}/events/{event}'
// Current window URL is https://myapp.com/venues/1/events/2?hosts=all

route().params; // { venue: '1', event: '2', hosts: 'all' }

Note: parameter values retrieved with route().params will always be returned as strings.

Route-model binding

Ziggy supports Laravel's route-model binding, and can even recognize custom route key names. If you pass route() a JavaScript object as a route parameter, Ziggy will use the registered route-model binding keys for that route to find the correct parameter value inside the object. If no route-model binding keys are explicitly registered for a parameter, Ziggy will use the object's id key.

// app/Models/Post.php

class Post extends Model
{
    public function getRouteKeyName()
    {
        return 'slug';
    }
}
Route::get('blog/{post}', function (Post $post) {
    return view('posts.show', ['post' => $post]);
})->name('posts.show');
const post = {
    id: 3,
    title: 'Introducing Ziggy v1',
    slug: 'introducing-ziggy-v1',
    date: '2020-10-23T20:59:24.359278Z',
};

// Ziggy knows that this route uses the 'slug' route-model binding key:

route('posts.show', post); // 'https://ziggy.test/blog/introducing-ziggy-v1'

Ziggy also supports custom keys for scoped bindings declared directly in a route definition:

Route::get('authors/{author}/photos/{photo:uuid}', fn (Author $author, Photo $photo) => /* ... */)
    ->name('authors.photos.show');
const photo = {
    uuid: '714b19e8-ac5e-4dab-99ba-34dc6fdd24a5',
    filename: 'sunset.jpg',
}

route('authors.photos.show', [{ id: 1, name: 'Ansel' }, photo]);
// 'https://ziggy.test/authors/1/photos/714b19e8-ac5e-4dab-99ba-34dc6fdd24a5'

TypeScript

Ziggy includes TypeScript type definitions, and an Artisan command that can generate additional type definitions to enable route name and parameter autocompletion.

To generate route types, run the ziggy:generate command with the --types or --types-only option:

php artisan ziggy:generate --types

To make your IDE aware that Ziggy's route() helper is available globally, and to type it correctly, add a declaration like this in a .d.ts file somewhere in your project:

import { route as routeFn } from 'ziggy-js';

declare global {
    var route: typeof routeFn;
}

If you don't have Ziggy's NPM package installed, add the following to your jsconfig.json or tsconfig.json to load Ziggy's types from your vendor directory:

{
    "compilerOptions": {
        "paths": {
            "ziggy-js": ["./vendor/tightenco/ziggy"]
        }
    }
}

Strict route name type checking

By default, even when you generate type definitions to enable better autocompletion, Ziggy still allows passing any string to route(). You can optionally enable strict type checking of route names, so that calling route() with a route name Ziggy doensn't recognizes triggers a type error. To do so, extend Ziggy's TypeConfig interface and set strictRouteNames to true:

declare module 'ziggy-js' {
  interface TypeConfig {
    strictRouteNames: true
  }
}

Place this declaration in a .d.ts type definition file somewhere in your project. Depending on your setup, you may need to add an export {}; statement to the end of file so TypeScript can pick it up.

JavaScript frameworks

[!NOTE] Many applications don't need the additional setup described here—the @routes Blade directive makes Ziggy's route() function and config available globally, including within bundled JavaScript files.

If you are not using the @routes Blade directive, you can import Ziggy's route() function and configuration directly into JavaScript/TypeScript files.

Generating and importing Ziggy's configuration

Ziggy provides an Artisan command to output its config and routes to a file:

php artisan ziggy:generate

This command places your configuration in resources/js/ziggy.js by default, but you can customize this path by passing an argument to the Artisan command or setting the ziggy.output.path config value.

The file ziggy:generate creates looks something like this:

// resources/js/ziggy.js

const Ziggy = {
    url: 'https://ziggy.test',
    port: null,
    routes: {
        home: {
            uri: '/',
            methods: [ 'GET', 'HEAD'],
            domain: null,
        },
        login: {
            uri: 'login',
            methods: ['GET', 'HEAD'],
            domain: null,
        },
    },
};

export { Ziggy };

Importing the route() function

You can import Ziggy like any other JavaScript library. Without the @routes Blade directive Ziggy's config is not available globally, so it must be passed to the route() function manually:

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

route('home', undefined, undefined, Ziggy);

To simplify importing the route() function, you can create an alias to the vendor path:

// vite.config.js

export default defineConfig({
    resolve: {
        alias: {
            'ziggy-js': path.resolve('vendor/tightenco/ziggy'),
        },
    },
});

Now your imports can be shortened to:

import { route } from 'ziggy-js';

Vue

Ziggy includes a Vue plugin to make it easy to use the route() helper throughout your Vue app:

import { createApp } from 'vue';
import { ZiggyVue } from 'ziggy-js';
import App from './App.vue';

createApp(App).use(ZiggyVue);

Now you can use the route() function anywhere in your Vue components and templates:

<a class="nav-link" :href="https://github.com/tighten/ziggy/raw/v2.6.3/route('home')">Home</a>

With <script setup> in Vue 3 you can use inject to make the route() function available in your component script:

<script setup>
import { inject } from 'vue';

const route = inject('route');
</script>

If you are not using the @routes Blade directive, import Ziggy's configuration too and pass it to .use():

import { createApp } from 'vue';
import { ZiggyVue } from 'ziggy-js';
import { Ziggy } from './ziggy.js';
import App from './App.vue';

createApp(App).use(ZiggyVue, Ziggy);

If you're using TypeScript, you may need to add the following declaration to a .d.ts file in your project to avoid type errors when using the route() function in your Vue component templates:

declare module 'vue' {
    interface ComponentCustomProperties {
        route: typeof routeFn;
    }
}

React

Ziggy includes a useRoute() hook to make it easy to use the route() helper in your React app:

import React from 'react';
import { useRoute } from 'ziggy-js';

export default function PostsLink() {
    const route = useRoute();

    return <a href={route('posts.index')}>Posts</a>;
}

If you are not using the @routes Blade directive, import Ziggy's configuration too and pass it to useRoute():

import React from 'react';
import { useRoute } from 'ziggy-js';
import { Ziggy } from './ziggy.js';

export default function PostsLink() {
    const route = useRoute(Ziggy);

    return <a href={route('posts.index')}>Posts</a>;
}

You can also make the Ziggy config object available globally, so you can call useRoute() without passing Ziggy'

Extension points exported contracts — how you extend this code

Router (Interface)
* Ziggy's Router class. [1 implementers]
src/js/index.d.ts
RouteList (Interface)
(no doc)
tests/js/route.test-d.ts
RouteList (Interface)
(no doc)
tests/fixtures/ziggy.d.ts
Route (Interface)
* A route.
src/js/index.d.ts
Model (Interface)
(no doc)
tests/js/route.test-d.ts
Config (Interface)
* Ziggy's config object.
src/js/index.d.ts
RouteList (Interface)
(no doc)
src/js/index.d.ts
TypeConfig (Interface)
(no doc)
src/js/index.d.ts

Core symbols most depended-on inside this repo

route
called by 366
src/js/index.js
current
called by 184
src/js/index.d.ts
_unresolve
called by 4
src/js/Router.js
has
called by 3
src/js/index.d.ts
toString
called by 2
src/js/Router.js
_location
called by 2
src/js/Router.js
_parse
called by 2
src/js/Router.js
matchesUrl
called by 1
src/js/Route.js

Shape

Method 26
Interface 9
Class 4
Function 4

Languages

TypeScript100%

Modules by API surface

src/js/Router.js17 symbols
src/js/index.d.ts11 symbols
src/js/Route.js8 symbols
src/js/index.js4 symbols
tests/js/route.test-d.ts2 symbols
tests/fixtures/ziggy.d.ts1 symbols

Dependencies from manifests, versioned

laravel/framework>=9.0 · 1×
jsdom28.1.0 · 1×
microbundle0.15.1 · 1×
prettier3.8.1 · 1×
qs-esm7.0.3 · 1×
typescript5.9.3 · 1×
vitest4.0.18 · 1×

For agents

$ claude mcp add ziggy \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact