react-resource-view
Quickstart
Five minutes from zero to a list on your API, then a filter and a second layout.
Five minutes, from nothing to a list running on your API, then a filter and a second way to look at the same rows. Every step ends on what you should see on screen.
1. A project on your API#
Either let the starter write the application around your API — a Vite and React back office with the dialect wired and one example resource:
npx react-resource-view init my-admin
cd my-admin
npm install
npm run devIt asks which API you talk to (API Platform, Spring Boot, Supabase, Strapi, FastAPI, Django or any REST API) and where it runs. Start a project lists every flag and every file it writes. You should see a back office on http://localhost:5173, with its menu and the example resource. Skip to step 2 to make it yours.
Or add the package to an application you already have:
pnpm add react-resource-view react-data-form react-mini-i18n resource-registry@import "tailwindcss";
@source "../node_modules/react-resource-view/dist";
@source "../node_modules/react-data-form/dist";
@import "react-resource-view/styles.css";import { configureApi, configurePorts } from "react-resource-view"
import { tanstackAdapter } from "react-resource-view/tanstack"
configurePorts({ navigation: tanstackAdapter })
configureApi({
baseUrl: "https://api.example.com",
getAuthToken: () => localStorage.getItem("token") ?? undefined,
// jsonLdDialect() by default — see Backends for the others.
})Import setup.ts once, before anything renders. The pieces are detailed in Installation, the other backends in Backends & dialects.
The browser calls the API
The views fetch from the reader's browser: the API has to allow the origin your application is served from. Without CORS the list stays empty and the console says why.
2. Declare a resource#
One declaration per resource: where it lives on the API, and the fields. Those fields are the create and edit form and the table's columns.
import { createViewResource } from "react-resource-view"
export const articles = createViewResource("articles", {
name: "Articles",
path: "/api/articles",
form: {
inputs: {
title: { label: "Title", required: true },
author: { label: "Author" },
},
},
})Declaring a resource covers the repository behind it and every key of the declaration.
3. The list, from your API#
Render it:
import { ActionList } from "react-data-form"
import { ViewResourceContextProvider } from "react-resource-view"
export function ArticlesPage() {
return (
<ViewResourceContextProvider
resource={articles}
resourceAction={ActionList.list}
/>
)
}You should see a table with one row per record the API returns, a pager, a button to create one, and on each row the edit and delete actions — every action is offered unless permissions restricts it, and the five screens come from the one declaration:
The list — rows read from the API
4. Add a filter#
The filter bar is an ordinary form description, in views.list.filters. Its values go out with the request and into the URL.
form: { … },
views: {
list: {
filters: {
inputs: {
title: { label: "Search a title" },
status: {
label: "Status",
controller: SelectInputController,
valueOptions: STATUSES,
},
},
},
},
}You should see a bar above the table. Type in it and the rows narrow down; reload the page and the filter is still there. Filters explains defaults and the URL.
Type a title or pick a status
5. Add a second layout#
Layouts are a list. Declare two and the view shows a switcher; the reader picks, and the choice survives a reload.
import { layout } from "react-resource-view"
form: { … },
views: {
list: {
filters: { … },
layouts: [layout.table(), layout.cards({ columns: 3 })],
},
}You should see a switcher above the filter bar. Pick Cards and the same rows, with the same filter, become a grid:
Same resource, same filter — as cards
Where to go next#
Choosing a layout has the five others (split, board, calendar, timeline…); Routing puts the views on real URLs; Types from OpenAPI types the resources from your API's schema.