Connect external API (Centra) to Sanity for product selection dropdown
Great question! Building custom input components that fetch data from external APIs (like Centra) is a common need for e-commerce projects, and Sanity makes this pretty straightforward.
For your use case where you want to select Centra products directly in Sanity Studio without manually copying IDs, you'll want to create a custom input component that fetches products from the Centra API and displays them in a searchable dropdown.
Basic Approach
Here's how to set this up:
- Create a custom input component that uses Sanity UI's Autocomplete component - this gives you a searchable dropdown that matches Sanity's design system
- Fetch data from Centra's API inside your component (using React hooks like
useEffect) - Store the product ID (or relevant data) in your Sanity document
Implementation Example
First, define your field in your schema using defineField:
defineField({
name: 'centraProduct',
title: 'Product',
type: 'object',
fields: [
{ name: 'productId', type: 'string' },
{ name: 'productName', type: 'string' },
// Store whatever Centra data you need
],
components: {
input: CentraProductInput
}
})Then create your custom input component using @sanity/ui components:
import { Autocomplete } from '@sanity/ui'
import { set, unset } from 'sanity'
import { useState, useEffect } from 'react'
function CentraProductInput(props) {
const { value, onChange } = props
const [products, setProducts] = useState([])
const [loading, setLoading] = useState(false)
// Fetch products from Centra API
useEffect(() => {
async function fetchProducts() {
setLoading(true)
try {
const response = await fetch('YOUR_CENTRA_API_ENDPOINT', {
headers: {
'Authorization': `Bearer ${process.env.SANITY_STUDIO_CENTRA_TOKEN}`
}
})
const data = await response.json()
setProducts(data.products) // Adjust based on Centra's response structure
} catch (error) {
console.error('Error fetching products:', error)
} finally {
setLoading(false)
}
}
fetchProducts()
}, [])
const handleSelect = (productId) => {
const selectedProduct = products.find(p => p.id === productId)
onChange(
selectedProduct
? set({ productId: selectedProduct.id, productName: selectedProduct.name })
: unset()
)
}
return (
<Autocomplete
options={products.map(p => ({ value: p.id, payload: p.name }))}
value={value?.productId}
onChange={handleSelect}
loading={loading}
placeholder="Search for a product..."
renderOption={(option) => option.payload}
/>
)
}Key Points
Sanity UI Components: Yes! Sanity provides @sanity/ui which includes Autocomplete, Select, and other components that match Studio's design. You should definitely use these for consistency.
Data Patching: Use the set() and unset() functions from the sanity package to update your field values properly - this is how custom input components communicate changes back to the Content Lake.
Environment Variables: Store your Centra API credentials in environment variables (prefixed with SANITY_STUDIO_ to make them available in the Studio).
Caching Considerations: For better performance, you might want to implement debouncing for search queries or cache the product list if it doesn't change frequently.
Alternative Approach
There's also a community plugin approach with packages like @sanity/sanity-plugin-async-list that can help with async data fetching, though building your own gives you more control over the UX and integration with Centra's specific API structure.
For your "BEST SELLING" content block, you could even create an array field where editors can select multiple Centra products, giving them a great authoring experience without ever leaving Sanity Studio. The custom input component documentation has more details on handling complex field types and the component props you'll receive.
Show original thread2 replies
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.