How to pull Supabase user data into Sanity Studio?
Great question! You're right that this is similar to how people integrate Firebase with Sanity Studio. To display your Supabase users in Sanity Studio, you'll want to create a custom tool. Here's how to approach this:
Creating a Custom Tool for Supabase Users
A custom Studio tool is perfect for this use case. Tools are top-level views in Sanity Studio that appear in the menu bar, and they're essentially React components that can fetch and display external data.
Basic Setup
Here's a starter example that shows how to structure your custom tool:
// supabaseUsersTool.tsx
import { defineConfig } from 'sanity'
import { Card, Container, Stack, Heading } from '@sanity/ui'
import { UsersIcon } from '@sanity/icons'
import { createClient } from '@supabase/supabase-js'
const supabaseUsersTool = () => {
return {
title: 'Supabase Users',
name: 'supabase-users',
icon: UsersIcon,
component: () => {
const [users, setUsers] = useState([])
useEffect(() => {
// Initialize your Supabase client
const supabase = createClient(
process.env.SANITY_STUDIO_SUPABASE_URL,
process.env.SANITY_STUDIO_SUPABASE_ANON_KEY
)
// Fetch users using Supabase admin API
// Note: You'll need proper auth setup for this
async function fetchUsers() {
const { data, error } = await supabase.auth.admin.listUsers()
if (data) setUsers(data.users)
}
fetchUsers()
}, [])
return (
<Container padding={4}>
<Stack space={4}>
<Heading>Supabase Users</Heading>
{/* Render your users here */}
</Stack>
</Container>
)
}
}
}
// In your sanity.config.ts
export default defineConfig({
// ...other config
tools: [supabaseUsersTool()],
})Important Considerations
Authentication: For
listUsers()to work, you'll need your Supabase service role key (not the anon key). Store this securely in environment variables. Check the Supabase admin API docs for details.Environment Variables: Use Sanity Studio environment variables prefixed with
SANITY_STUDIO_to access them in your tool.Use Sanity UI: Like you saw with Shopify/Stripe integrations, leverage @sanity/ui components for consistent styling (Card, Stack, Table, etc.).
Plugin Option: If you want to reuse this across projects, you can package it as a plugin using
definePlugininstead of directly in your config.
Example with Better UI
import { Card, Stack, Text, Flex, Avatar } from '@sanity/ui'
// In your component:
return (
<Container padding={4}>
<Stack space={3}>
{users.map(user => (
<Card key={user.id} padding={3} border>
<Flex gap={3} align="center">
<Avatar size={1} />
<Stack space={2}>
<Text weight="semibold">{user.email}</Text>
<Text size={1} muted>
Created: {new Date(user.created_at).toLocaleDateString()}
</Text>
</Stack>
</Flex>
</Card>
))}
</Stack>
</Container>
)The key difference from Shopify/Stripe is that those have pre-built plugins, but the underlying concept is the same—you're creating a custom view that fetches external data and displays it using React and Sanity UI components.
If you want to make this read/write (not just viewing), you could also add buttons that trigger Supabase mutations, though be mindful of permissions and security when doing so from the Studio.
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.