How to Use ListPage, ShowPage, CreatePage, and EditPage Components in refine-shadcn

Use the four pre-built CRUD wrappers ListPage, ShowPage, CreatePage, and EditPage from ferdiunal/refine-shadcn to render fully-styled resource pages with automatic headers, breadcrumbs, and action buttons by nesting your table or form components inside them.

The ferdiunal/refine-shadcn library provides production-ready page components that integrate the Refine data framework with the shadcn/ui design system. These wrappers eliminate boilerplate UI logic—such as back navigation, permission-based action buttons, and i18n-aware titles—allowing you to focus entirely on data presentation while maintaining a consistent visual hierarchy across your application.

ListPage – Displaying Resource Tables

ListPage renders a collection view with a dynamic header, breadcrumb navigation, and an optional Create button. It is implemented in [packages/theme/src/curds/list.tsx](https://github.com/ferdiunal/refine-shadcn/blob/main/packages/theme/src/curds/list.tsx).

Key Features

  • Automatic resource resolution: Uses the useResource hook to derive the resource identifier from props or context.
  • Dynamic titles: Defaults to "List {Resource}" via useTranslate, or accepts a custom title prop.
  • Permission-aware actions: Renders a CreateButton when canCreate is true.
  • Consistent padding: Wraps children in a responsive container with standardized spacing.

Usage Example

The following example from [templates/vite-react/src/pages/users/list.tsx](https://github.com/ferdiunal/refine-shadcn/blob/main/templates/vite-react/src/pages/users/list.tsx) demonstrates a typical user list implementation:

import { ListPage, Table } from "@ferdiunal/refine-shadcn";
import { Checkbox } from "@/components/ui/checkbox";

export const UserList = () => (
    <ListPage>
        <Table enableSorting enableFilters>
            <Table.Column
                accessorKey="id"
                id="select"
                header={({ table }) => (
                    <Table.CheckAll options={[bulkDeleteAction(table)]} table={table} />
                )}
                cell={({ row }) => (
                    <Checkbox
                        checked={row.getIsSelected()}
                        onCheckedChange={(v) => row.toggleSelected(!!v)}
                    />
                )}
            />
            <Table.Column header="First Name" accessorKey="firstName" />
            <Table.Column header="Last Name" accessorKey="lastName" />
            <Table.Column
                accessorKey="id"
                id="actions"
                cell={({ row: { original } }) => (
                    <Table.Actions>
                        <Table.ShowAction resource="users" row={original} />
                        <Table.EditAction resource="users" row={original} />
                        <Table.DeleteAction resource="users" row={original} />
                    </Table.Actions>
                )}
            />
        </Table>
    </ListPage>
);

The Table component automatically wires into react-table for sorting, filtering, and pagination, while ListPage handles the page chrome.

ShowPage – Presenting Single Records

ShowPage displays a detailed view of a single record with back navigation and Edit/Delete actions. Its source resides in [packages/theme/src/curds/show/index.tsx](https://github.com/ferdiunal/refine-shadcn/blob/main/packages/theme/src/curds/show/index.tsx).

Key Features

Usage Example

From [templates/vite-react/src/pages/users/Show.tsx](https://github.com/ferdiunal/refine-shadcn/blob/main/templates/vite-react/src/pages/users/Show.tsx):

import { ShowPage } from "@ferdiunal/refine-shadcn";
import { useShow } from "@refinedev/core";

export const UserShow = () => {
    const { query: { data } } = useShow();
    const record = data?.data;

    return (
        <ShowPage>
            <ShowPage.Row title="ID" children={record?.id as number} />
            <ShowPage.Row title="First Name" children={record?.firstName?.toString() || ""} />
            <ShowPage.Row title="Last Name" children={record?.lastName?.toString() || ""} />
            <ShowPage.Row title="Email" children={record?.email?.toString() || ""} />
        </ShowPage>
    );
};

CreatePage – Adding New Records

CreatePage provides a form container with back navigation and a List button. The implementation is located in [packages/theme/src/curds/create.tsx](https://github.com/ferdiunal/refine-shadcn/blob/main/packages/theme/src/curds/create.tsx).

Key Features

  • Header actions: Includes a ListButton in the extra slot by default, allowing quick navigation to the collection view.
  • Flexible content: Accepts any child component, typically a form handling data mutation.
  • i18n support: Translates the default title as "Create {Resource}" unless overridden.

Usage Example

From [templates/vite-react/src/pages/users/Create.tsx](https://github.com/ferdiunal/refine-shadcn/blob/main/templates/vite-react/src/pages/users/Create.tsx):

import { CreatePage } from "@ferdiunal/refine-shadcn";
import { UserForm } from "./Form";

export const UserCreate = () => (
    <CreatePage>
        <UserForm redirect="edit" />
    </CreatePage>
);

The redirect="edit" prop instructs the form to navigate to the edit view upon successful creation.

EditPage – Modifying Existing Records

EditPage wraps update forms and provides Show and Delete actions alongside back navigation. See [packages/theme/src/curds/edit.tsx](https://github.com/ferdiunal/refine-shadcn/blob/main/packages/theme/src/curds/edit.tsx).

Key Features

Usage Example

From [templates/vite-react/src/pages/users/Edit.tsx](https://github.com/ferdiunal/refine-shadcn/blob/main/templates/vite-react/src/pages/users/Edit.tsx):

import { EditPage } from "@ferdiunal/refine-shadcn";
import { UserForm } from "./Form";

export const UserEdit = () => (
    <EditPage>
        <UserForm redirect="edit" />
    </EditPage>
);

Customizing Headers and Actions

All four components accept an extra prop to override default header actions and a title prop to customize the page heading. The underlying PageHeader component (shared across all pages) processes breadcrumb, isBack, and extra slots uniformly.

For example, to replace the default List button on a Create page with a custom action:

<CreatePage extra={<CustomAction />}>
    <UserForm />
</CreatePage>

Summary

Frequently Asked Questions

How do I customize the page title in refine-shadcn CRUD components?

Pass a string to the title prop on any page component. If omitted, the component calls useTranslate with the resource identifier to generate a default such as "List Users" or "Create User".

Can I remove the default Create button from ListPage?

Set canCreate={false} on the ListPage component. This boolean prop controls whether the CreateButton appears in the header's extra slot.

How do I add custom actions to the page header?

Use the extra prop to inject any React element. This overrides the default actions while preserving the back button and breadcrumb logic. For example, <ListPage extra={<CustomExportButton />}> replaces the Create button with your custom control.

What TypeScript types do these components use?

The types are defined in [packages/theme/src/types/curds.d.ts](https://github.com/ferdiunal/refine-shadcn/blob/main/packages/theme/src/types/curds.d.ts). Each component exports a corresponding interface—ListProps, ShowProps, CreateProps, and EditProps—that extends Refine's core UI props with shadcn/ui-specific styling options.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →