Back to Spree

Admin SPA

docs/plans/6.0-admin-spa.md

5.4.22.9 KB
Original Source

Admin SPA

Status: Design finalized, implementation not started
Target: Spree 6.0
Depends on: API v3 conventions

Key Decisions (do not deviate without discussion)

  • Drop thee rails admin panel entirely
  • Create new Vite/TanStack React admin UI
  • Use Admin API and Admin SDK
  • Use Shadcn UI components
  • No server-side rendering

Migration Path

  • Remove spree/admin engine
  • Create new packages/admin

Architecture

We should use conventions when handling forms, lists, and other UI components to reduce boilerplate and make it easier for developers to extend the admin dashboard.

  • Build & Dev: Vite (obvious choice for a pure client-side SPA — fast HMR, clean config, outputs static files you can bundle into the Rails gem or deploy standalone)
  • Routing: TanStack Router — type-safe routes, file-based convention, built-in loader pattern pairs perfectly with TanStack Query for prefetching on navigation
  • Data Fetching: TanStack Query — handles caching, background refetches, optimistic updates. Your @spree/admin-sdk becomes the query function layer. Wrap SDK methods as custom hooks (useProducts, useOrder, etc.)
  • Forms: React Hook Form + Zod for validation schemas. Zod schemas can mirror your API contracts, and if you're auto-generating types from OpenAPI specs, you can derive Zod schemas from the same source
  • UI: shadcn/ui + Tailwind. Copy-paste ownership model means your plugin authors can extend or override components without fighting a component library's abstraction
  • Auth: For JWT — store the access token in memory (React context/state), refresh token in an httpOnly cookie if possible, or memory as fallback. TanStack Router's beforeLoad guards check auth state before rendering protected routes. A simple AuthProvider context that exposes login(), logout(), getToken() and injects the token into the SDK client instance
  • State: You likely don't need a global state library. TanStack Query covers server state, React Hook Form covers form state, and a small AuthContext covers the session. If something edges toward complex client-only state later, Zustand is the lightest option that won't fight you
  • Linting/Formatting: Biome — single tool, fast, no ESLint/Prettier config sprawl
  • Testing: Vitest + React Testing Library for unit/integration, Playwright for E2E

Extension points

Developers will be able to extend the admin dashboard by adding custom pages, components, and logic.

There are 3 main areas where developers can extend the admin dashboard:

  1. Navigation - needs to be configurable via registry
  2. Tables - record listing, eg. products, orders. Developers need to be able to customize table columns and filters.
  3. Pages - developers should be able to add custom pages, extend routes, and add custom logic.
  4. Components - developers should be able to add custom components and extend existing ones. Developers should be able to inject their own components into existing pages, eg. new fields on product form page.