API reference

Common props for all extensionsAnchor

export interface ExtensionPropsBase {
context: {
project: {
id: string;
name: string;
mgmtApi: string;
mgmtToken: string;
environment: {
id: string;
name: string;
endpoint: string;
authToken: string;
// see `OpenDialog` in "additional types"
openDialog: OpenDialog;
// open the asset picker (see the Asset type in your Content Api)
openAssetPicker: () => Promise<null | (Asset & Record<string, unknown>)>;
// see `ShowToast` in "additional types"
showToast: ShowToast;
// Hygraph internal navigation (without page refresh)
historyReplace: (url: string | (currentUrl: string) => string) => Promise<void>;
historyPush: (url: string | (currentUrl: string) => string) => Promise<void>;
// Redirect the Hygraph app (full redirect to any URL)
redirectParent: (location: string | Location) => Promise<void>;

Field extensionAnchor

function useFieldExtension(): FieldExtensionProps;
export interface FieldExtensionProps extends ExtensionPropsBase {
// name of the field in the form (may differ from the field apiId, ie. for localized fields)
name: string;
// current locale on localized field
locale?: string;
// id of the current entry, null on a new entry.
entryId: string | null;
isTableCell: boolean;
value: any;
onBlur: <T extends HTMLElement = HTMLElement>(
event?: FocusEvent<T>,
) => Promise<void>;
onChange: <T extends HTMLElement = HTMLElement>(
event: ChangeEvent<T> | any,
) => Promise<void>;
onFocus: <T extends HTMLElement = HTMLElement>(
event?: FocusEvent<T>,
) => Promise<void>;
// @see https://final-form.org/docs/react-final-form/types/FieldRenderProps
meta: {
active: boolean;
error: any;
touched: boolean;
// access to the form state and other form fields
form: Form;
// details about the current field
field: {
id: string;
apiId: string;
description: string | null;
displayName: string;
isList: boolean;
isLocalized?: boolean;
isRequired?: boolean;
isUnique?: boolean;
// true when in version or stage comparison view
isPreview: boolean;
type: FieldExtensionType;
// details about the current model
model: Model;
// configuration of the extension.
extension: {
config: Record<string, any>;
fieldConfig: Record<string, any>;
tableConfig: Record<string, any>;
// whether the field is currently in fullscreen mode
isExpanded: boolean;
// set fullscreen mode
expand: (expand: boolean | ((isExpanded: boolean) => boolean)) => void;
function useFormSidebarExtension(): FormSidebarExtensionProps;
export interface FormSidebarExtensionProps extends ExtensionPropsBase {
extension: {
// global extension config
config: Record<string, any>;
// sidebar instance config
sidebarConfig: Record<string, any>;
form: Form;
model: Model;
allLocales: Locale[];
stages: Stage[];
entry?: {
id: string | null;
createdBy?: User;
updatedBy?: User;
createdAt?: string;
updatedAt?: string;

Additional typesAnchor


interface Model {
apiId: string;
apiIdPlural: string;
id: string;
description: string | null;
displayName: string;
isLocalized: boolean;


interface Form {
change: <Value = any>(name: string, value: Value) => Promise<void>;
changeBulk: (values: Record<string, any>) => Promise<void>;
// @see https://hygraph.com/docs/ui-extensions/react-sdk/state-getters#get-state
getState: <Values = Record<string, any>>() => Promise<FormState<Values>>;
// @see https://hygraph.com/docs/ui-extensions/react-sdk/state-getters#get-field-state
getFieldState: <Value = any>(fieldName: string) => Promise<FieldState<Value>>;
// @see https://hygraph.com/docs/ui-extensions/react-sdk/state-subscriptions#subscribe-to-field-state
subscribeToFieldState: <Value = any>(
name: string,
callback: (state: FieldState<Value>) => any,
subscription: FieldSubscription,
) => Promise<() => any>;
// @see https://hygraph.com/docs/ui-extensions/react-sdk/state-subscriptions#subscribe-to-form-state
subscribeToFormState: <Values = Record<string, any>>(
callback: Subscriber<FormState<Values>>,
subscription: FormSubscription,
) => Promise<() => any>;
// @see https://hygraph.com/docs/ui-extensions/field-extension/interacting-with-fields#set-fields-visibility
setFieldsVisibility: (
| VisibilityMap
| ((currentVisibilityMap: VisibilityMap) => VisibilityMap),
) => void;


interface Locale {
apiId: string;
id: string;
displayName: string;
isDefault: boolean;


interface Stage {
id: string;
apiId: string;
color: string;
colorPaletteId: keyof typeof StageColorPalette;
backgroundColor: string;
displayName: string;
description?: string | null | undefined;
isSystem: boolean;
position: number;
export const StageColorPalette = {
} as const;


interface User {
id: string;
kind: keyof typeof UserKind;
name: string;
picture: string | null;
isActive: boolean;
export const UserKind = {
} as const;


export type OpenDialog = <
DialogReturn = any,
DialogProps = Record<string, any>,
src: string,
props?: {
disableOverlayClick?: boolean;
maxWidth?: string;
ariaLabel?: string;
} & DialogProps,
) => Promise<DialogReturn | null>;


export type ShowToast = (options: ToastOptions) => Promise<Id>;
export type ToastOptions = {
title: string;
description?: string;
variantColor: keyof typeof ToastVariantColor;
id?: Id;
isClosable?: boolean;
position?: keyof typeof ToastPosition;
duration?: number;
type Id = number | string;
export const ToastVariantColor = {
success: 'success',
error: 'error',
warning: 'warning',
info: 'info',
primary: 'primary',
dark: 'dark',
publish: 'publish',
} as const;
export const ToastPosition = {
'top-right': 'top-right',
'top-center': 'top-center',
'top-left': 'top-left',
'bottom-right': 'bottom-right',
'bottom-center': 'bottom-center',
'bottom-left': 'bottom-left',
} as const;