> ## Documentation Index
> Fetch the complete documentation index at: https://kawax.biz/llms.txt
> Use this file to discover all available pages before exploring further.

# URL generation

> Learn how to generate URLs in Laravel using the url() helper, named routes, signed URLs, and controller action URLs.

## Introduction

Laravel provides several helpers to assist you in generating URLs for your application.
These helpers are primarily useful when building links in your templates and API responses, or when generating redirect responses to another part of your application.

## Basic usage

### Generating URLs

You can use the `url` helper to generate arbitrary URLs.
The generated URL will automatically use the scheme (HTTP or HTTPS) and host of the current request the application is handling.

```php theme={null}
$post = App\Models\Post::find(1);

echo url("/posts/{$post->id}");

// http://example.com/posts/1
```

To generate a URL with query string parameters, use the `query` method.

```php theme={null}
echo url()->query('/posts', ['search' => 'Laravel']);

// https://example.com/posts?search=Laravel

echo url()->query('/posts?sort=latest', ['search' => 'Laravel']);

// http://example.com/posts?sort=latest&search=Laravel
```

If you provide query string parameters that already exist in the path, the existing values will be overridden.

```php theme={null}
echo url()->query('/posts?sort=latest', ['sort' => 'oldest']);

// http://example.com/posts?sort=oldest
```

You can also pass array values as query parameters. These values will be properly keyed and encoded in the generated URL.

```php theme={null}
echo $url = url()->query('/posts', ['columns' => ['title', 'body']]);

// http://example.com/posts?columns%5B0%5D=title&columns%5B1%5D=body

echo urldecode($url);

// http://example.com/posts?columns[0]=title&columns[1]=body
```

### Accessing the current URL

If no path is provided to the `url` helper, an `Illuminate\Routing\UrlGenerator` instance is returned, allowing you to access information about the current URL.

```php theme={null}
// The current URL without the query string
echo url()->current();

// The current URL including the query string
echo url()->full();
```

Each of these methods may also be accessed via the `URL` [facade](./facades).

```php theme={null}
use Illuminate\Support\Facades\URL;

echo URL::current();
```

### Accessing the previous URL

Sometimes you want to know the URL of the previous page the user was visiting. You can use the `previous` or `previousPath` method on the `url` helper.

```php theme={null}
// The full URL of the previous request
echo url()->previous();

// The path of the previous request
echo url()->previousPath();
```

You can also retrieve the previous URL via the session.

```php theme={null}
use Illuminate\Http\Request;

Route::post('/users', function (Request $request) {
    $previousUri = $request->session()->previousUri();

    // ...
});
```

You can also retrieve the route name of the previously visited URL via the session.

```php theme={null}
$previousRoute = $request->session()->previousRoute();
```

## URLs for named routes

The `route` helper may be used to generate URLs to [named routes](./routing#named-routes).
Named routes allow you to generate URLs without being coupled to the actual URL defined on the route.
Therefore, if the route's URL changes, no changes need to be made to your `route` function calls.

```php theme={null}
Route::get('/post/{post}', function (Post $post) {
    // ...
})->name('post.show');
```

Generate a URL to this route as follows.

```php theme={null}
echo route('post.show', ['post' => 1]);

// http://example.com/post/1
```

Routes with multiple parameters work as expected.

```php theme={null}
Route::get('/post/{post}/comment/{comment}', function (Post $post, Comment $comment) {
    // ...
})->name('comment.show');

echo route('comment.show', ['post' => 1, 'comment' => 3]);

// http://example.com/post/1/comment/3
```

Any additional array elements that do not correspond to the route's defined parameters will be added to the URL's query string.

```php theme={null}
echo route('post.show', ['post' => 1, 'search' => 'rocket']);

// http://example.com/post/1?search=rocket
```

### Eloquent models

You will often be generating URLs using the route key of an Eloquent model (usually its primary key).
For this reason, you may pass Eloquent models as parameter values. The `route` helper automatically extracts the model's route key.

```php theme={null}
echo route('post.show', ['post' => $post]);
```

### Signed URLs

Laravel allows you to easily create "signed" URLs to named routes.
These URLs have a "signature" hash appended to the query string, which allows Laravel to verify that the URL has not been modified since it was created.
Signed URLs are especially useful for routes that are publicly accessible but need protection against URL manipulation.

For example, you might use signed URLs to implement a public "unsubscribe" link that is sent to your customers via email.
To create a signed URL to a named route, use the `signedRoute` method of the `URL` facade.

```php theme={null}
use Illuminate\Support\Facades\URL;

return URL::signedRoute('unsubscribe', ['user' => 1]);
```

You can exclude the domain from the signed URL hash by providing the `absolute` argument to the `signedRoute` method.

```php theme={null}
return URL::signedRoute('unsubscribe', ['user' => 1], absolute: false);
```

If you want to generate a temporary signed route URL that expires after a specified amount of time, use the `temporarySignedRoute` method.
When Laravel validates a temporary signed route URL, it ensures that the expiration timestamp encoded in the signed URL has not elapsed.

```php theme={null}
use Illuminate\Support\Facades\URL;

return URL::temporarySignedRoute(
    'unsubscribe', now()->plus(minutes: 30), ['user' => 1]
);
```

#### Signed URL validation flow

```mermaid theme={null}
sequenceDiagram
    participant App as Laravel app
    participant User as User
    participant Mail as Email
    App->>App: URL::signedRoute() / temporarySignedRoute()
    App->>Mail: Send signed URL via email
    Mail->>User: User receives email
    User->>App: Click URL (GET request)
    App->>App: Verify signature<br>hasValidSignature()
    alt Signature valid
        App->>User: Execute action (e.g. unsubscribe)
    else Signature invalid or expired
        App->>User: 403 error
    end
```

#### Validating signed route requests

To verify that an incoming request has a valid signature, call the `hasValidSignature` method on the `Illuminate\Http\Request` instance.

```php theme={null}
use Illuminate\Http\Request;

Route::get('/unsubscribe/{user}', function (Request $request) {
    if (! $request->hasValidSignature()) {
        abort(401);
    }

    // ...
})->name('unsubscribe');
```

If you want to ignore certain query parameters during validation, use `hasValidSignatureWhileIgnoring`.

```php theme={null}
if (! $request->hasValidSignatureWhileIgnoring(['page', 'order'])) {
    abort(401);
}
```

Instead of using the incoming request instance, you can assign the `signed` (`Illuminate\Routing\Middleware\ValidateSignature`) [middleware](./middleware) to your route.
If the incoming request does not have a valid signature, the middleware will automatically return a `403` HTTP response.

```php theme={null}
Route::post('/unsubscribe/{user}', function (Request $request) {
    // ...
})->name('unsubscribe')->middleware('signed');
```

If your signed URLs do not include the domain, provide the `relative` argument to the middleware.

```php theme={null}
Route::post('/unsubscribe/{user}', function (Request $request) {
    // ...
})->name('unsubscribe')->middleware('signed:relative');
```

#### Responding to invalid signed routes

When someone visits an expired signed URL, they receive a generic error page for the `403` HTTP status code.
You can customize this by defining a custom "render" closure for the `InvalidSignatureException` exception in your application's `bootstrap/app.php` file.

```php theme={null}
use Illuminate\Routing\Exceptions\InvalidSignatureException;

->withExceptions(function (Exceptions $exceptions): void {
    $exceptions->render(function (InvalidSignatureException $e) {
        return response()->view('errors.link-expired', status: 403);
    });
})
```

## URLs for controller actions

The `action` function generates a URL for the given controller action.

```php theme={null}
use App\Http\Controllers\HomeController;

$url = action([HomeController::class, 'index']);
```

If the controller method accepts route parameters, pass an associative array of parameters as the second argument to the function.

```php theme={null}
$url = action([UserController::class, 'profile'], ['id' => 1]);
```

## Fluent URI objects

Laravel's URI class provides a convenient, fluent interface for creating and manipulating URIs via objects.

```php theme={null}
use App\Http\Controllers\UserController;
use Illuminate\Support\Uri;

// Generate a URI instance from a string
$uri = Uri::of('https://example.com/path');

// Generate URIs for a path, named route, or controller action
$uri = Uri::to('/dashboard');
$uri = Uri::route('users.show', ['user' => 1]);
$uri = Uri::signedRoute('users.show', ['user' => 1]);
$uri = Uri::temporarySignedRoute('user.index', now()->plus(minutes: 5));
$uri = Uri::action([UserController::class, 'index']);

// Generate a URI instance from the current request URL
$uri = $request->uri();
```

Once you have a URI instance, you can modify it fluently.

```php theme={null}
$uri = Uri::of('https://example.com')
    ->withScheme('http')
    ->withHost('test.com')
    ->withPort(8000)
    ->withPath('/users')
    ->withQuery(['page' => 2])
    ->withFragment('section-1');
```

## Default URL parameters

Sometimes you may wish to specify request-wide default values for certain URL parameters.
For example, imagine many of your routes have a `{locale}` parameter.

```php theme={null}
Route::get('/{locale}/posts', function () {
    // ...
})->name('post.index');
```

It's cumbersome to pass the `locale` every time you call the `route` helper.
So you can use the `URL::defaults` method to define a default value for this parameter that will always be applied during the current request.
You may want to call this method from a [route middleware](./middleware#assigning-middleware-to-routes) so you have access to the current request.

```php theme={null}
<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\URL;
use Symfony\Component\HttpFoundation\Response;

class SetDefaultLocaleForUrls
{
    /**
     * Handle an incoming request.
     *
     * @param  \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response)  $next
     */
    public function handle(Request $request, Closure $next): Response
    {
        URL::defaults(['locale' => $request->user()->locale]);

        return $next($request);
    }
}
```

Once the default value for the `locale` parameter has been set, you no longer need to pass its value when generating URLs via the `route` helper.

<Info>
  Setting URL defaults may interfere with Laravel's handling of implicit model bindings.
  Therefore, you should [prioritize your middleware](./middleware) so that middleware that set URL defaults are executed before Laravel's own `SubstituteBindings` middleware.
  You can accomplish this using the `priority` middleware method in your application's `bootstrap/app.php` file.

  ```php theme={null}
  ->withMiddleware(function (Middleware $middleware): void {
      $middleware->prependToPriorityList(
          before: \Illuminate\Routing\Middleware\SubstituteBindings::class,
          prepend: \App\Http\Middleware\SetDefaultLocaleForUrls::class,
      );
  })
  ```
</Info>


## Related topics

- [Helper functions](/en/helpers.md)
- [Remote Sessions](/en/packages/laravel-copilot-sdk/remote-sessions.md)
- [Guide to Building Apps with VOICEVOX Engine API](/en/packages/laravel-voicevox/app-guide.md)
- [Laravel AI SDK](/en/ai-sdk.md)
- [Laravel 13 new features overview](/en/blog/laravel-13-new-features.md)
