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.

Table of contents

The dashboard shell

Almost every dashboard shares the same frame: a persistent sidebar for navigation, a header with context and account controls, and a scrollable content region that swaps per route. Building this well once — as a real layout with landmark regions — pays off on every screen after.

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
Combined Featured Section
Combined Featured Section — 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">
      <aside aria-label="Primary"><nav>{nav}</nav></aside>
      <div className="shell-main">
        <header>{header}</header>
        <main id="content" tabIndex={-1}>{children}</main>
      </div>
    </div>
  );
}

An AI coding assistant scaffolds this shape well because it is conventional. Give it the semantic landmarks (aside, nav, header, main) explicitly — left to itself it often nests divs and loses the structure screen readers rely on. Owned layout components like these are the foundation of a coherent set of dashboard components, which is why AETumi ships the shell and its landmarks as reviewed source rather than leaving the assistant to reinvent them.

The parts: cards, tables, charts

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

How the pieces connectAETumi technical diagram — How the pieces connectDesignTokensPrimitiveVariantsStatesShip
How the pieces connect
Liquid Metal Button
Liquid Metal Button — live preview from the AETumi library
  • Stat cards — a label, a value, an optional delta and sparkline. Presentational; they can be Server Components if you use 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 (range toggles, tooltips) are client components. Do not 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>
  );
}

For a data table, use a real <table> with <th scope="col"> headers. AI assistants frequently render tables as grids of divs, which strips the semantics that make the data navigable. Insist on the native element unless you have a specific reason not to.

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:

Roadmap Ascent
Roadmap Ascent — live preview from the AETumi library
  • Loading — a skeleton or spinner with aria-busy so the layout doesn't jump and assistive tech announces the wait.
  • Empty — a genuine "no data yet" message with a next action, not a blank rectangle. New accounts and filtered-to-nothing views hit this constantly.
  • Error — a clear message and a retry affordance. The fetch will fail eventually; decide what the user sees when it does.
  • Data — the happy path the assistant gives you by default.
// 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 union type like this makes the missing branches impossible to ignore — TypeScript forces you to handle each one. When you prompt your assistant, ask for all four explicitly; "build a table for this data" will get you only the last. AETumi's dashboard parts model these four states out of the box, so the loading, empty, and error branches are present before the assistant touches them.

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:

Hero ASCII
Hero ASCII — live preview from the AETumi library
  • 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 (a value that refreshes) 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. Starting from a themable source like AETumi means that ownership is there from the first screen. When the primitives are yours and themable, an assistant filling them produces something that looks like your product, not like every other AI dashboard. For the bigger picture of AI assembling UIs from owned parts, see how AI coding assistants build React UIs.

An AI-assisted workflow

1. Build or import the shell and the parts (StatCard, DataTable, Chart wrapper) with your tokens and semantics — or start from AETumi's dashboard components so the shell, parts, and states already exist. 2. Prompt per screen in terms of those parts, and explicitly ask for loading, empty, and error states for anything that fetches. 3. Wire real data — fetch on the server where you can, keep interactive charts as client islands. 4. Do a keyboard and screen-reader pass; fix what the assistant left as div-with-onClick. 5. Verify the empty and error paths by actually forcing them, not just imagining them.

If your dashboard includes 3D or WebGL visuals, the react-three-fiber-examples repo shows accessible, performant patterns for embedding React Three Fiber scenes inside a React app.

Common mistakes

  • Shipping only the happy path — no loading, empty, or error UI.
  • Rendering tables as div grids and losing all table semantics.
  • Making a chart the only way to read a number; provide a text or table alternative.
  • Hardcoding colors so the dashboard can't theme or do dark mode.
  • Putting the whole page in a client component when only the chart needs state.
  • Accepting the assistant's accessibility without a keyboard test.
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 (happy-path) state. Ask for all four explicitly and model them as a union type so none can be skipped.

Should dashboard charts be Server or Client Components? Interactive charts (range toggles, tooltips, hover) must be Client Components. Static stat cards and the layout can stay Server Components in the App Router, which keeps your client bundle smaller.

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 into every screen. A source like AETumi gives you those primitives up front.

How should a data table stay accessible? Use a real <table> with <th scope="col">, keyboard-operable sort controls, a visible focus ring, and a caption or summary. Avoid recreating tables from divs.

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, 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 →