Debugging & Profiler
When the Symfony WebProfilerBundle is installed and enabled (automatically in dev environments), the bundle registers a CwaDataCollector that adds a CWA entry to the toolbar and profiler panel. No configuration is required.
The Toolbar Entry
The CWA icon appears in the toolbar on every request. Click it to open the full panel.
Profiler Panel Data
The panel is split into seven sections:
JWT / Authentication
| Field | What it shows |
|---|---|
| Cookie present | Whether a JWT cookie was read on this request |
| Token refreshed | Whether the bundle issued a new JWT on this request (sliding expiry) |
| Cookie cleared | Whether the JWT cookie was deleted (sign-out or expiry) |
Useful for diagnosing login loops, unexpected sign-outs, or confirming that token refresh is triggering correctly.
Route Resolution
| Field | What it shows |
|---|---|
| Resolved path | The URL path the RouteStateProvider matched — confirms which Route entity was resolved |
| Route IRI | The IRI of the matched Route entity (e.g. /_/routes/018e-...) |
Useful for confirming that a URL resolves to the expected route and page, especially when debugging redirect chains or 404 responses.
Mercure Publications
| Field | What it shows |
|---|---|
| Publication count | How many Mercure updates were dispatched on this request |
| Topic list | The full list of topics published — one per updated resource |
Useful for verifying that real-time updates are being dispatched after a PATCH or state change, and for auditing which topics are published to.
Publishable ORM Queries
For each ORM query involving a #[Publishable] resource, the panel records which mode was chosen:
| Mode | Meaning |
|---|---|
draft | Admin user in edit mode — the query returns the draft version |
published_only | Anonymous or non-admin — the query returns only the published version |
Both item (single resource) and collection queries are tracked. Useful for confirming that the correct version is served per request and that the publishable filter is not unexpectedly applying the wrong mode.
PageDataProperty Resolutions
Each dynamic component slot (pageDataProperty position) resolved during normalisation is recorded with its outcome:
| Outcome | Meaning |
|---|---|
| ✓ (no skip reason) | Resolved successfully — the component from the PageData property was used |
no_path | No current route path available on this request |
no_pagedata | The route does not point to a PageData resource |
no_request | No current HTTP request (e.g. console context) |
property_missing | The pageDataProperty name does not exist on the PageData class |
no_component | The PageData property is null — no component assigned |
not_published | The component in the property exists but is an unpublished draft |
not_in_allowed | The component's type is not in the ComponentGroup.allowedComponents list |
Useful for diagnosing blank dynamic slots — the skip reason tells you exactly why a slot rendered nothing.
Write Invalidation Fan-out
After any write operation (POST / PATCH / DELETE), the panel shows:
- Entity counts — how many entities were created, updated, and deleted by
PropagateUpdatesListener - Cache-purged IRIs — the list of IRIs whose HTTP cache entries were purged by
HttpCachePurger
Useful for confirming that a mutation invalidated the expected set of cached resources and for auditing unexpected cache churn.
Private Mercure Upgrades
When PublishableAwareHub upgrades a Mercure update to private: true (because the resource is an unpublished draft), the panel records:
- The Mercure topics included in the private update
- The PHP class of the resource being published privately
Useful for confirming that draft updates are kept off the public Mercure channel and only delivered to authenticated subscribers.