Rename "Add item" button in array field

2 replies
Last updated: Dec 14, 2021
Is there anyway to rename the “Add item” button used by the array field?
AI Update

Unfortunately, there is no built-in way to rename the "Add item" button for array fields in Sanity Studio. The button text is hardcoded in the default array input component.

However, you can achieve this by creating a custom input component that replaces the default array field interface. This requires some React development work, but gives you full control over the button text and other aspects of the array interface.

How to implement it

Here's the general approach:

1. Define your array field schema with a custom option:

{
  name: "categories",
  title: "Categories",
  type: "array",
  of: [{ type: "category" }],
  options: {
    buttonTitle: "Add new category" // Custom option for your button text
  },
  components: {
    input: CustomArrayInput // Your custom component
  }
}

2. Create a custom input component:

Your custom component needs to:

  • Accept the standard input component props
  • Read the buttonTitle from props.schemaType.options?.buttonTitle
  • Render the array interface with your custom button text
  • Handle adding items to the array using the onChange and value props

The custom component will need to implement the array item management logic (adding, removing, reordering items) or use the renderDefault prop to wrap the existing functionality while only customizing the button.

Why this requires a custom component

The Form Components API is designed to give developers complete control over form inputs when the default behavior doesn't fit their needs. While this means more implementation work for simple changes like button text, it provides the flexibility to customize any aspect of the array field interface - from button labels to item layouts to validation behavior.

Additional resources

The lack of a simple built-in option for this is a known limitation, but the custom component approach gives you the flexibility to customize not just the button text, but the entire array editing experience if needed.

Show original thread
2 replies
OK, thanks for letting me know
user M
It would cool if it was available to override in the options.
Haven’t really done this since native conditional fields were released, but you used to be able to overwrite the default fields via the parts system.
You basically add sth. like

{
    "implements": "part:@sanity/form-builder/input/array/functions",
    "path": "./utils/conditionalFields/"
}
to
sanity.json
. (Modify “path” accordingly to point to your custom implementation).
Here’s a rough sample from a while back, where I modified the button to read “Choose” instead of “Add” when there was a certain validation method on the native array field:

// Simple implementation of <https://github.com/sanity-io/sanity/blob/21af6baffe88d57db32d0a05e048ef7d3d671523/packages/%40sanity/form-builder/src/inputs/ArrayInput/ArrayFunctions.tsx>

import React from "react";
import DropDownButton from "part:@sanity/components/buttons/dropdown";
import Button from "part:@sanity/components/buttons/default";
import ButtonGrid from "part:@sanity/components/buttons/button-grid";

export default class ArrayFunctions extends React.Component {
  handleDropDownAction = (menuItem) => {
    this.handleInsertItem(menuItem.type);
  };
  handleAddBtnClick = () => {
    this.handleInsertItem(this.props.type.of[0]);
  };
  handleInsertItem = (type) => {
    const { onCreateValue, onAppendItem } = this.props;
    const item = onCreateValue(type);
    onAppendItem(item);
  };
  renderSelectType(isList) {
    const items = this.props.type.of.map((memberDef) => ({
      title: memberDef.title || memberDef.type.name,
      type: memberDef,
    }));
    return (
      <DropDownButton
        inverted
        items={items}
        onAction={this.handleDropDownAction}
      >
        {isList ? "Add" : "Choose"}
      </DropDownButton>
    );
  }
  render() {
    const { type, readOnly, children, value } = this.props;

    const maxLength =
      type.validation[0]._rules.find((rule) => rule.flag === "max") || false;

    const isList = maxLength && maxLength.constraint === 1 ? false : true;

    if (maxLength && value && value.length >= maxLength.constraint) {
      return null;
    }

    if (readOnly) {
      return null;
    }

    if (type?.options?.generated) {
      return null;
    }

    return (
      <div>
        <ButtonGrid align="start">
          {type.of.length === 1 ? (
            <Button inverted onClick={this.handleAddBtnClick}>
              Add
            </Button>
          ) : (
            this.renderSelectType(isList)
          )}

          {children || null}
        </ButtonGrid>
      </div>
    );
  }
}
Haven’t tested this with a newer studio installation, so I can’t vouch that this will work with the new Sanity UI. But maybe it will put you on the right track
✌️

Sanity – Build the way you think, not the way your CMS thinks

Sanity is the developer-first content operating system that gives you complete control. Schema-as-code, GROQ queries, and real-time APIs mean no more workarounds or waiting for deployments. Free to start, scale as you grow.

Was this answer helpful?