Configuration
A panel is configured by overriding methods of Anvil\Panel\Panel. This
page covers identity, look and assets; content, access and tenants have
pages of their own.
| Method | Default | Purpose |
|---|---|---|
id() |
– (required) | unique id |
path() |
id() |
URI prefix |
brand() |
Anvil |
name in the sidebar, the title and the login page |
logo() |
null (brand mark) |
URL of a logo |
primaryColor() |
null (theme colour) |
accent colour |
maxContentWidth() |
Panel::WIDTH_FULL |
width of the content area |
stylesheets() |
[] |
own CSS files |
scripts() |
[] |
own JavaScript files |
public function id(): string { return 'admin'; }Lower case letters, digits and -, starting with a letter, at most 32
characters (Panel::ID_PATTERN); otherwise registering the panel throws an
InvalidArgumentException. The id appears in:
- permissions of pages (
admin.page.reports) and the panel itself, - component ids (
admin:invoices:collection) and tokens – a token of one panel is not valid in another, - route names (
anvil.admin.dashboard,anvil.admin.invoices.index), - saved views and widget layouts of the users.
Changing the id later invalidates these: choose it once.
path()
Section titled “path()”public function path(): string { return 'backoffice'; } // https://example.com/backofficeThe URI prefix of all routes of the panel, defaults to the id. It can be
changed later; links built with url() follow.
brand() and logo()
Section titled “brand() and logo()”public function brand(): string { return 'ACME Back Office'; }
public function logo(): ?string { return base_url('images/logo.svg'); }The brand is shown in the sidebar, in the browser title (Page · Brand)
and on the login page. A logo is a public URL of the own origin (the
Content Security Policy blocks other origins); without one the brand mark
of Anvil is shown. SVG or PNG with a transparent background work best in
light and dark mode.
primaryColor()
Section titled “primaryColor()”public function primaryColor(): ?string { return '#0f3d76'; }The accent colour as #rrggbb: buttons, links, active navigation entries,
focus rings. Other formats are ignored. Pick a colour with enough contrast
to white text (WCAG AA, 4.5:1). Different panels can have different
colours, e.g. blue for the back office and green for the portal. See
Colours.
maxContentWidth()
Section titled “maxContentWidth()”public function maxContentWidth(): string { return Panel::WIDTH_WIDE; }| Value | Effect |
|---|---|
Panel::WIDTH_FULL |
lists and cards use the whole window (default) |
Panel::WIDTH_WIDE |
the content stops at 1440px |
Forms and detail pages always stop at 1440px, so their fields stay readable.
stylesheets() and scripts()
Section titled “stylesheets() and scripts()”public function stylesheets(): array { return [base_url('css/app.css')]; }
public function scripts(): array { return [base_url('js/app.js')]; }Own CSS and JavaScript files as URLs of the own origin, loaded on every page of the panel: stylesheets after Anvil’s stylesheet (so they can override it), scripts before Anvil’s script. Inline styles and scripts are not possible with the Content Security Policy.
Scripts are loaded deferred before Anvil starts Alpine, so they can register Alpine components:
document.addEventListener('alpine:init', () => { Alpine.data('counter', () => ({ count: 0, increment() { this.count++; } }));});Alpine runs in its CSP build: templates reference properties and methods by name, not with expressions. See Own styles and scripts.