owenvoke/laravel-dashboard-cloudflare-stats-tile
A Laravel Dashboard tile that displays Cloudflare statistics, including requests, bandwidth, and threats, directly on your dashboard.
Architecture fit: This is an additive leaf node with a tightly bounded blast radius. The tile implements spatie/laravel-dashboard's tile contract, renders through Livewire on an existing dashboard route, and reads cached Cloudflare zone statistics produced by a scheduled fetch command. It introduces no migrations, no auth surface, no public routes, and no core overrides — the entire footprint is a config block, a scheduler entry, a cache namespace, and one Blade/Livewire component.
The non-negotiable TPM framing: the tile has no standalone value. It is an extension of a framework we must already operate. If spatie/laravel-dashboard is not installed and rendering today, then adopting an entire dashboard framework to display one Cloudflare card is the tail wagging the dog, and the correct decision is to reject on scope grounds before any engineering time is spent. That gate is answered in minutes and should be answered first.
Integration feasibility: Low effort, conditional on that gate passing. The path is composer require → publish config → provision a zone-scoped Cloudflare token → set zone ID and token in env → register the tile in config/dashboard.php → schedule the fetch command. The friction is narrow and predictable: version constraints against our Laravel/PHP target, which Cloudflare analytics API the tile targets, and whether the exposed metrics (requests, bandwidth, unique visitors, cached vs. uncached, threats) are the ones we actually want on an ops surface.
Technical risk: Adoption signal is weak — 11 stars, 0 dependents, score 0.215, single maintainer, no SLA, no downstream validation. Three risks are material:
illuminate/support constraint plus a test pass — cheap, but it must be scoped as work, not discovered as an incident.The offsetting factor across all three is small surface area plus MIT licensing: the worst case is a cheap internal fork, not a blocked initiative. Frame this as a liability we choose to own, never as a vendor we rely on.
Key questions:
spatie/laravel-dashboard, or would this be the tail wagging the dog? (Hard gate.)composer.json, and are the constraints tight (validated in CI) or loose (untested)?Zone.Analytics:Read on a single zone, with no broader account permissions?Stack fit: Good for Laravel 9/10 with Livewire and spatie/laravel-dashboard already installed and rendering. Poor otherwise — a one-tile dashboard deployment is not a defensible ROI story for a TPM to sponsor, and it creates a framework we now own for a single card. Confirm the live stack before committing engineering time; this is a gate, not a detail.
Migration path: Purely additive; no data migration, no cutover, no dual-run period, and a trivially reversible rollback (remove the tile registration and the scheduler entry). Sequence:
Zone → Analytics → Read, single zone) and store it via the standard secret path — not .env on a shared box if we have a secrets manager.composer require the tile and publish its config; pin the version.config/dashboard.php with position and refresh interval.Compatibility: Verify before committing, and pin the tile and the dashboard package together. If the tile caps at Laravel 9/10 while we are on 11/12, plan the fork explicitly (widened illuminate/support constraint plus a test pass). Also inspect the Cloudflare API client pulled in transitively — that is the real dependency risk, and it is invisible in the tile's own composer.json.
One subtlety worth calling out to stakeholders: the tile's refresh interval controls Livewire polling of the cache, not the Cloudflare fetch. A short refresh interval over a stale cache just shows stale numbers faster. Cadence decisions live in the scheduler; freshness decisions live in the TTL; the tile just renders.
Sequencing:
Defer multi-zone, multi-tenant, and any historical/retention work until single-zone proves the value hypothesis.
Maintenance: Low volume but non-zero ownership. A single maintainer means we assume we patch it ourselves. Budget a small recurring allowance — roughly one dependency bump and one Cloudflare API compatibility check per year — and enforce the discipline of never modifying the package in place: subclass or override, so upstream can be re-pulled or abandoned cheaply. If we ever vendor it, record the commit SHA and the exact diff in the runbook.
Support: MIT, community-only, no SLA, no escalation path. Acceptable for an internal, non-customer-facing dashboard. Not acceptable where the tile's output drives an alert or a business decision without an independent source of truth. Cloudflare's own dashboard and the GraphQL Analytics API remain authoritative; this tile is a convenience surface, never a monitoring system of record. Write that sentence into the runbook so no one downstream builds an alert on top of it.
Scaling: Fetching is scheduler-driven and cached, so cost is flat per zone rather than per viewer — ten viewers cost the same as one. Multiple zones mean multiple tile instances and multiplied API calls, still trivial against Cloudflare rate limits at any sane cadence. The cache is the scaling mechanism; do not drive the TTL toward zero to make the tile feel "live," because that converts a flat cost into a per-viewer cost and buys no real freshness.
Failure modes and detection:
| Failure | How it surfaces | Mitigation |
|---|---|---|
| Expired/revoked token | Often an empty tile rather than a visible 403 | Alert on fetch command exit status |
| Zone ID misconfiguration | Empty or wrong-zone numbers | Validate against non-prod zone first |
| Cloudflare GraphQL schema change | Command error or null payload | Pin client; monitor exit status |
| Scheduler not running | Silent staleness — plausible stale numbers | Cache-age freshness indicator; php artisan schedule:list check |
| Cache backend outage | Tile errors or blanks | Standard cache monitoring |
composer update pulls incompatible dashboard |
Render/class errors | Pin both packages together |
The dominant risk is silent staleness, and it is the one most likely to erode trust in the whole dashboard rather than just this tile. Treat the freshness indicator and the exit-status alert as part of the definition of done, not as follow-up nice-to-haves.
Ramp-up: Roughly half a day for a Laravel developer to wire and validate, plus a few hours of ops time for token creation, secret storage, and scheduler monitoring. No new platform knowledge required beyond Cloudflare token scoping. Before handoff, document token rotation, the fork procedure, and the explicit statement that the tile is a convenience view — not a system of record.
The decision this enables: Is edge/CDN observability valuable enough to build or buy a real solution, or is a free tile sufficient? Both answers are informative and both are cheaper to reach with this tile than with a custom build. Set the evaluation window up front — e.g. 60 days of use, then ask whether PMs, on-call, and leadership actually looked at it during triage. If the answer is no, delete it and close the ops-dashboard question cheaply; if the answer is yes, that is the evidence to fund the real thing.
How can I help you explore Laravel packages today?