Install
Emit the fetch client into your frontend, point shadcn at the @quickback registry, and add the components.
Requirements
- A React app initialised with a shadcn base-ui style.
components.jsonhas"style": "base-…". For a new Vite app:npx shadcn@latest init -t vite -b base -p nova - The
@/import alias. The shadcn templates set it up. - The emitted client at
@/lib/quickback.client. Every item imports it from that path.
1. Emit the client into the frontend
In quickback.config.ts, point client at the frontend's src/lib/. Put
the types output next to it. The client imports Api and Qb from the
first types output by relative path, so keeping both inside the frontend
keeps its tsconfig self-contained.
import { defineConfig } from "@quickback/compiler";
export default defineConfig({
name: "my-app",
types: { output: "web/src/lib/quickback.gen.ts" },
client: "web/src/lib/quickback.client.ts",
});client requires types. The compile fails if types is false.
quickback build rewrites both files on every compile. Don't edit them. See
Fetch client for the full client API.
The components read the schema registry from GET /api/v1/schema. By
default only platform sysadmins may read it. For a UI that other users use,
widen it with schemaRegistry.access:
export default defineConfig({
schemaRegistry: { access: "member" }, // any organization member
// schemaRegistry: { access: "authenticated" }, // any signed-in user (apps without organizations)
});Without this, every component shows a 403 CMS_ACCESS_DENIED error. When
cms is also enabled, schemaRegistry.access must equal cms.access. The
route gates the CMS too, so widening one must not silently widen the other.
2. Add the registry
Namespace (recommended). Add the registry to the frontend's
components.json:
{
"registries": {
"@quickback": "https://docs.quickback.dev/r/{style}/{name}.json"
}
}npx shadcn add @quickback/quickback-provider @quickback/resource-table @quickback/resource-form @quickback/action-dialogshadcn fills {style} from components.json. Only base-* style paths
exist, so a Radix project stops here with nothing written:
The item at https://docs.quickback.dev/r/radix-nova/resource-table.json was not found. It may not exist at the registry.
Message:
[Quickback registry items support shadcn base-ui styles only; "radix-nova" is not one. See https://docs.quickback.dev/ui/components]Direct URL. Add one item without configuring the namespace:
npx shadcn add https://docs.quickback.dev/r/resource-table.jsonDirect URLs resolve quickback-provider for you, but they skip the style
check. Use them only on a base-ui project.
| URL | Serves |
|---|---|
https://docs.quickback.dev/r/registry.json | Registry index |
https://docs.quickback.dev/r/{name}.json | One item (direct-URL installs) |
https://docs.quickback.dev/r/base-{style}/{name}.json | One item (namespace installs) |
{name} is one of quickback-provider, resource-table, resource-form, action-dialog.
3. What gets installed
| Item | Files | Also installs |
|---|---|---|
quickback-provider | components/quickback-provider.tsx | @tanstack/react-query@^5 |
resource-table | components/resource-table.tsx | button, dropdown-menu, input, label, table, @remixicon/react |
resource-form | components/resource-form.tsx | button, checkbox, combobox, input, label, native-select, textarea, @remixicon/react |
action-dialog | components/action-dialog.tsx | button, checkbox, dialog, input, label, native-select, @remixicon/react |
Every item except quickback-provider depends on it, so adding any one of
them pulls it in. Re-run shadcn add with --overwrite to take a newer
version. That replaces any local edits you made to those files.
4. Wire it up
// web/src/main.tsx
import { createClient } from "@/lib/quickback.client"
import { QuickbackProvider } from "@/components/quickback-provider"
const client = createClient({ baseUrl: import.meta.env.VITE_API_URL })
createRoot(document.getElementById("root")!).render(
<QuickbackProvider client={client}>
<App />
</QuickbackProvider>,
)Next: Auth to sign users in. For the whole flow, see Build a frontend.