Skip to main content
Refine provides button components that handle common actions like navigation, data mutations, and exports. These buttons work consistently across all UI frameworks and include built-in features like loading states, confirmations, and access control.

CreateButton

Navigate to the create page for a resource.

Basic Usage

import { CreateButton } from "@refinedev/antd";

function ProductList() {
  return <CreateButton />;
}

Props

PropTypeDescription
resourcestringResource name (auto-detected from route)
metaobjectMeta data for navigation
hideTextbooleanHide button text, show icon only
accessControlobjectAccess control configuration
onClickfunctionCustom click handler

Examples

import { CreateButton } from "@refinedev/antd";

// Default - detects resource from route
<CreateButton />

// Specific resource
<CreateButton resource="products" />

// Icon only
<CreateButton hideText />

// Custom handler
<CreateButton onClick={(e) => {
  e.preventDefault();
  // Custom logic
}} />

// With access control
<CreateButton
  accessControl={{
    enabled: true,
    hideIfUnauthorized: true,
  }}
/>

EditButton

Navigate to the edit page for a record.

Basic Usage

import { EditButton } from "@refinedev/antd";

function ProductList() {
  return <EditButton recordItemId="1" />;
}

Props

PropTypeDescription
recordItemIdstring | numberRecord ID to edit
resourcestringResource name
metaobjectMeta data for navigation
hideTextbooleanHide button text
accessControlobjectAccess control configuration

Examples

// In a table
<Table.Column
  title="Actions"
  render={(_, record) => <EditButton recordItemId={record.id} />}
/>

// Icon only
<EditButton recordItemId="1" hideText size="small" />

// Different resource
<EditButton resource="products" recordItemId="1" />

ShowButton

Navigate to the show page for a record.

Basic Usage

import { ShowButton } from "@refinedev/antd";

function ProductList() {
  return <ShowButton recordItemId="1" />;
}

Props

Same as EditButton.

Examples

// In a table
<Table.Column
  title="Actions"
  render={(_, record) => (
    <Space>
      <ShowButton recordItemId={record.id} hideText />
      <EditButton recordItemId={record.id} hideText />
    </Space>
  )}
/>

DeleteButton

Delete a record with confirmation dialog.

Basic Usage

import { DeleteButton } from "@refinedev/antd";

function ProductList() {
  return <DeleteButton recordItemId="1" />;
}

Props

PropTypeDescription
recordItemIdstring | numberRecord ID to delete
resourcestringResource name
metaobjectMeta data for mutation
hideTextbooleanHide button text
confirmTitlestringConfirmation dialog title
confirmOkTextstringConfirmation OK button text
confirmCancelTextstringConfirmation cancel button text
onSuccessfunctionSuccess callback
accessControlobjectAccess control configuration

Examples

import { DeleteButton } from "@refinedev/antd";

// Default with confirmation
<DeleteButton recordItemId="1" />

// Custom confirmation text
<DeleteButton
  recordItemId="1"
  confirmTitle="Delete this product?"
  confirmOkText="Yes, delete"
  confirmCancelText="No, keep it"
/>

// With success callback
<DeleteButton
  recordItemId="1"
  onSuccess={() => {
    notification.success({
      message: "Product deleted successfully",
    });
  }}
/>

// Danger variant
<DeleteButton recordItemId="1" danger />

ListButton

Navigate to the list page for a resource.

Basic Usage

import { ListButton } from "@refinedev/antd";

function ProductEdit() {
  return <ListButton />;
}

Props

PropTypeDescription
resourcestringResource name
metaobjectMeta data for navigation
hideTextbooleanHide button text

Examples

// Back to list from edit/show page
<ListButton />

// Specific resource
<ListButton resource="products" />

// Icon only
<ListButton hideText />

RefreshButton

Refresh the current page data.

Basic Usage

import { RefreshButton } from "@refinedev/antd";

function ProductShow() {
  return <RefreshButton />;
}

Props

PropTypeDescription
resourcestringResource name
recordItemIdstring | numberRecord ID
hideTextbooleanHide button text
onClickfunctionCustom click handler

Examples

// Auto-refresh current page
<RefreshButton />

// Custom resource
<RefreshButton resource="products" recordItemId="1" />

// Icon only
<RefreshButton hideText />

SaveButton

Submit a form.

Basic Usage

import { SaveButton } from "@refinedev/antd";

function ProductForm() {
  return <SaveButton />;
}

Props

PropTypeDescription
hideTextbooleanHide button text
loadingbooleanLoading state
disabledbooleanDisabled state
onClickfunctionCustom click handler

Examples

import { Create, useForm, SaveButton } from "@refinedev/antd";
import { Form, Input } from "antd";

export const ProductCreate = () => {
  const { formProps, saveButtonProps } = useForm();

  return (
    <Create
      saveButtonProps={saveButtonProps}
      footerButtons={({ defaultButtons }) => (
        <>
          <SaveButton {...saveButtonProps} />
          <Button>Save as Draft</Button>
        </>
      )}
    >
      <Form {...formProps}>
        <Form.Item name="name">
          <Input />
        </Form.Item>
      </Form>
    </Create>
  );
};

CloneButton

Clone a record by navigating to create page with pre-filled data.

Basic Usage

import { CloneButton } from "@refinedev/antd";

function ProductShow() {
  return <CloneButton recordItemId="1" />;
}

Props

PropTypeDescription
recordItemIdstring | numberRecord ID to clone
resourcestringResource name
metaobjectMeta data for navigation
hideTextbooleanHide button text

Examples

// Clone current record
<CloneButton recordItemId="1" />

// In show page header
<Show
  headerButtons={({ defaultButtons }) => (
    <>
      {defaultButtons}
      <CloneButton />
    </>
  )}
>
  {/* Content */}
</Show>

ExportButton

Export table data to CSV or Excel.

Basic Usage

import { ExportButton, useTable } from "@refinedev/antd";

export const ProductList = () => {
  const { tableProps, tableQueryResult } = useTable();

  return (
    <List headerButtons={<ExportButton />}>
      <Table {...tableProps} />
    </List>
  );
};

Props

PropTypeDescription
hideTextbooleanHide button text
loadingbooleanLoading state
onClickfunctionCustom export handler

Custom Export

import { ExportButton } from "@refinedev/antd";
import { useExport } from "@refinedev/core";

function ProductList() {
  const { triggerExport, isLoading } = useExport({
    resource: "products",
    mapData: (item) => ({
      id: item.id,
      name: item.name,
      price: `$${item.price}`,
    }),
  });

  return (
    <ExportButton
      onClick={triggerExport}
      loading={isLoading}
    />
  );
}

ImportButton

Trigger import functionality for bulk data upload.

Basic Usage

import { ImportButton } from "@refinedev/antd";

function ProductList() {
  return <ImportButton />;
}

Props

PropTypeDescription
hideTextbooleanHide button text
loadingbooleanLoading state
onClickfunctionCustom import handler

Button Groups

Combine multiple buttons together:
import { Space } from "antd";
import { EditButton, ShowButton, DeleteButton } from "@refinedev/antd";

function ActionButtons({ record }) {
  return (
    <Space>
      <ShowButton recordItemId={record.id} hideText size="small" />
      <EditButton recordItemId={record.id} hideText size="small" />
      <DeleteButton recordItemId={record.id} hideText size="small" />
    </Space>
  );
}

Access Control

Buttons automatically respect access control rules:
import { Refine } from "@refinedev/core";
import { CreateButton, EditButton, DeleteButton } from "@refinedev/antd";

const accessControlProvider = {
  can: async ({ resource, action }) => {
    // Your access control logic
    if (resource === "products" && action === "delete") {
      return { can: false };
    }
    return { can: true };
  },
};

function App() {
  return (
    <Refine
      accessControlProvider={accessControlProvider}
      // ... other props
    >
      {/* DeleteButton will be hidden for products */}
      <DeleteButton resource="products" recordItemId="1" />
    </Refine>
  );
}

Custom Buttons

Create custom action buttons using Refine hooks:
import { useNavigation, useDelete } from "@refinedev/core";
import { Button } from "antd";

function CustomButton({ recordItemId }) {
  const { show } = useNavigation();
  const { mutate, isLoading } = useDelete();

  const handleArchive = () => {
    mutate({
      resource: "products",
      id: recordItemId,
      meta: {
        action: "archive", // Custom action
      },
    });
  };

  return (
    <Button onClick={handleArchive} loading={isLoading}>
      Archive
    </Button>
  );
}

Best Practices

  1. Icon Only Buttons: Use hideText for compact layouts like tables
  2. Loading States: Buttons show loading automatically during mutations
  3. Confirmations: Use confirmation dialogs for destructive actions
  4. Access Control: Rely on built-in access control integration
  5. Consistent Placement: Place action buttons in consistent locations
  6. Mobile Friendly: Test button groups on mobile devices

Common Patterns

List Page Header

import { List, CreateButton, ExportButton, ImportButton } from "@refinedev/antd";
import { Space } from "antd";

export const ProductList = () => {
  return (
    <List
      headerButtons={({ defaultButtons }) => (
        <Space>
          <ImportButton />
          <ExportButton />
          {defaultButtons}
        </Space>
      )}
    >
      {/* Table */}
    </List>
  );
};

Show Page Header

import { Show, EditButton, DeleteButton, RefreshButton, ListButton } from "@refinedev/antd";
import { Space } from "antd";

export const ProductShow = () => {
  return (
    <Show
      headerButtons={({ defaultButtons, editButtonProps, deleteButtonProps }) => (
        <Space>
          <ListButton />
          <EditButton {...editButtonProps} />
          <DeleteButton {...deleteButtonProps} />
          <RefreshButton />
        </Space>
      )}
    >
      {/* Content */}
    </Show>
  );
};

Edit Page Header

import { Edit, DeleteButton, RefreshButton, ListButton } from "@refinedev/antd";
import { Space } from "antd";

export const ProductEdit = () => {
  return (
    <Edit
      headerButtons={({ defaultButtons }) => (
        <Space>
          <ListButton />
          <RefreshButton />
          {defaultButtons}
          <DeleteButton />
        </Space>
      )}
    >
      {/* Form */}
    </Edit>
  );
};

Table Action Column

import { List, useTable, EditButton, ShowButton, DeleteButton } from "@refinedev/antd";
import { Table, Space } from "antd";

export const ProductList = () => {
  const { tableProps } = useTable();

  return (
    <List>
      <Table {...tableProps} rowKey="id">
        <Table.Column dataIndex="name" title="Name" />
        <Table.Column
          title="Actions"
          fixed="right"
          render={(_, record) => (
            <Space size="small">
              <ShowButton recordItemId={record.id} hideText size="small" />
              <EditButton recordItemId={record.id} hideText size="small" />
              <DeleteButton recordItemId={record.id} hideText size="small" />
            </Space>
          )}
        />
      </Table>
    </List>
  );
};

Next Steps

CRUD Components

Build data interfaces

Field Components

Display data fields

Navigation

Learn about navigation hooks

Access Control

Implement access control

Build docs developers (and LLMs) love