---
title: Live KPI Strip
description: Compact horizontal row of ticker widgets with auto-refresh via wire:poll.
visibility: guest
draft: false
---

# Live KPI Strip

Tickers are the right primitive for a "live data" header — denser than stat cards, designed for quick scanning. Pair them with Livewire's `wire:poll` for periodic auto-refresh.

## Recipe

:::preview{title="Live KPI ticker strip — wire:poll.1s in action"}
<livewire:demos.live-kpi-strip-demo />
:::

:::source{language="blade"}
{{-- align="start" keeps tickers top-aligned when some carry a delta and others don't --}}
{{-- — without it, shorter tickers vertically center against taller siblings. --}}
<div wire:poll.30s="refreshKpis">
    <x-wirekit::row gap="md" :wrap="true" align="start">
        @foreach($kpis as $kpi)
            <x-wirekit::ticker
                :label="$kpi['label']"
                :value="$kpi['value']"
                :delta="$kpi['delta']"
                :intent="$kpi['intent']"
                size="sm"
            />
        @endforeach
    </x-wirekit::row>
</div>
:::

:::source{language="php"}
// Livewire component
public array $kpis = [];

public function mount(): void
{
    $this->refreshKpis();
}

public function refreshKpis(): void
{
    $this->kpis = [
        ['label' => 'Today', 'value' => '$' . number_format($this->todayRevenue()), 'delta' => '+8.4', 'intent' => 'success'],
        ['label' => 'MTD', 'value' => '$' . number_format($this->mtdRevenue()), 'delta' => '+12.5', 'intent' => 'success'],
        ['label' => 'AOV', 'value' => '$' . number_format($this->aov(), 2), 'delta' => '+3.8', 'intent' => null],
        ['label' => 'Live Visitors', 'value' => (string) $this->liveVisitors(), 'delta' => null, 'intent' => null],
    ];
}
:::

::: tip
**Heads up — the preview above is real:** it's a Livewire component with `wire:poll.1s`, jittering its dummy values every second so you can see the strip update without leaving the page open. Production cadence is almost always slower — the Show Code panel above carries the canonical `.30s` baseline for marketing dashboards. The Variations section below lists faster / slower presets for trading or analytics workloads.
:::

## Variations

- **Polling interval:** Change `wire:poll.30s` to match data freshness needs (`.5s` for trading dashboards, `.5m` for marketing analytics).
- **Pause when hidden:** Wrap with Alpine + `IntersectionObserver` to skip polling when the strip scrolls out of view — saves backend cycles on long pages.
- **Sparkline overlay:** For high-attention metrics, swap one or two tickers for `<x-wirekit::stat>` cards with `sparkline` slots (see [Stat with Sparkline](/blueprints/recipes/stat-with-sparkline)).

## Components Used

- [Ticker](/components/ticker) — `label`, `value`, `delta`, `intent`, `size`
- [Row](/components/row) — flex container with wrap

## See Also

- [Ticker component docs](/components/ticker)
- [Stat with Sparkline recipe](/blueprints/recipes/stat-with-sparkline) — denser variant with trend visualization
