<UserProfileView /> component
The <UserProfileView /> component renders a fully native profile management interface using SwiftUI on iOS and Jetpack Compose on Android. It allows users to manage:
- Profile details
- Email addresses
- Phone numbers
- Multi-factor authentication (MFA)
- Passkeys
- Connected accounts
- Active sessions
Usage
There are three ways to render the profile view in an Expo app:
- Native modal (recommended): Use the
useUserProfileModal()hook to present the profile view as a native modal (SwiftUI/Jetpack Compose). This uses a nativeXbutton for dismissal. - React Native Modal: Wrap the inline
<UserProfileView />in a React Native<Modal>component. You must provide your own close button to dismiss the modal. - Inline: Render
<UserProfileView />directly in your layout without a modal.
If you need to react to sign-out, use useAuth() inside a useEffect.
Use the following tabs to select your preferred approach.
The useUserProfileModal() hook provides an imperative presentUserProfile() function that opens the native profile modal directly from a button press. No component is needed.
import { useUserProfileModal } from '@clerk/expo'
import { Text, TouchableOpacity, View } from 'react-native'
export default function HomeScreen() {
const { presentUserProfile } = useUserProfileModal()
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<TouchableOpacity onPress={presentUserProfile}>
<Text>Manage Profile</Text>
</TouchableOpacity>
</View>
)
}- Name
presentUserProfile- Type
() => Promise<void>- Description
Opens the native profile modal. The promise resolves when the modal is dismissed. If the user signs out from within the modal, the JS SDK session is automatically cleared.
- Name
isAvailable- Type
boolean- Description
Whether the native module supports presenting the profile modal. Returns
falseon web or when the@clerk/expoplugin is not installed.
- Name
sessions- Type
Ref<Session>- Description
A list of sessions that have been registered on the client device.
When rendering inside a React Native <Modal>, ensure isDismissable is set to false (the default) and provide your own close button to dismiss the modal.
import { useState } from 'react'
import { View, Text, TouchableOpacity, Modal, StyleSheet } from 'react-native'
import { UserProfileView } from '@clerk/expo/native'
export default function HomeScreen() {
const [showProfile, setShowProfile] = useState(false)
return (
<View style={{ flex: 1 }}>
<TouchableOpacity onPress={() => setShowProfile(true)}>
<Text>Open Profile</Text>
</TouchableOpacity>
<Modal visible={showProfile} animationType="slide">
<View style={styles.modalHeader}>
<TouchableOpacity onPress={() => setShowProfile(false)}>
<Text style={styles.closeButton}>Close</Text>
</TouchableOpacity>
</View>
<UserProfileView />
</Modal>
</View>
)
}
const styles = StyleSheet.create({
modalHeader: {
paddingTop: 60,
paddingHorizontal: 20,
paddingBottom: 8,
alignItems: 'flex-end',
backgroundColor: '#fff',
},
closeButton: {
color: '#007AFF',
fontSize: 17,
fontWeight: '600',
},
})You can render <UserProfileView /> directly in your layout without a modal. This is useful for dedicated profile screens.
import { UserProfileView } from '@clerk/expo/native'
import { useAuth } from '@clerk/expo'
import { useRouter } from 'expo-router'
import { useEffect } from 'react'
export default function ProfileScreen() {
const { isSignedIn } = useAuth({ treatPendingAsSignedOut: false })
const router = useRouter()
useEffect(() => {
if (!isSignedIn) {
router.replace('/(auth)/sign-in')
}
}, [isSignedIn])
return <UserProfileView style={{ flex: 1 }} />
}- Name
isDismissable- Type
boolean- Description
Whether the inline profile view can be dismissed by the user. When
true, a dismiss button appears. This does not present a modal — to present a native modal, use theuseUserProfileModal()hook instead. Defaults tofalse.
- Name
style- Type
StyleProp<ViewStyle>- Description
Style applied to the container view.
Feedback
Last updated on