Add hosted navigation SPI for framework integrations#519
Draft
mikepitre wants to merge 1 commit into
Draft
Conversation
Hosts that embed UserProfileView or AuthView inside their own navigation chrome (e.g. the Expo SDK) can now hide Clerk's navigation bars and drive the components' internal stacks. Setting the new @_spi(FrameworkIntegration) ClerkHostedNavigation value in the environment hides the bars; AuthView additionally reports stack depth changes and executes pop()/popToRoot(), since unlike UserProfileView its path cannot be owned externally. Behavior is unchanged when the environment value is absent.
Contributor
CI pausedCI does not run automatically on pull request updates. Before merging, manual CI must be run and pass for the latest commit. When this PR is ready for CI, the PR author or a repository maintainer can comment:
Or use the quick action below:
|
This was referenced Jul 9, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Expo (and any host that embeds our components in its own navigation) can't push
UserProfileViewonto its stack without getting two headers: the host's route header and Clerk's navigation bar. Hiding our bar alone isn't enough — the host's back button then pops the route while Clerk's internal stack still has screens on it. Context: Slack thread.What this adds
A
@_spi(FrameworkIntegration)environment value,clerkHostedNavigation. When a host sets it:UserProfileViewandAuthViewhide their navigation bars (iOS only). For the profile that's the whole story — hosts use the existing publicnavigationPath:initializer, own theNavigationPath, and derive depth / pop from it directly.AuthView's path is an internal[Destination]array that can't be owned externally, so it additionally reports depth changes throughonDepthChangeand executespop()/popToRoot()from the handle.No title reporting: the host owns its header and sets whatever title it wants.
When the environment value is absent (every non-SPI consumer), the components take the same code paths as before. No public API changes.
The add-account sheet inside the profile explicitly resets the environment value so modal auth keeps Clerk's own chrome.
Touch surface
HostedNavigation.swift(new, SPI-only): the handle, env entry, and bar-hiding modifierUserProfileView.swift: +6 lines (bar-hiding modifiers at the destination sites, sheet env reset)AuthView.swift: +20 lines (depth reporting + pop handler)Testing
make test-ui: 76 tests in 9 suites pass on iOS simulator, including the newHostedNavigationTestsswift build(macOS),make format-check,make lintall cleanThe consuming side is clerk/javascript#9121, which needs this in a release before its iOS pod compiles.
🤖 Generated with Claude Code