Going further
Debugging
In development, Nitro adds an overlay to every page: the components on it and their state, each request they send and how long the server took, the page's data, the stores, and the errors. It is never sent in production.
On this page
Open any page of your app with APP_DEBUG=true and a small badge sits in the bottom-left corner:
N and the number of components on the page, with a red count when something failed. Click it,
and a drawer opens at the bottom of the window. There is nothing to install or turn on:
@nitroScripts adds it in development.
What the overlay shows
| Tab | Shows |
|---|---|
| Components | Every component on the page, with its id. Point at a row to outline the component in the page; click it to see its state, as the browser holds it |
| Requests |
Each
#[Server]
call, reload and upload: the component, the method, the status, the total time, the time on the server and in the database, and the size of the answer. The latest hundred are kept
|
| Page | The URL, the layout, and the size of the page's data: each component's state and the globals, so you can see what makes a page heavy |
| Stores | Each store made in this tab, and its values as they change |
| Errors |
What failed in the browser: a call, a render, a handler, with its message (the
nitro:error
event). The badge counts them
|
The overlay lives in a shadow root, so your CSS never reaches it and its CSS never reaches your page. It is a plugin on Nitro's public runtime, like any you could write, and it watches the page without changing it.
Slow page? Look at Requests and Page
A call that spends most of its time in the database needs a query looked at, or caching. A page whose data is large sends a model or a list the view doesn't use: keep only the fields it shows, as Arrays and models explains.
Turning it on and off
The overlay follows APP_DEBUG. To choose yourself, set devtools in config/nitro.php:
// config/nitro.php
'devtools' => null, // null: on when APP_DEBUG is on. true or false: always, or never.
null(the default): on in development, off in production, asAPP_DEBUGsays.false: never, even in development. For a screen recording or a demo.true: always. Keep it for a staging server only: on a public site every visitor would get it.
When it is off, @nitroScripts leaves its script out of the page, and its URL under
/_nitro answers 404: the overlay's code never leaves the server.
Server-Timing
While the overlay is on, every response from your app carries a Server-Timing header: the
time the request took on the server, and the part of it spent in the database. The overlay's Requests tab
reads it, and so do the browser's own developer tools: open the Network tab, pick a request, and look at
Timing.
Server-Timing: nitro;dur=38.4, db;dur=11.2
Your own scripts can read it too, through the browser's Performance API:
// The same numbers, for your own logging: every response the page has fetched.
for (const entry of performance.getEntriesByType('resource')) {
for (const { name, duration } of entry.serverTiming) {
console.log(entry.name, name, `${duration}ms`); // ".../_nitro/update" "nitro" "38.4ms"
}
}
nitro is the whole request on the server, from the middleware Nitro adds to the response;
db is the time all its queries took, on every connection. With the overlay off, the header isn't
sent.
Names in a build
After php artisan nitro:build, components, methods and pages go by short aliases
(Building for production), and the overlay shows those. To see
your own names while you work, run php artisan nitro:clear: without a build, Nitro compiles
each component as you change it, under its real name.