
Grab your gear: The official Sanity swag store
Read Grab your gear: The official Sanity swag storeGreat question! You'll want to create a custom input component that replaces the default array string input with an autocomplete experience. Here's how to approach this:
You need to build a custom input component that uses the Sanity UI Autocomplete component and queries existing tags from your content. Here's the basic structure:
import {set, unset} from 'sanity'
import {Autocomplete, Card} from '@sanity/ui'
import {useCallback, useState, useEffect} from 'react'
import {useClient} from 'sanity'
function TagsAutocompleteInput(props) {
const {onChange, value = [], schemaType} = props
const [inputValue, setInputValue] = useState('')
const [existingTags, setExistingTags] = useState([])
const client = useClient({apiVersion: '2024-01-01'})
// Fetch existing tags from your content
useEffect(() => {
client.fetch(`array::unique(*[defined(tags)].tags[])`)
.then(setExistingTags)
}, [client])
// Filter tags based on input
const suggestions = existingTags.filter(tag =>
tag.toLowerCase().startsWith(inputValue.toLowerCase())
)
const handleSelect = useCallback((selectedTag) => {
// Add the selected tag to the array
const newValue = [...(value || []), selectedTag]
onChange(set(newValue))
setInputValue('') // Clear input for next tag
}, [value, onChange])
const handleRemoveTag = useCallback((index) => {
const newValue = value.filter((_, i) => i !== index)
onChange(newValue.length ? set(newValue) : unset())
}, [value, onChange])
return (
<Card>
{/* Display existing tags with remove buttons */}
<div>
{value?.map((tag, index) => (
<span key={index}>
{tag}
<button onClick={() => handleRemoveTag(index)}>×</button>
</span>
))}
</div>
{/* Autocomplete input */}
<Autocomplete
options={suggestions.map(tag => ({value: tag}))}
value={inputValue}
onChange={setInputValue}
onSelect={handleSelect}
placeholder="Type to search tags..."
/>
</Card>
)
}Modify your field definition to use the custom component:
{
name: 'tags',
title: 'Tags',
type: 'array',
of: [{type: 'string'}],
components: {
input: TagsAutocompleteInput
},
validation: Rule => Rule.required().min(2).error('At least 2 tags are required.')
}The GROQ query array::unique(*[defined(tags)].tags[]) flattens all tag arrays across your documents and returns unique values - perfect for your autocomplete suggestions!
value, onChange, and other props to integrate with Studio's form systemset() and unset() from the sanity package to patch changes back to the Content LakeFormField from sanity if you want to preserve the label, description, and validation UI around your custom inputCheck out the custom input component guide for more detailed examples and best practices. The guide walks through all the props available and how to properly handle patch events!
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.
Content operations
Content backend


The only platform powering content operations
By Industry


Tecovas strengthens their customer connections
Build and Share

Grab your gear: The official Sanity swag store
Read Grab your gear: The official Sanity swag store