> ## 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's genereren

> Leer hoe je URL's genereert met de url()-helper van Laravel, named route-URL's, signed URL's en controller action-URL's.

## Inleiding

Laravel biedt verschillende helpers om URL's voor je applicatie te genereren.
Deze zijn vooral handig bij het bouwen van links in templates of API-responses, of bij het genereren van redirect-responses naar een andere plek in je applicatie.

## Basisgebruik

### URL's genereren

Met de `url` helper kun je willekeurige URL's genereren.
De gegenereerde URL gebruikt automatisch het schema (HTTP of HTTPS) en de host van het huidige request dat de applicatie verwerkt.

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

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

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

Gebruik de `query` methode om een URL met querystring-parameters te genereren.

```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
```

Geef je querystring-parameters op die al in het pad voorkomen, dan worden de bestaande waarden overschreven.

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

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

Je kunt ook arrays als queryparameters doorgeven. Deze waarden krijgen de juiste sleutels en worden gecodeerd in de gegenereerde 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
```

### De huidige URL ophalen

Als je geen pad opgeeft aan de `url` helper, krijg je een `Illuminate\Routing\UrlGenerator` instantie terug waarmee je informatie over de huidige URL kunt opvragen.

```php theme={null}
// De huidige URL zonder querystring
echo url()->current();

// De huidige URL inclusief querystring
echo url()->full();
```

Deze methoden zijn ook toegankelijk via de `URL` [facade](./facades).

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

echo URL::current();
```

### De vorige URL ophalen

Soms wil je weten welke URL de gebruiker hiervoor heeft bezocht. Dat kan met de `previous` en `previousPath` methoden van de `url` helper.

```php theme={null}
// De volledige URL van het vorige request
echo url()->previous();

// Het pad van het vorige request
echo url()->previousPath();
```

Je kunt de vorige URL ook via de sessie ophalen.

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

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

    // ...
});
```

Ook de routenaam van de laatst bezochte URL is via de sessie op te halen.

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

## URL's voor named routes

De `route` helper gebruik je om URL's naar [named routes](./routing#named-routes) te genereren.
Met named routes kun je URL's genereren zonder afhankelijk te zijn van de daadwerkelijke URL die in de route is gedefinieerd.
Verandert de URL van de route, dan hoef je de aanroepen van de `route` functie dus niet aan te passen.

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

Een URL naar deze route genereer je als volgt.

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

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

Routes met meerdere parameters worden ook ondersteund.

```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
```

Extra array-elementen die niet overeenkomen met de gedefinieerde routeparameters worden toegevoegd aan de querystring van de URL.

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

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

### Eloquent-modellen

Vaak genereer je URL's met de route key (meestal de primaire sleutel) van een Eloquent-model.
Daarvoor kun je het Eloquent-model als parameterwaarde doorgeven. De `route` helper haalt de route key van het model automatisch op.

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

### Signed URL's

Met Laravel kun je eenvoudig "signed" URL's naar named routes maken.
Deze URL's krijgen een "signature"-hash in de querystring, waarmee Laravel kan verifiëren dat de URL na het aanmaken niet is gewijzigd.
Signed URL's zijn vooral handig voor routes die publiek toegankelijk zijn, maar beschermd moeten worden tegen URL-manipulatie.

Je kunt signed URL's bijvoorbeeld gebruiken om een publieke "uitschrijven"-link te implementeren die je per e-mail naar klanten stuurt.
Maak een signed URL met de `signedRoute` methode van de `URL` facade.

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

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

Door het `absolute` argument mee te geven aan de `signedRoute` methode kun je het domein uitsluiten van de signature-hash.

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

Gebruik de `temporarySignedRoute` methode om een tijdelijke signed URL te genereren die na de opgegeven tijd verloopt.
Bij het valideren van een tijdelijke signed URL controleert Laravel of de in de URL gecodeerde vervaltijd nog niet is verstreken.

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

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

#### Validatieflow van signed URL's

```mermaid theme={null}
sequenceDiagram
    participant App as Laravel-app
    participant User as Gebruiker
    participant Mail as E-mail
    App->>App: URL::signedRoute() / temporarySignedRoute()
    App->>Mail: Signed URL per e-mail versturen
    Mail->>User: E-mail ontvangen
    User->>App: URL aanklikken (GET-request)
    App->>App: Signature valideren<br>hasValidSignature()
    alt Signature geldig
        App->>User: Actie uitvoeren (bijv. uitschrijven)
    else Signature ongeldig of verlopen
        App->>User: 403-fout
    end
```

#### Signed route-requests valideren

Om te controleren of een binnenkomend request een geldige signature heeft, roep je de `hasValidSignature` methode aan op de `Illuminate\Http\Request` instantie.

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

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

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

Wil je bepaalde queryparameters negeren bij de validatie, gebruik dan de `hasValidSignatureWhileIgnoring` methode.

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

In plaats van de binnenkomende request-instantie te gebruiken, kun je ook de `signed` (`Illuminate\Routing\Middleware\ValidateSignature`) [middleware](./middleware) aan de route toewijzen.
Heeft het binnenkomende request geen geldige signature, dan geeft de middleware automatisch een `403` HTTP-response terug.

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

Bevat de signed URL geen domein, geef dan het `relative` argument mee aan de middleware.

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

#### Reageren op ongeldige signed routes

Wie een verlopen signed URL bezoekt, krijgt een generieke foutpagina met HTTP-statuscode `403` te zien.
Je kunt dit gedrag aanpassen door in het bestand `bootstrap/app.php` van je applicatie een eigen "render"-closure te definiëren voor de `InvalidSignatureException` exception.

```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);
    });
})
```

## URL's voor controlleracties

De `action` functie genereert een URL voor de opgegeven controlleractie.

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

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

Als de controllermethode routeparameters ontvangt, geef je als tweede argument een associatieve array met routeparameters door.

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

## Fluent URI-objecten

De URI-klasse van Laravel biedt een handige fluent interface om URI's via objecten te maken en te bewerken.

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

// Een URI-instantie maken van een string
$uri = Uri::of('https://example.com/path');

// URI's genereren naar een pad, named route of controlleractie
$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']);

// Een URI-instantie maken van de URL van het huidige request
$uri = $request->uri();
```

Heb je eenmaal een URI-instantie, dan kun je die fluent aanpassen.

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

## Standaardwaarden voor URL-parameters

Soms wil je voor een bepaalde URL-parameter een standaardwaarde instellen die voor het hele request geldt.
Stel bijvoorbeeld dat veel van je routes een `{locale}` parameter hebben.

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

Het is omslachtig om bij elke aanroep van de `route` helper `locale` door te geven.
Met de `URL::defaults` methode kun je een standaardwaarde voor deze parameter definiëren die tijdens het huidige request altijd wordt toegepast.
Roep deze methode aan vanuit een [route-middleware](/nl/middleware#middleware-toepassen-op-routes), zodat je toegang hebt tot het huidige 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
{
    /**
     * Verwerk het binnenkomende 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);
    }
}
```

Zodra de standaardwaarde voor de `locale` parameter is ingesteld, hoef je die waarde niet meer door te geven bij het genereren van URL's met de `route` helper.

<Info>
  Het instellen van standaardwaarden voor URL's kan de verwerking van Laravels impliciete model binding verstoren.
  Stel daarom de [middleware-prioriteit](./middleware) zo in dat de middleware die de URL-standaardwaarden instelt vóór Laravels eigen `SubstituteBindings` middleware wordt uitgevoerd.
  Dat kan met de `priority` middlewaremethode in het bestand `bootstrap/app.php` van je applicatie.

  ```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

- [Routing](/nl/routing.md)
- [Laravel Folio](/nl/folio.md)
- [Bestandsopslag](/nl/filesystem.md)
- [Helperfuncties](/nl/helpers.md)
- [Strings bewerken (de Str-klasse)](/nl/strings.md)
