Skip to main content

<ResourceSchema>

Props

PropTypeDefaultDescription
namestringRequired. The unique identifier for the resource (e.g., "products").
childrenReactNodeField components (e.g., <TextField>) that define the data model.
listComponent|false<List>Override the default List View with a custom component or disable it with false.
editComponent|false<Edit>Override the default Edit Form with a custom component or disable it with false.
createComponent|false<Create>Override the default Create Form with a custom component or disable it with false.
detailComponent|false<Detail>Override the default Detail View with a custom component or disable it with false.
listComponentComponent<Table>Custom component to use for the List View. Must be schema-aware to utilize the field definitions.
detailComponentComponent<DetailHub>Custom component to use for the Detail View. Must be schema-aware to utilize the field definitions.
listTitleReactNodeCustom title for the List View.
listDescriptionReactNodeCustom description for the List View.
listIncludestring[]Fields to include in the List View.
listExcludestring[]Fields to hide from the List View.
listDisplaystring[]Fields to display by default in the List View table.
defaultSortSortObjectThe initial sort order for the resource.
perPagenumberNumber of items to display per page (default: 10).
defaultFiltersanyPermanent filters applied to all data fetching for this resource.
detailTitleReactNode | fnCustom title for the Detail View. String values support ICU variables from the record (e.g. "Product: {name}").
detailDescriptionReactNode | fnCustom description for the Detail View. String values support ICU variables from the record.
detailIncludestring[]Fields to include in the Detail View.
detailExcludestring[]Fields to hide from the Detail View.
editTitleReactNode | fnCustom title for the Edit Form. String values support ICU variables from the record (e.g. "Edit Product - {name}").
editDescriptionReactNode | fnCustom description for the Edit Form. String values support ICU variables from the record.
formIncludestring[]Fields to include in both Create and Edit Forms (shared fallback).
formExcludestring[]Fields to exclude from both Create and Edit Forms (shared fallback).
editIncludestring[]Fields to include in the Edit Form (takes priority over formInclude).
editExcludestring[]Fields to exclude from the Edit Form (takes priority over formExclude).
createIncludestring[]Fields to include in the Create Form (takes priority over formInclude).
createExcludestring[]Fields to exclude from the Create Form (takes priority over formExclude).
createTitleReactNodeCustom title for the Create Form.
createDescriptionReactNodeCustom description for the Create Form.
deletebooleantrueSet to false to disable delete functionality for this resource.
queryOptionsobjectOptions passed to the data provider for all queries (e.g., meta: { embed: ['category'] }).

list

By default, the List View is generated automatically based on the defined fields. You can disable it or replace it with a custom component.

Set list={false} to hide the resource from the sidebar and prevent access to the list page, while still allowing access to the Detail, Create, and Edit views. The resource can still be used as a reference in other resources.

<ResourceSchema name="products" list={false}>
{/* fields */}
</ResourceSchema>

To use a custom list component while still benefiting from the schema context:

<ResourceSchema name="products" list={MyCustomList}>
{/* schema definition */}
</ResourceSchema>

edit

Disable the Edit Form with edit={false} or provide a custom component. If you disable the Edit Form, the Edit button will be hidden from the Detail View, but the Create Form and List View will still be accessible.

create

Disable the Create Form with create={false} or provide a custom component. If you disable the Create Form, the "Create" button will be hidden from the List View, but the Edit Form and Detail View will still be accessible.

detail

Disable the Detail View with detail={false} or provide a custom component. If you disable the Detail View, the fields that link to the detail page will no longer be clickable.

delete

Set delete={false} to remove delete functionality from this resource. This hides the delete button from both the Detail View and the Edit Form.

<ResourceSchema name="products" delete={false}>
{/* fields */}
</ResourceSchema>

queryOptions

Options passed to the data provider for all queries made against this resource. Useful for passing meta parameters to REST APIs, such as embedding related resources.

<ResourceSchema name="products" queryOptions={{ meta: { embed: ['category'] } }}>
<TextField source="id" />
<TextField source="name" />
<ReferenceField source="categoryId" reference="categories" />
</ResourceSchema>

The queryOptions value is forwarded to every getList, getOne, and getMany call made by schema-aware components for this resource.

listComponent

By default, the List View uses a <Table> component that is aware of the fields defined in the schema. You can provide other schema-aware components like <Cards> or a custom component.

<ResourceSchema name="products" listComponent={Cards}>
<TextField source="id" />
<TextField source="name" />
</ResourceSchema>

detailComponent

The Detail View defaults to a <DetailHub> that organizes fields in 3 columns. You can override this with any schema-aware component.

const MyDetailHub2 = (props) => {
const { children, columns: _, ...rest } = props;
return (
<DetailHub columns={2} {...rest}>
{children}
</DetailHub>
);
};

<ResourceSchema name="products" detailComponent={MyDetailHub2}>
<TextField source="id" />
<TextField source="name" />
</ResourceSchema>;

defaultSort

Defines the default sorting for the List View.

<ResourceSchema name="products" defaultSort={{ field: 'createdAt', order: 'DESC' }}>
<TextField source="id" />
<TextField source="name" />
<DateField source="createdAt" />
</ResourceSchema>

Honored by all schema-aware collection components: <Table>, <Cards>, <ReferenceInput>, etc.

perPage

Sets the default number of items per page in the List View.

<ResourceSchema name="products" perPage={25}>
<TextField source="id" />
<TextField source="name" />
<CurrencyField source="price" currency="USD" />
</ResourceSchema>

defaultFilters

Applies permanent filters to all data fetching for this resource. Applied to all schema-aware collection components including <Table>, <Cards>, and <ReferenceInput>.

<ResourceSchema name="products" defaultFilters={{ status: 'active' }}>
<TextField source="id" />
<TextField source="name" />
<TextField source="status" />
</ResourceSchema>

Use this when a resource should always be scoped — for example, showing only pending tasks:

<ResourceSchema name="tasks" defaultFilters={{ status: 'pending' }}>
{/* fields */}
</ResourceSchema>

Field Control Props

Control which fields appear in which views without creating separate custom components.

listInclude, listExclude

By default, all fields defined in the schema are included in the List View. Use listInclude to specify a subset, or listExclude to hide specific fields.

<ResourceSchema name="products" listInclude={['id', 'name', 'price']}>
<TextField source="id" />
<TextField source="name" />
<CurrencyField source="price" currency="USD" />
<TextField source="description" />
</ResourceSchema>
<ResourceSchema name="products" listExclude={['description']}>
<TextField source="id" />
<TextField source="name" />
<CurrencyField source="price" currency="USD" />
<TextField source="description" />
</ResourceSchema>

listDisplay

Fields to display by default in the List View table. Users can still toggle other included fields using the table's column preferences.

<ResourceSchema name="products" listDisplay={['id', 'name']} listExclude={['description']}>
<TextField source="id" />
<TextField source="name" />
<CurrencyField source="price" currency="USD" />
<TextField source="description" />
</ResourceSchema>

detailInclude, detailExclude

Controls which fields appear in the Detail View.

<ResourceSchema name="products" detailExclude={['internalNotes']}>
<TextField source="id" />
<TextField source="name" />
<TextField source="internalNotes" />
</ResourceSchema>

formInclude, formExclude

Controls which fields appear in both Create and Edit Forms as a shared baseline.

<ResourceSchema name="products" formExclude={['id']}>
<TextField source="id" />
<TextField source="name" />
<CurrencyField source="price" currency="USD" />
</ResourceSchema>

IDs are a common case: use <IdField> (a <TextField> with input={false}) to display the ID in read views while automatically excluding it from all forms.

<ResourceSchema name="products">
<IdField source="id" />
<TextField source="name" />
</ResourceSchema>

editInclude, editExclude, createInclude, createExclude

For finer-grained control, these view-specific props override formInclude/formExclude for a single form type.

A common use case is showing a password field only on the Create form, and hiding auto-generated fields like createdAt only on the Edit form:

<ResourceSchema name="users" createInclude={['name', 'email', 'password']} editExclude={['createdAt', 'updatedAt']}>
<TextField source="name" isRequired />
<TextField source="email" isRequired />
<TextField source="password" isRequired />
<DateField source="createdAt" />
<DateField source="updatedAt" />
</ResourceSchema>

You can also combine formExclude (shared baseline) with createExclude (additional exclusions for create only):

<ResourceSchema name="products" formExclude={['id']} createExclude={['sku']}>
{/* id hidden in both; sku hidden in create only */}
<TextField source="id" />
<TextField source="sku" />
<TextField source="name" isRequired />
</ResourceSchema>

Label Props

Custom titles and descriptions for each view. Each prop accepts a string, a React element, or (for Edit and Detail) a function that receives the current record.

<ResourceSchema
name="products"
listTitle="Product List"
createTitle="Create New Product"
detailTitle="Product: {name}"
editTitle="Edit Product - {name}"
>
{/* fields */}
</ResourceSchema>

listTitle, listDescription

Custom title and description for the List View. Accept a string or any React element.

createTitle, createDescription

Custom title and description for the Create Form. Accept a string or any React element.

detailTitle, detailDescription

Custom title and description for the Detail View. Accept a string, a React element, or a function (record) => ReactNode.

When a string is provided it is treated as an ICU message. All record fields are available as named variables:

// Simple variable interpolation
<ResourceSchema name="products" detailTitle="Product: {name}" />

// ICU plural rules
<ResourceSchema name="orders" detailTitle="Order #{id} with {count_items, plural, one {# item} other {# items}}" />

// Function form for full control
<ResourceSchema name="products" detailTitle={(record) => record.name} />

// React element
<ResourceSchema name="products" detailTitle={<TextField source="name" />} />
If you plan to translate your app

Prefer the ICU string form over a function. Strings like "Product: {name}" are picked up by the i18n CLI and can be translated — the {name} variable is resolved at runtime after translation. A function like (record) => record.name bypasses the translation system entirely and cannot be extracted or localized.

editTitle, editDescription

Custom title and description for the Edit Form. Accept a string, a React element, or a function (record) => ReactNode.

// Variable interpolation from the record
<ResourceSchema name="products" editTitle="Edit Product - {name}" />

// Function form for full control
<ResourceSchema name="products" editTitle={(record) => `Edit ${record.name}`} />
If you plan to translate your app

Prefer the ICU string form over a function. Strings like "Edit Product - {name}" are picked up by the i18n CLI and can be translated — the {name} variable is resolved at runtime after translation. A function that constructs the string in JavaScript bypasses the translation system entirely and cannot be extracted or localized.