Skip to content

Routes and URLs

Anvil registers the routes of every panel in Config\Anvil::$panels; you don’t add routes for resources or pages.

For a panel with the path admin:

Route Name Purpose
GET /admin anvil.admin.dashboard dashboard
GET /admin/<page> anvil.admin.page.<page> pages
GET /admin/<resource> anvil.admin.<resource>.index list
GET /admin/<resource>/create anvil.admin.<resource>.create create
GET /admin/<resource>/{uuid} anvil.admin.<resource>.view detail page
GET /admin/<resource>/{uuid}/edit anvil.admin.<resource>.edit edit
POST /admin/_anvil anvil.admin.endpoint component endpoint
POST /admin/_tenant anvil.admin.tenant tenant switch and favourite tenant
GET /admin/_file/{uuid} anvil.admin.file download of a stored file
GET /admin/_export/{uuid} anvil.admin.export download of an export
  • Records are addressed by UUID only; other ids in the URL do not match the route (404).
  • All routes carry the filters of the panel.
  • The segment of the endpoint is Config\Anvil::$endpointPath (default _anvil). Slugs of resources and pages must not collide with it or with _tenant, _file and _export.
  • Pages are rendered with Cache-Control: no-store and the security headers of Anvil.

Routes outside the panels: the login of Shield, sso/… for single sign-on and api/v1/… for the API.

$panel = service('panels')->current(); // the panel of the current request, null outside
$panel->url(); // https://example.com/admin
$panel->url('reports'); // https://example.com/admin/reports
$panel->endpointUrl(); // https://example.com/admin/_anvil
$resource->url(); // list
$resource->url('create');
$resource->url('view', $uuid);
$resource->url('edit', $uuid);
$page->url();

Or with the route names: url_to('anvil.admin.invoices.view', $uuid). Build URLs with these methods instead of writing paths, so a changed path() does not break links.

service('panels') is the registry of all panels:

Method Returns
all() all panels by id
get('admin') a panel by id, or null
current() the panel of the current request, or null (CLI, API, routes outside panels)

Code that runs in several panels – resources, columns, widgets – should use current() instead of a fixed panel.