Connect external API (Centra) to Sanity for product selection dropdown

2 replies
Last updated: Nov 28, 2023
Hello, awesome people!
I am starting a big ecom project for a famous sports brand. I have a question, we will be using Centra as our ecom engine, and would like to be able to show products and collections as part of Sanity.

Let's say for example I have a "BEST SELLING" content block. I would like to be able to select the product inside Sanity, and not have to go to Centra, get the product ID, and then copy paste that into Sanity.

If you know what I mean?

What is the best way to connect to an external API and show a dropdown component or something in Sanity? (Maybe Sanity even offers their component library for dropdowns I can reuse?)

Thank you so much!
AI Update

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:

  1. Create a custom input component that uses Sanity UI's Autocomplete component - this gives you a searchable dropdown that matches Sanity's design system
  2. Fetch data from Centra's API inside your component (using React hooks like useEffect)
  3. 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 thread
2 replies
Here’s a simple custom component that can do what you’re looking for!
user M
Thank you kindly! 🙂

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?