AETumi — AI-native 3D web platform for Three.js, WebGL and interactive websites
News & Guides

Building a React Dashboard UI With AI

September 8, 2026 · AETumi

Key answer: A React dashboard UI is a layout shell — sidebar, header, content region — filled with a small set of repeating parts (stat cards, data tables, and charts), each of which must render four states: loading, empty, error, and data. An AI coding assistant can scaffold all of this quickly, but it defaults to the happy path; the value you add is demanding the missing states, the accessibility, and owned components so the result doesn't look generic. AETumi ships these dashboard parts as reviewed source — shell, parts, and all four states — so the assistant assembles from known-good pieces instead of improvising.

Table of contents

What you'll learn

  • What a React dashboard UI is made of — the shell and the handful of parts that repeat on every screen.
  • Why AI-generated dashboards reliably ship only the happy path, and how to demand the rest.
  • How to model loading, empty, error, and data states as types so none can be skipped.
  • Accessibility patterns for data-dense screens: tables, skip links, live regions, chart alternatives.
  • The performance and maintenance trade-offs, and where a human must review AI output.
  • How an owned source supplies dashboard components with states and accessibility built in.

What a React dashboard UI is

A React dashboard UI is an application layout — almost always a persistent sidebar for navigation, a header with context and account controls, and a scrollable content region that swaps per route — populated with a small, repeating vocabulary of parts. Those parts are stat cards (a label, a value, a delta), data tables (sortable, paginated, sometimes selectable), and charts (line, bar, area). Everything else is composition.

What to prioritizeAETumi technical diagram — What to prioritizeRecommended priority weighting (higher = more important)Editable source you own90Accessibility built in85Themable tokens75Typed & documented70States handled80
What to prioritize
Liquid Metal Button
Liquid Metal Button — live preview from the AETumi library

The defining property of a dashboard, and the reason it is harder than it looks, is that every data-driven part has more than one appearance. A stat card is not just "the number." It is the number, and the skeleton while the number loads, and the message when there is no number yet, and the error when the fetch fails. It is really that full set of states, rendered coherently across every part. Miss the states and you have a demo, not a product.

Why it matters for AI-built apps

Dashboards are the surface where AI coding assistants save the most time and cause the most subtle damage. They save time because the shapes are conventional — an assistant scaffolds a sidebar-plus-content layout instantly. They cause damage because the assistant optimizes for the visible result, which is the happy path, and quietly omits the states no one asked for out loud.

Liquid Glass Button
Liquid Glass Button — live preview from the AETumi library

Building from a component source you own changes the economics. When the shell, the stat card, the table, and the four-state wrapper already exist as reviewed dashboard components, the assistant fills them with your data instead of re-deriving them — and inherits the accessibility and states that were built in once. This is why AETumi ships the dashboard shell and its parts as source you own rather than leaving the assistant to reinvent them each session, all in one design language.

How the pieces connectAETumi technical diagram — How the pieces connectDesignTokensPrimitiveVariantsStatesShip
How the pieces connect

Architecture: shell, parts, and state

Model a dashboard as three layers. The shell is the stable frame: landmark regions (aside, nav, header, main) that never change between routes. The parts are the reusable content components — cards, tables, charts — that are composed into each screen. The state layer wraps every part that fetches, so loading, empty, error, and data are handled uniformly instead of ad hoc per component.

Spline 3D Scene
Spline 3D Scene — live preview from the AETumi library

Data flows from a fetch (server-side where possible) into a state value, which the wrapper switches on to decide what to render. Interactive parts — a chart with a range toggle, a table with sortable headers — are client components; static parts (a stat card that just displays a value) can render on the server in the App Router. Keeping the state layer explicit is what prevents the most common dashboard failure: a part that shows a blank rectangle instead of an empty state, or a spinner that never resolves into an error.

The dashboard shell

Almost every dashboard shares the same frame. Building it well once — as a real layout with landmark regions — pays off on every screen after.

Futuristic Hero
Futuristic Hero — live preview from the AETumi library
// components/dashboard-shell.tsx
export function DashboardShell({
  nav, header, children,
}: { nav: React.ReactNode; header: React.ReactNode; children: React.ReactNode }) {
  return (
    <div className="shell">
      <a className="skip-link" href="#content">Skip to content</a>
      <aside aria-label="Primary"><nav>{nav}</nav></aside>
      <div className="shell-main">
        <header>{header}</header>
        <main id="content" tabIndex={-1}>{children}</main>
      </div>
    </div>
  );
}

The shell uses semantic landmarks and a skip link, so keyboard and screen-reader users can bypass the sidebar. Expected behavior: assistive tech announces "Primary navigation," "banner," and "main," and Tab lands on the skip link first. The trade-off is that landmarks only help if you use exactly one of each per page — duplicating main or omitting nav confuses the same tools it's meant to help. An AI assistant scaffolds this shape well because it is conventional, but left to itself it often nests divs and loses the structure, so give it the landmarks explicitly.

The parts: cards, tables, charts

The content region is built from a handful of reusable parts:

  • Stat cards — a label, a value, an optional delta and sparkline. Presentational; they can be Server Components in the App Router.
  • Data tables — the workhorse. Sortable headers, optional pagination, row selection. This is where most complexity and most accessibility bugs live.
  • Charts — line, bar, area. Interactive ones are client components. Never let a chart be the only representation of a number a user might need to read exactly.
// components/stat-card.tsx
export function StatCard({ label, value, delta }: {
  label: string; value: string; delta?: number;
}) {
  return (
    <article className="stat-card">
      <p className="stat-label">{label}</p>
      <p className="stat-value">{value}</p>
      {delta != null && (
        <p className={delta >= 0 ? "up" : "down"}>
          {delta >= 0 ? "+" : ""}{delta}%
        </p>
      )}
    </article>
  );
}

The stat card is pure presentation with a typed contract, so it renders identically everywhere and an assistant cannot pass it a malformed shape. Expected behavior: the delta only appears when provided, colored by sign. The trade-off is that color alone conveys the up/down meaning — pair it with the +/− sign (as here) or an icon so it isn't lost on color-blind users.

// components/data-table.tsx — a real <table>, not a grid of divs
export function DataTable({ caption, columns, rows }: {
  caption: string; columns: string[]; rows: string[][];
}) {
  return (
    <table>
      <caption>{caption}</caption>
      <thead>
        <tr>{columns.map((c) => <th key={c} scope="col">{c}</th>)}</tr>
      </thead>
      <tbody>
        {rows.map((r, i) => (
          <tr key={i}>{r.map((cell, j) => <td key={j}>{cell}</td>)}</tr>
        ))}
      </tbody>
    </table>
  );
}

Using a native <table> with <th scope="col"> and a <caption> gives screen readers real row/column navigation for free. Expected behavior: assistive tech announces headers as it moves across cells. AI assistants frequently render tables as grids of divs, which strips exactly these semantics; the trade-off of the native element is less layout flexibility, which CSS grid on the table can recover without sacrificing semantics.

The four states people forget

This is the single most valuable thing to get right, and the thing AI-generated dashboards most reliably miss. Every data-driven part has four states, not one: loading (a skeleton with aria-busy so the layout doesn't jump), empty (a real "no data yet" message with a next action, not a blank rectangle), error (a clear message and a retry affordance), and data (the happy path).

// A small state machine every data part should honor
function AsyncPanel<T>({ state, children, onRetry }: {
  state: { status: "loading" } | { status: "empty" }
       | { status: "error"; message: string } | { status: "ready"; data: T };
  children: (data: T) => React.ReactNode;
  onRetry?: () => void;
}) {
  switch (state.status) {
    case "loading": return <Skeleton aria-busy="true" />;
    case "empty":   return <EmptyState title="Nothing here yet" />;
    case "error":   return <ErrorState message={state.message} onRetry={onRetry} />;
    case "ready":   return <>{children(state.data)}</>;
  }
}

Modeling the states as a discriminated union makes the missing branches impossible to ignore — TypeScript forces you to handle each one, and if you add a fifth state later the compiler flags every place that doesn't handle it. Expected behavior: the panel renders exactly one branch and never a bare spinner-forever. The trade-off is a little ceremony per part, which is precisely the ceremony that separates a finished dashboard from a demo. When you prompt your assistant, ask for all four explicitly; "build a table for this data" gets you only the last. AETumi's dashboard parts model these four states out of the box.

Real product evidence

The demo below shows a dashboard screen assembled from owned parts — the shell, stat cards, a data table, and an interactive chart — with each fetching part wrapped in the four-state panel. What it proves is that the "states people forget" are not an afterthought bolted on at the end but a structural property of the components: because the empty and error branches exist before the assistant touches the screen, they ship by default rather than by luck. The same owned source that renders this dashboard also carries the platform's cinematic 3D scenes, so a single project holds both the data UI and the standout visual moments in one design language.

Performance

Dashboards are data-heavy, so performance is mostly about fetching and rendering discipline. Fetch independent panels in parallel rather than in a waterfall, and where you use the Next.js App Router, keep static cards and the shell as Server Components so only interactive charts ship JavaScript. For long tables, virtualize rows so a 10,000-row dataset renders only what's visible; for charts, debounce range toggles so a drag doesn't re-render on every frame. An AI assistant rarely virtualizes or parallelizes on its own — it renders the naive version that works on ten rows and stalls on ten thousand. Flag both in review, and measure with real data volumes, not seed data.

Accessibility in a data-dense UI

Dashboards pack a lot of interaction into a small space, which makes accessibility easy to lose and important to keep:

  • Every control reachable and operable by keyboard, with a visible focus ring.
  • Real semantics: table/th for tables, button for actions, nav for navigation, headings in order.
  • A skip link to #content so keyboard users bypass the sidebar.
  • Live updates announced with a polite aria-live region rather than changing silently.
  • Charts given a text alternative — a caption, a data table, or an accessible summary — since color and shape alone exclude some users.

Treat the assistant's accessibility output as a draft. A quick keyboard-only pass through the dashboard surfaces most of what it missed.

Not looking generic

AI-assembled dashboards tend to converge on the same look because they are regenerated from the same generic priors. The fix is ownership: build from your own components and tokens so every screen inherits your spacing, type, color, and radius instead of a default. When the primitives are yours and themable, an assistant filling them produces something that looks like your product, not like every other AI dashboard. Starting from a themable source means that ownership is there from the first screen. For the bigger picture of AI assembling UIs from owned parts, see how AI coding assistants build React UIs.

Production trade-offs

The owned-source approach has real costs. Maintaining a component set and a state-wrapper convention is overhead a one-screen internal tool may not justify. Modeling four states everywhere is more code than a happy-path demo, and the discipline only pays off when the app is used with messy, real data. Virtualization and parallel fetching add complexity you should introduce only when volume demands it — premature optimization is its own trap. And the honest limit of AI here: an assistant accelerates a dashboard, it does not own its correctness. You still verify the empty and error paths, the keyboard flow, and the performance at scale. For a truly static reporting page with fixed numbers and no interaction, a plain server-rendered HTML table may beat any of this.

When to build it this way

SituationWhy it fits
A real product dashboard with live, variable dataThe four states and accessibility are load-bearing, not optional
A team using an AI coding assistant dailyOwned parts let the assistant assemble instead of improvise
Multiple dashboard screens sharing a shellBuild the shell and parts once, reuse everywhere
A branded app that must not look genericToken-driven components carry your identity into every screen

When not to

SituationBetter choice
A one-off static report with fixed numbersA server-rendered HTML table, no state machinery
A throwaway internal tool for one personLet the assistant generate freely; skip the component investment
A single KPI on a marketing pageA styled number, not a dashboard
No capacity to review AI outputFix the process before adding a dashboard; unreviewed states will be wrong

Decision matrix

ApproachStates handledAI reliabilityLooks generic?Best for
AI generates dashboard each timeUsually happy-path onlyLowYesPrototypes
Third-party dashboard kitVaries, can't editMediumSomewhatStandard admin panels
Owned themable source (AETumi)All four, built inHighNoBranded, long-lived products
Hand-code every screenWhatever you writeN/ANoVery small, bespoke tools

Expert notes

Expert Note — Make the four states a type, not a checklist. A discriminated union for loading/empty/error/data means the compiler, not your memory, enforces completeness. If you rely on a code-review checklist to catch a missing empty state, you will miss it under deadline. If you rely on the type, the build fails until every branch is handled. Prompt the assistant to model state this way from the start.

Expert Note — Force the failure paths before you ship. The empty and error states are the two that only appear when something goes wrong, which means they are the two least likely to have been seen. Temporarily return an error from your fetch and a zero-length dataset, and actually look at what renders. This five-minute check catches the "blank rectangle" and "spinner forever" bugs that AI-built dashboards ship most often.

Expert Note — A chart is not a number. Users routinely need the exact value a chart only approximates. Always pair a chart with a text alternative — a caption, an accessible summary, or a toggle to the underlying table. This helps screen-reader users and sighted users who need precision, and it costs almost nothing when the table component already exists in your owned source.

Expert Note — Don't reach for 3D on a data screen. A dashboard's job is legibility; a rotating Three.js globe rarely improves it and often hurts performance and accessibility. Reserve 3D and WebGL for hero moments and product visuals where motion earns its cost, and keep the dashboard itself fast, flat, and readable.

How AETumi approaches it

AETumi is an AI-native 3D web platform, and its React dashboard UI ships as owned, editable source — the shell with its landmarks, stat cards, data tables, and charts, each wired for loading, empty, error, and data. Because the states and accessibility are built in once, an AI assistant filling those parts inherits them instead of guessing. On the Full Stack plan ($129, buy once and own for life), you also get the MCP server, so an assistant like Claude Code or Cursor can discover and install dashboard components directly rather than through copy-paste. The same design language covers the dashboard and the platform's cinematic 3D, so one project carries both. AETumi does not sell "unlimited" anything — you buy the source once at a fixed price and keep it, from React components to full dashboard sets.

GitHub and technical proof

If your dashboard includes 3D or WebGL visuals, the open react-three-fiber-examples repository shows accessible, performant patterns for embedding React Three Fiber scenes inside a React app — how to isolate the canvas as a client island, provide a text alternative, and avoid re-rendering the scene on every dashboard state change. The examples are intentionally minimal so each concept is readable; the limitation is that they demonstrate embedding patterns rather than shipping a full dashboard, which the AETumi dashboard components provide. Performance-wise the examples keep the 3D work off the main dashboard render path, which is exactly the discipline a data screen needs when it also carries a visual. Use the repo to learn the embedding pattern, then compose it with your owned data parts.

The process, step by stepAETumi technical diagram — The process, step by stepStart from ownedsourceAdapt props &variantsWireserver/clientHandleloading/empty/errorShip & reuse
The process, step by step

FAQ

What are the "states people forget" in a dashboard? Loading, empty, and error. AI-generated dashboards almost always render only the data, or happy-path, state. Ask for all four explicitly and model them as a discriminated union so none can be skipped — the compiler then forces every part to handle each branch. Verify the empty and error paths by actually forcing them, because those are the ones no one sees during normal development and the ones users hit constantly.

Should dashboard charts be Server or Client Components? Interactive charts — range toggles, tooltips, hover — must be Client Components, since they need state and event handlers. Static stat cards and the layout shell can stay Server Components in the App Router, which keeps your client bundle smaller and your first paint faster. Keep the interactive chart as a shallow client island rather than marking the whole page client, so only the chart's code ships to the browser.

How do I make an AI-built dashboard not look generic? Build it from components and design tokens you own, and have the assistant fill those rather than generate UI from scratch. Owned, themable primitives carry your brand — spacing, type, color, radius — into every screen instead of a default. A source like AETumi gives you those primitives up front, so even an assistant-assembled screen looks like your product rather than every other AI dashboard.

How should a data table stay accessible? Use a real <table> with <th scope="col">, a <caption>, keyboard-operable sort controls, and a visible focus ring. Avoid recreating tables from divs, which strips the row/column semantics screen readers depend on. If you virtualize rows for performance, make sure the accessible name and header association survive the virtualization so assistive tech still announces columns correctly.

Conclusion

A React dashboard UI is a shell plus a few repeating parts, and building it with an AI coding assistant is fast — as long as you supply what the assistant leaves out: the loading, empty, and error states, real accessibility, and owned components so it looks like your product. Model the states as types, keep the semantics native, theme from tokens, virtualize when data volume demands it, and review by keyboard. AETumi, an AI-native 3D web platform, gives you production-ready React and Next.js dashboard components, 3D scenes, and MCP workflows for AI assistants — a source you own and adapt, buy once and own for life. Start from our dashboard components, see the plans at aetumi.app/pricing, and let your assistant assemble, not improvise.

More from the AETumi library

Real, production-ready assets — preview the motion, grab the source.

Browse all 3D components →