Admin Experience
Application patterns for making Admin forms react to editor input and stay easier to use as content gets more structured.
Use these patterns when the underlying content model is already clear, but the editing experience needs to be more guided. They help reduce clutter, keep related fields in sync, and make forms respond to what the editor is doing.
Show an Admin field only when it is relevant
Problem: some fields only make sense after another field has been filled in or enabled.
This pattern uses a serializable admin condition so the editor only sees the field when it is relevant. It is useful for optional discounts, feature toggles, and forms that should stay focused until a later choice unlocks more detail.
Example implementation
import { defineCollection, defineNumberField, defineTextField } from "@dyrected/core";
export const Orders = defineCollection({
slug: "orders",
fields: [
defineTextField({ name: "couponCode", label: "Coupon code" }),
defineNumberField({
name: "discountPercent",
label: "Discount percentage",
admin: { condition: "couponCode != null && couponCode != ''" },
}),
],
});
Read the full docs:
Update a dropdown from another field
Problem: the valid options for one field depend on what the editor picked in another field.
This pattern updates select options from sibling field data in the Admin UI. It works well for country-and-region choices, dependent selectors, or any form where the next choice should be constrained by the last one.
Example implementation
import { defineCollection, defineSelectField } from "@dyrected/core";
export const Locations = defineCollection({
slug: "locations",
fields: [
defineSelectField({
name: "country",
label: "Country",
required: true,
options: [
{ label: "Nigeria", value: "ng" },
{ label: "United States", value: "us" },
],
}),
defineSelectField({
name: "region",
label: "State or region",
required: true,
options: [],
admin: {
hooks: {
options: ({ siblingData }) => {
if (siblingData.country === "ng") return ["Lagos", "Abuja", "Oyo"];
if (siblingData.country === "us")
return ["California", "New York", "Texas"];
return [];
},
},
},
}),
],
});
Read the full docs:
Group SEO fields into an Admin tab
Problem: SEO metadata matters, but it clutters the main editing form when it sits beside every primary field.
This pattern uses defineTab to move secondary metadata into a dedicated Admin tab without changing the stored document shape. It is a good fit when editors need metadata fields regularly, but not at the expense of a focused main content form.
Example implementation
import { defineCollection, defineTab, defineTextField, defineTextareaField, defineUrlField } from "@dyrected/core";
export const Pages = defineCollection({
slug: "pages",
admin: { useAsTitle: "title" },
fields: [
defineTextField({ name: "title", label: "Title", required: true }),
defineTextField({ name: "slug", label: "Slug", required: true, unique: true }),
...defineTab({
label: "SEO",
fields: [
defineTextField({ name: "metaTitle", label: "Meta title" }),
defineTextareaField({ name: "metaDescription", label: "Meta description" }),
defineUrlField({ name: "canonicalUrl", label: "Canonical URL" }),
],
}),
],
});
Read the full docs: