Recipe: Live API Status Dashboard

Turn any JSON status endpoint into a self-updating WordPress dashboard. This recipe wires a single [tablecrafter] shortcode to TableCrafter's Smart Auto-Refresh engine so your table re-fetches on an interval, pauses politely while people read, and shows a live "updated X ago" indicator.

Smart Auto-Refresh REST / JSON Shortcode Live Indicator No-Code

What you'll build

A status dashboard page showing the health of your services (component name, status, latency, last incident) that refreshes itself every 30 seconds without a page reload. The table preserves the visitor's current page, search, filters, and sort across each refresh, pauses while the tab is hidden or while someone is actively interacting, and exposes a small control bar to pause/resume or refresh on demand.

Everything here uses only real, shipped attributes from TableCrafter v3.5.6. No custom code is required, though we cover optional CSS theming at the end.

Prerequisites

ℹ️

For cross-origin APIs, the browser request is proxied through the WordPress tc_proxy_fetch AJAX action. That proxy requires the user to have at least edit_posts capability and applies SSRF protection plus rate limiting (30 requests / 60 seconds). Public, same-origin JSON files are fetched directly with no proxy and no capability check.

Step 1 — Inspect your API response shape

TableCrafter auto-discovers columns from the keys of the first row, so the shape of the response matters. The two common shapes:

A flat array — works with no extra attributes:

// GET https://status.example.com/api/components.json
[
  { "component": "API Gateway", "status": "operational", "latency_ms": 87 },
  { "component": "Database",    "status": "degraded",    "latency_ms": 412 }
]

A nested object — point at the array with the root attribute using dot notation:

// GET https://status.example.com/api/v1/summary.json
{
  "page": { "name": "Example Status" },
  "data": {
    "components": [
      { "component": "API Gateway", "status": "operational" }
    ]
  }
}
// reach the array with: root="data.components"

Step 2 — Add the dashboard shortcode

Create a new page (Pages → Add New), add a Shortcode block, and paste the example below. This is the core recipe — a 30-second live dashboard with a countdown timer:

[tablecrafter source="https://status.example.com/api/components.json"
  root="data.components"
  include="component,status,latency_ms,updated_at"
  search="true"
  filters="true"
  per_page="25"
  auto_refresh="true"
  refresh_interval="30000"
  refresh_countdown="true"
  refresh_last_updated="true"]

Publish, then view the page. On first load the server renders the table (Stale-While-Revalidate), then the frontend script hydrates it and starts the refresh loop. You should see a control bar reading "Auto-refresh active" with a live countdown and an "Updated just now" timestamp.

💡

refresh_interval is in milliseconds, not seconds. 30000 = 30 seconds, 60000 = 1 minute. The shortcode default when auto_refresh="true" but no interval is given is 300000 (5 minutes).

Step 3 — Curate the columns

Status APIs are often verbose. Trim the table to the columns that matter with include (a comma-separated allow-list) or exclude (a comma-separated hide-list). Column order follows the order of the keys discovered in the first row.

// Show only these four columns, in this priority
[tablecrafter source="..." include="component,status,latency_ms,updated_at"]

// Or keep everything except internal IDs
[tablecrafter source="..." exclude="internal_id,region_code"]

Add sort in column:direction format to land visitors on the most urgent rows first — for example sort="status:asc" or sort="latency_ms:desc".

Shortcode attribute reference

These are the attributes relevant to a live dashboard. Booleans accept true/false (also 1/yes).

AttributeRequired?DefaultPurpose
sourceRequiredURL of the JSON API, CSV, or public Google Sheet to load.
rootOptional(empty)Dot-notation path to the data array inside a nested response, e.g. data.components.
includeOptional(all keys)Comma-separated allow-list of columns to display.
excludeOptional(none)Comma-separated list of columns to hide.
searchOptionalfalseShow the live search box.
filtersOptionaltrueShow auto-detected per-column filters.
per_pageOptional0 (all)Rows per page; enables pagination when > 0.
sortOptional(none)Initial sort as column:direction, e.g. latency_ms:desc.
auto_refreshRequiredfalseSet true to enable the Smart Auto-Refresh loop. This is the switch that makes the dashboard "live."
refresh_intervalOptional300000Refresh cadence in milliseconds.
refresh_indicatorOptionaltrueRender the control bar (status text, pause/resume, refresh-now).
refresh_countdownOptionalfalseShow a "Next: 0m 29s" countdown to the next refresh.
refresh_last_updatedOptionaltrueShow an "Updated X ago" timestamp.
⚠️

Auto-refresh only runs when there is a data URL to re-fetch (a source). Inline data has nothing to poll. If auto_refresh is on but no URL resolves, the engine logs a warning and skips the loop rather than erroring.

How Smart Auto-Refresh behaves

Once auto_refresh="true", the TableCrafter instance starts a setInterval loop at your interval. Each tick calls performRefresh(), which:

  1. Snapshots the visitor's current page, filters, search term, and sort.
  2. Re-fetches the source (through the proxy for cross-origin URLs, with a 1-hour server transient cache on the proxy result).
  3. Re-renders the table and restores that snapshot, so a refresh never yanks a reader back to page 1 or clears their filter.
  4. Updates the "last updated" timestamp and resets the countdown.

Two "smart" guards keep it unobtrusive, both on by default:

If a refresh fails, the engine retries with exponential backoff (2s, 4s, 8s) up to 3 attempts. After the final failure it stops the loop to avoid hammering a down endpoint.

The control bar and its CSS hooks

When refresh_indicator is enabled, TableCrafter injects a control bar at the top of the container. These are the real class names you can target for theming:

Element / classWhat it is
.tc-refresh-indicatorThe control-bar wrapper. Gets a .paused class while paused.
.tc-refresh-statusThe left-hand status group (icon + text + optional countdown/timestamp).
.tc-refresh-iconThe spinning 🔄 glyph (animated by the tc-spin keyframe; animation stops when paused).
.tc-refresh-textReads "Auto-refresh active" or "Auto-refresh paused".
.tc-countdown"Next: …" countdown, shown only when refresh_countdown="true".
.tc-last-updated"Updated X ago" timestamp, shown when refresh_last_updated="true".
.tc-refresh-toggleThe ⏸️ / ▶️ pause-resume button.
.tc-refresh-manualThe ↻ "Refresh now" button — forces an immediate refresh and resets the interval.

The plugin injects baseline styles for these once, under a <style id="tc-refresh-styles"> tag. To restyle the bar (for example to match a dark dashboard), add your own CSS with higher specificity:

.tc-refresh-indicator {
  background: #0f172a;
  border-color: #1e293b;
  color: #e2e8f0;
}
.tc-refresh-indicator .tc-countdown { color: #38bdf8; }

Color-coding status values

TableCrafter renders cell values as text, so there is no built-in "status pill." The accurate way to color-code is plain CSS targeting the rendered cells. Because the table is re-rendered on every refresh, attribute-based selectors keep working after each update. A robust approach is to drive color from your data itself — return a CSS-friendly value and style by content using a small wrapper, or scope styles to the table cells:

/* Scope to your dashboard page/container, then style status text */
.tablecrafter-container td { font-variant-numeric: tabular-nums; }
/* Pair with a 'status' column whose values are operational/degraded/down */
.tablecrafter-container td:nth-child(2) { font-weight: 600; }
💡

The most maintainable pattern is to have your API include a numeric latency_ms and a normalized status string. TableCrafter's auto-detected filters will then offer a status dropdown and a latency range automatically — no configuration needed.

Tuning the refresh cadence

ScenarioSuggested intervalRecommended flags
NOC wall display, fast-moving metricsrefresh_interval="15000" (15s)refresh_countdown="true"
Public status pagerefresh_interval="60000" (1m)refresh_last_updated="true"
Cross-origin API (rate-limited proxy)refresh_interval="60000" or higherkeep default smart pausing on
⚠️

For cross-origin sources, remember the proxy enforces 30 requests per 60 seconds per user and caches each URL's response for an hour. A 15-second interval against a remote API will hit the cache, not your origin, between cache expiries — fine for status pages, but don't expect sub-cache real-time freshness from a remote source without lowering the cache window. Same-origin JSON files bypass the proxy and refresh at the literal interval.

Manual control and instances

Each rendered table is a TableCrafter instance bound to its .tablecrafter-container. The visible ⏸️ and ↻ buttons map to toggleAutoRefresh() and refreshNow(). Visitors can pause a noisy dashboard themselves; the bar text and icon update to reflect the paused state. If you hide the bar with refresh_indicator="false", the loop still runs silently with the same smart pausing — useful for an unattended kiosk where you don't want controls on screen.

Troubleshooting

Next, see data-sources.html to connect JSON, CSV, and Google Sheets sources (and configure nested root paths), and shortcode-reference.html for the full attribute list including export and pagination options.