diff --git a/.changeset/hosted-navigation-native-views.md b/.changeset/hosted-navigation-native-views.md new file mode 100644 index 00000000000..12658382e7e --- /dev/null +++ b/.changeset/hosted-navigation-native-views.md @@ -0,0 +1,16 @@ +--- +'@clerk/expo': minor +--- + +Support pushing the native `UserProfileView` and `AuthView` onto your app's own navigation stack. + +New optional `onHostBack` prop shows a back button on the component's root screen and calls you when it is tapped. The component keeps its own navigation chrome, so screen titles, back buttons, swipe-back, and transitions inside the component stay native — hide your route's header and pop your route from the callback: + +```tsx + + router.back()} /> +``` + +The component never leaves the route on its own, so react to auth state for flow completion — either swap the content in place or pop the route. + +Existing usage is unaffected: the prop is optional, and the components render exactly as before without it. Requires the corresponding clerk-ios and clerk-android SDK releases. diff --git a/integration/templates/expo-native/App.tsx b/integration/templates/expo-native/App.tsx index 3d7bdf3efa4..967814e9f68 100644 --- a/integration/templates/expo-native/App.tsx +++ b/integration/templates/expo-native/App.tsx @@ -1,5 +1,5 @@ import { ClerkProvider, useAuth, useUser } from '@clerk/expo'; -import { AuthView, UserButton } from '@clerk/expo/native'; +import { AuthView, UserButton, UserProfileView } from '@clerk/expo/native'; import { tokenCache } from '@clerk/expo/token-cache'; import { useState } from 'react'; import { Button, Modal, StyleSheet, Text, View } from 'react-native'; @@ -18,6 +18,7 @@ function NativeBuildFixture() { const { isLoaded, isSignedIn, signOut } = useAuth({ treatPendingAsSignedOut: false }); const { user } = useUser(); const [isAuthOpen, setIsAuthOpen] = useState(false); + const [isProfileOpen, setIsProfileOpen] = useState(false); const [e2eStatus, setE2eStatus] = useState(null); return ( @@ -38,6 +39,13 @@ function NativeBuildFixture() { {!isSignedIn && } {isSignedIn && } {e2eStatus && {e2eStatus}} + {isSignedIn && ( +