PHP Logotightenco/ziggy

Ziggy is a Composer package for Laravel that bridges the gap between your server-side Laravel named routes and your client-side JavaScript applications. In modern web development, it's common to build Single Page Applications (SPAs) or interactive front-ends with JavaScript frameworks (like Vue, React, Angular, or even vanilla JS) that need to interact with your Laravel backend. A frequent challenge is generating URLs for API endpoints or other server routes directly within your JavaScript code.

Traditionally, developers might hardcode URLs in JavaScript, which can lead to issues when routes change on the backend. Alternatively, they might pass URLs from PHP to JavaScript through data attributes or global variables, but this can become cumbersome for many routes or routes requiring parameters.

Ziggy solves this by providing a simple way to expose your Laravel named routes directly to JavaScript. It generates a JavaScript object containing all your defined routes (or a filtered subset), which can then be used with a global `route()` helper function in your JavaScript code. This `route()` helper mimics Laravel's `route()` helper, allowing you to generate URLs dynamically in JavaScript with proper route names and parameters, ensuring consistency and reducing maintenance overhead.

Key features and benefits:

* Dynamic URL Generation: Generate URLs in JavaScript using named routes, similar to how you do it in PHP.
* Parameter Handling: Easily pass parameters to routes, just like Laravel's `route()` helper.
* Consistency: Ensures your JavaScript always uses the correct URLs defined in your Laravel application, even if the URL patterns change.
* Maintainability: Avoids hardcoding URLs in JavaScript, making your front-end code more robust and easier to update.
* Filtering: You can choose to expose only specific routes or groups of routes, preventing unnecessary route data from being sent to the client.
* Custom Domains: Supports generating routes for different domains if your application requires it.
* TypeScript Support: Provides TypeScript definitions for better development experience with TypeScript projects.

Under the hood, Ziggy works by using a Blade directive (`@routes`) to render a JavaScript `script` tag that exports the route data. This data includes the route name, URI, and any default parameters, making it accessible to the global `route()` function provided by Ziggy's JavaScript library.

Example Code

```php
// 1. Install Ziggy via Composer
// composer require tightenco/ziggy

// 2. Publish the Ziggy configuration (optional, but good practice)
// php artisan vendor:publish --tag=ziggy-config

// 3. Define some Laravel routes in routes/web.php or routes/api.php
// For this example, let's use web.php

// routes/web.php
use Illuminate\Support\Facades\Route;

Route::get('/', function () {
    return view('welcome');
});

Route::get('/posts', function () {
    return 'List of posts';
})->name('posts.index');

Route::get('/posts/{id}', function ($id) {
    return "Viewing post #{$id}";
})->name('posts.show');

Route::get('/users/{name?}', function ($name = 'Guest') {
    return "Hello, {$name}!";
})->name('users.greet');

// 4. Include Ziggy's routes in your Blade layout file (e.g., resources/views/layouts/app.blade.php
// or resources/views/welcome.blade.php for this simple example)

// resources/views/welcome.blade.php
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Ziggy Example</title>
    <!-- Ziggy's @routes Blade directive must be included before your custom JavaScript -->
    @routes
</head>
<body>
    <h1>Welcome to Ziggy Example!</h1>
    <p>Check the console for JavaScript route generation.</p>

    <script>
        // Ziggy provides a global 'route' function after @routes is rendered
        document.addEventListener('DOMContentLoaded', function() {
            console.log('--- Ziggy Routes in JavaScript ---');

            // 1. Get a simple route without parameters
            const postsIndexUrl = route('posts.index');
            console.log('URL for posts.index:', postsIndexUrl);
            // Expected output: /posts

            // 2. Get a route with a required parameter
            const postShowUrl = route('posts.show', { id: 123 });
            console.log('URL for posts.show (id=123):', postShowUrl);
            // Expected output: /posts/123

            // 3. Get a route with an optional parameter (provided)
            const userGreetJohnUrl = route('users.greet', { name: 'John Doe' });
            console.log('URL for users.greet (name=John Doe):', userGreetJohnUrl);
            // Expected output: /users/John%20Doe

            // 4. Get a route with an optional parameter (not provided, uses default)
            const userGreetDefaultUrl = route('users.greet');
            console.log('URL for users.greet (default):', userGreetDefaultUrl);
            // Expected output: /users

            // 5. Example of using the URL with fetch API (conceptual)
            // fetch(postShowUrl)
            //     .then(response => response.text())
            //     .then(data => console.log('Fetched Data:', data));
        });
    </script>
</body>
</html>
```