Nitro

Essentials

Attributes

Attributes are how you tell Nitro what a part of your component is for. Mark a method #[Server] and it runs on your server instead of in the browser; mark a property #[Locked] and the browser can read it but never change it. This page brings every attribute together, so you can see at a glance what each one does and where to read more.

On this page

What attributes do

A Nitro component works without any attributes at all, because Nitro has a sensible default for everything. Its public properties are its state: the browser holds them, can change them, and sends them back to the server with each call. Its methods run in the browser, compiled from your PHP, so clicks and typing feel instant. Its view is the Blade view named after the class. For many components, that is all you need.

An attribute changes one of those defaults, for the one thing it is written on. A method that must touch the database gets #[Server]. A property the browser should never change, such as an order's id, gets #[Locked]. A page that should load its code only when someone visits it gets #[LazyLoad]. Because each attribute sits right next to the code it affects, you can read a component from top to bottom and see exactly how it behaves.

Attributes are PHP's own #[...] annotations, and Nitro's live in the Nitro\Attributes namespace. Nitro reads them when it builds your components, not while your page runs. So a mistake, such as #[Server] on a method that cannot be called from the browser, stops the build and names the file and line, rather than failing later in a visitor's browser.

Every attribute

Here is every attribute, with where it goes and what it changes. The sections after the table show each group in a real component, and link to the page that explains it in full.

Attribute Goes on What it does
#[View] A component Its view, when it isn't the conventional Blade view, or is Vue, React, Solid or Svelte
#[LazyLoad] A component or page Its code in a chunk of its own, loaded when first needed
#[Layout] A page The Blade layout it renders in
#[Title] A page Its title, for the layout
#[Description] A page Its description, for search results and link previews
#[Navigate] A page How a visit shows it: data first, markup first, or rendered in the browser
#[Locked] A property Read in the browser, changed only by the server
#[Validate] A property Rules the server checks whenever the browser changes it
#[Url] A property Kept in the query string
#[Remember] A property Kept in the browser's history entry
#[Modelable] A property The one a parent binds with nitro:model
#[Uploads] An array property Takes several uploaded files
#[Computed] A method A value worked out in the browser, read as a property
#[Html] A method HTML made on the server, placed by the view
#[Server] A method Runs on the server, called from the browser
#[Cached] mount() or a #[Server] method Its result kept, for a time or until a tag expires
#[On] A method Runs when an event is dispatched
#[Persist] A store or its property Kept in localStorage
#[Sync] A store or its property Shared with the site's other tabs
#[Browser] Any class Its static methods and constants usable in the browser

On a component

#[View] names a component's view when it isn't nitro.components.*, or when it is a Vue, React, Solid or Svelte view. #[LazyLoad] leaves the component out of the main bundle: the browser loads it when a page first needs it. #[LazyLoad('reports')] puts several in one chunk.

PHP
use Nitro\Attributes\LazyLoad;
use Nitro\Attributes\View;

#[View(vue: 'charts/revenue')]   // its view is resources/views/vue/charts/revenue.vue
#[LazyLoad]                       // its code loads when a page first needs it
class RevenueChart extends Component
{
    // ...
}

On a page

A page is a component with a route. #[Layout] picks its layout (with data for it as a second argument), and #[Title] and #[Description] fill its <head>. #[Navigate] chooses how a visit shows it: 'data' (the default) waits for its data, 'markup' shows it at once and fills it in, 'client' renders it in the browser without asking the server.

PHP
use Nitro\Attributes\Description;
use Nitro\Attributes\Layout;
use Nitro\Attributes\Navigate;
use Nitro\Attributes\Title;

#[Layout('components.layouts.admin')]
#[Title('Orders')]
#[Description('Every order, newest first, with its status and total.')]
#[Navigate('markup')]                       // shown at once on a visit, its data after
class Index extends Component
{
    // ...
}

These go on pages only: on a component, the build says to move it to the pages namespace.

On a property

A public property is state: the browser holds it and can change it. These attributes change what it may do. See Properties for #[Locked], #[Url], #[Remember] and #[Modelable], Forms and validation for #[Validate], and Uploads for #[Uploads].

PHP
use Nitro\Attributes\Locked;
use Nitro\Attributes\Modelable;
use Nitro\Attributes\Remember;
use Nitro\Attributes\Uploads;
use Nitro\Attributes\Url;
use Nitro\Attributes\Validate;

class Checkout extends Component
{
    #[Locked]                               // the browser reads it, only the server changes it
    public int $orderId;

    #[Validate('required|email')]           // checked on the server whenever the browser changes it
    public string $email = '';

    #[Url(as: 'step')]                      // ?step=2, kept in the address
    public int $page = 1;

    #[Remember]                             // back, forward and a reload bring it back
    public string $note = '';

    #[Modelable]                            // the property a parent's nitro:model binds
    public string $coupon = '';

    #[Uploads]                              // takes several files from <input type="file" multiple>
    public array $receipts = [];
}
  • #[Url] takes as (the name in the address), history (a history entry per change), keep (keep it when it equals its default) and except (a value left out of the address).
  • #[Validate] takes Laravel's rules, as a string or an array, and as: the name its messages give the field.
  • Model properties are always locked: the browser can't swap one model for another.

On a method

Methods run in the browser unless an attribute says otherwise. #[Server] sends a call to the server, with the component's state (Server methods). #[Computed] is a value worked out in the browser from the state (Methods), and #[Html] is HTML made on the server for the view to place (Server-made HTML). Both are read as properties.

PHP
use Nitro\Attributes\Cached;
use Nitro\Attributes\Computed;
use Nitro\Attributes\Html;
use Nitro\Attributes\On;
use Nitro\Attributes\Server;

class Invoice extends Component
{
    #[Computed]                             // worked out in the browser, read as $this->total
    public function total(): float
    {
        return array_sum(array_column($this->lines, 'amount'));
    }

    #[Html]                                 // made on the server, placed by the view: {!! $this->terms !!}
    public function terms(): string
    {
        return Str::markdown($this->termsMarkdown, ['html_input' => 'escape']);
    }

    #[Server]                               // runs on the server, called from the browser
    #[Cached(seconds: 300, tags: ['rates'])] // its result kept for five minutes
    public function exchangeRate(string $currency): float
    {
        return Rates::latest($currency);
    }

    #[On('customer-changed')]               // runs when the event is dispatched
    public function refresh(): void
    {
        // ...
    }
}
  • #[Cached] keeps mount()'s state or a #[Server] method's result, with seconds, tags (expired with Nitro::expire()), perUser and by (Caching).
  • #[On] can go on a method several times, one event each (Events).
  • #[Computed], #[Html] and #[Server] are one of each: a method is worked out in the browser, made on the server, or called on the server.

On a store

A store holds state several components share. #[Persist] keeps it in the browser's localStorage, and #[Sync] shares it with the site's other tabs. On the class, they cover every property the browser can change; on a property, that one.

PHP
use Nitro\Attributes\Persist;
use Nitro\Attributes\Sync;
use Nitro\Store;

#[Persist]                                  // kept in localStorage: a reload keeps the cart
#[Sync]                                     // and every tab of the site shows the same one
class Cart extends Store
{
    public array $items = [];
}

On any class

#[Browser] marks a class whose static methods and constants your browser methods and views may use, such as formatting money in one place (Browser classes and enums).

PHP
use Nitro\Attributes\Browser;

#[Browser]                                  // its static methods run in the browser too
final class Money
{
    public static function format(int $cents): string
    {
        return '$'.number_format($cents / 100, 2);
    }
}

Your own attributes

A class extending Nitro\FeatureAttribute is an attribute of your own that runs code around a component, a property or a #[Server] method on the server: logging a call, checking a permission. See Extending Nitro.