Skip to content

Inertia ​

The Inertia tabThe Inertia tab

The Inertia lens records every Inertia page a request returns, on the first load and on Inertia visits and partial reloads. It writes one row per top-level prop to section inertia - its type, size, whether it was sent and, if not, why - and one row per page to section inertia_pages.

Rows ​

Section inertia ​

A row for every prop that was declared or sent. A dotted key such as auth.user counts as part of its top-level prop auth.

FieldMeaningUnitMissing when
propthe prop's name-never
typehow it was declared: plain, closure, always, optional, lazy, defer, merge, scroll or once-never
sharedtrue for a shared prop, false for a prop of the page-never
sentwhether the prop was in the response-never
size_bytesthe prop's size as JSONbytesnull when not sent
groupthe defer group of a deferred prop, such as default-null when not deferred
mergehow the client merges it: append, prepend or deep-null when not merged
omittedwhy it was not sent - see below-null when sent
valuethe value that was sent, masked like request input-null when not sent; replaced by its size, such as (84.0 KB, larger than max_value_bytes), when larger than max_value_bytes
defined_atwhere the closure the prop resolves with is defined in your code, as file:line-null when the prop is not a closure, or the closure is in a package
durationhow long that closure took to resolvemsnull when no closure ran
timewhen the closure started resolving, or when the page was recordedms since the capture startednever
largetrue when the prop is larger than large_prop_bytes-null otherwise
shared_on_partialtrue when a shared prop was sent on a partial reload that did not ask for it-null otherwise

Why a prop was not sent (omitted), checked in this order:

ValueMeaning
rescuedresolving it failed and Inertia rescued it
deferredit is deferred and loads in a later request
partial reloada partial reload did not ask for it
optionalan optional or lazy prop that was not asked for
loaded oncea once prop the client already has
omittedany other reason

A deferred prop is timed on the request that loads it.

Section inertia_pages ​

FieldMeaningUnitMissing when
componentthe page component, such as Dashboard-never
urlthe page URL-never
versionthe asset version-null when not set
visitfirst load for a full page load, inertia for an Inertia visit-never
partialon a partial reload: the component and the props asked for with only or left out with except-null when not a partial reload
props_sentthe number of props in the responsecountnever
props_omittedthe number of declared props that were not sentcountnever
payload_bytesthe size of the whole page as JSONbytesnever
deferredthe deferred props by group, such as {"default": ["stats"]}-null when nothing is deferred
encrypt_historywhether history encryption is on-never
clear_historywhether the history is cleared-never
timewhen the page was recordedms since the capture startednever

Each closure a prop resolves with is also a span of kind inertia.prop on the Timeline, named after the prop, with the queries it ran under it.

Totals, warnings and errors ​

When the capture has an Inertia page, the summary gets:

TotalLabelValue
inertia_msspentthe time all prop closures took to resolve, in ms
inertia_propsprops sentthe number of props that were sent
inertia_payload_bytespayloadthe size of all pages as JSON, in bytes
inertia_deferreddeferredthe number of props left out because they are deferred

Warnings:

  • A prop larger than large_prop_bytes (50000 by default): "Inertia prop "prop" on Component is size, defined at file:line." The location is added when it is known.
  • A page larger than large_page_bytes (200000 by default): "Inertia page Component is size."
  • A shared prop sent on a partial reload that did not ask for it, such as every shared prop on a reload with only an except list: "Shared Inertia prop "prop" was sent on a partial reload of Component that did not ask for it." Props declared with Inertia::always() are exempt; wrap a prop in it if it is meant to be sent every time.

The Inertia lens reports no errors.

In the dashboard ​

The Inertia tab shows the totals, then a line with the page facts - component, URL, visit, version, the props a partial reload asked for or left out, the payload size, and whether history is encrypted or cleared - then the props table.

The props table has the columns scope (shared or page), prop, type, sent (sent or not sent), size, group, merge, omitted, duration and defined at; defined_at links to your editor. Large props and shared props sent on a partial reload are tinted as warnings. Group the rows in order, by type or by scope. Each row folds out to all of its fields, including the value that was sent. The pages are listed as their own table below the props.

The Request tab shows the Inertia response as a card titled with the component and its URL: the visit, the version, the partial reload, the props as sent (masked like request input), the deferred and merge props, and whether history is encrypted or cleared. This works for Inertia visits and for the page embedded in the HTML of a first load. See Response captures.

The Timeline tab shows an inertia.prop span for every prop closure that ran.

For agents ​

Is the page heavy, and which props make it so?

json
{
  "tool": "monocle-rows",
  "section": "inertia",
  "sort": "size_bytes",
  "dir": "desc",
  "limit": 10,
  "fields": ["prop", "type", "shared", "size_bytes", "defined_at"]
}

Which props were left out, and why:

json
{
  "tool": "monocle-rows",
  "section": "inertia",
  "where": [{ "field": "omitted", "op": "not_null" }],
  "fields": ["prop", "type", "omitted", "group", "defined_at"]
}

The page itself and the warnings for it, including what a partial reload asked for:

json
{ "tool": "monocle-show", "id": "latest", "sections": ["summary", "inertia_pages"] }

To find the slow prop closures, ask monocle-rows for section inertia sorted by duration. See For AI agents for every filter monocle-rows accepts.

Configuration ​

The lens is listed in the lenses block of config/monocle.php under its class, ExeQue\Monocle\Lenses\Packages\Inertia\InertiaLens. true runs it with its defaults, false turns it off, and an array passes options. See Lenses.

OptionDefaultEffect
large_prop_bytes50000a prop larger than this, as JSON, gets a warning and large: true
large_page_bytes200000a page larger than this, as JSON, gets a warning
max_value_bytes20000a prop value larger than this is shown as its size instead of its value

Other settings that affect it:

  • Masking - prop values are masked with mask.inputs. Key an entry by InertiaLens::class to mask more on the Inertia tab only.
  • RequestLens option capture - 'text/html' => InertiaCapture::class under response_types and 'X-Inertia' => InertiaCapture::class under headers give the Request tab its Inertia card. Leave them out to keep only the raw response. See Request.
  • dashboard.tabs - InertiaLens::class in the list places the Inertia tab.
php
use ExeQue\Monocle\Lenses\Packages\Inertia\InertiaCapture;
use ExeQue\Monocle\Lenses\Packages\Inertia\InertiaLens;
use ExeQue\Monocle\Lenses\Request\JsonCapture;
use ExeQue\Monocle\Lenses\RequestLens;

'lenses' => [
    RequestLens::class => [
        'capture' => [
            'response_types' => [
                'application/json' => JsonCapture::class,
                'application/*+json' => JsonCapture::class,
                'text/html' => InertiaCapture::class,
            ],
            'headers' => [
                'X-Inertia' => InertiaCapture::class,
            ],
        ],
    ],

    InertiaLens::class => [
        'large_prop_bytes' => 50000,
        'large_page_bytes' => 200000,
        'max_value_bytes' => 20000,
    ],
],

'mask' => [
    'inputs' => ['/pass|token|secret|authorization/i', InertiaLens::class => '/email|phone/i'],
],

Setting a capture key replaces its default, so list every entry you want to keep - see Request.

Requirements and limits ​

  • Needs inertiajs/inertia-laravel. Without it the lens does nothing.
  • Only the server side is recorded: what the page did in the browser, client-side visits answered from history, and prefetched pages that never reach the server are not.
  • Props are recorded by their top-level name; nested keys are not listed on their own.
  • defined_at and duration are only known for props that resolve through a closure. A closure defined inside a package has no defined_at.
  • Values larger than max_value_bytes are kept as their size only.