Skip to content
Documentation
Documentation

Custom Resolvers

A UserResolver is a React hook: a function that calls other hooks and returns { name, email } or null.

type UserResolver = () => { name: string; email: string } | null

Return null when the user is not logged in. MUS falls back to { name: 'Anonymous', email: '' }.

Pass it directly to MusProvider:

import type { UserResolver } from '@datachef/mus'
<MusProvider config={{
projectName: 'My App',
slack: { ... },
userResolver: myResolver,
}}>
import type { UserResolver } from '@datachef/mus'
const myResolver: UserResolver = () => {
const { currentUser } = useMyAuthContext() // your own hook
if (!currentUser) return null
return {
name: currentUser.displayName,
email: currentUser.email,
}
}
import { useState, useEffect } from 'react'
import type { UserResolver } from '@datachef/mus'
const localStorageResolver: UserResolver = () => {
const [user, setUser] = useState<{ name: string; email: string } | null>(null)
useEffect(() => {
const raw = localStorage.getItem('current_user')
if (raw) {
try {
setUser(JSON.parse(raw))
} catch {}
}
}, [])
return user
}
import Cookies from 'js-cookie'
import type { UserResolver } from '@datachef/mus'
const cookieResolver: UserResolver = () => {
const name = Cookies.get('user_name')
const email = Cookies.get('user_email')
if (!email) return null
return { name: name ?? email, email }
}
import type { UserResolver } from '@datachef/mus'
const apiResolver: UserResolver = () => {
const { data } = useQuery({
queryKey: ['me'],
queryFn: () => fetch('/api/me').then(r => r.json()),
staleTime: 5 * 60 * 1000,
})
if (!data?.email) return null
return { name: data.name ?? data.email, email: data.email }
}

If you want to pass options (e.g. a config object), wrap the resolver in a factory function. This is the same pattern used by the built-in resolvers:

import type { UserResolver } from '@datachef/mus'
function myAuthResolver(options?: { fallbackName?: string }): UserResolver {
return () => {
const { session } = useMyAuth()
if (!session?.user) return null
return {
name: session.user.name ?? options?.fallbackName ?? session.user.email,
email: session.user.email,
}
}
}
// Usage:
<MusProvider config={{
...
userResolver: myAuthResolver({ fallbackName: 'Team Member' }),
}}>

A user resolver is a React hook, so the Rules of Hooks apply:

  • Do not call conditionally; the hook is always called inside MusProvider
  • Do not call inside loops or nested functions
  • You can call other hooks (useState, useEffect, useContext, etc.) freely