fix(nextjs,clerk-js,types): Stop Clerk component flickering when used in App Router#2765
Merged
Conversation
🦋 Changeset detectedLatest commit: bc350f8 The changes in this PR will be included in the next version bump. This PR includes changesets to release 11 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
be8e82a to
a554f9e
Compare
panteliselef
approved these changes
Feb 9, 2024
a554f9e to
bc350f8
Compare
Contributor
|
💯 I enjoyed reading that PR description |
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.
A few things going on in this PR.
Navigation metadata
When using
router.pushfromnext/navigation(app router) the components in the current page will unmount before the navigation. In our case, if a component uses path-routing all internal navigations (for example/user>/user/securityuserouter.pushbut that means that the component will unmount and immediately mount again in the new URL.However, our components are client components and they can support client-side-only navigations. This type of navigation is usually called shallow navigation. App router apps can use the native
window.historyAPIs in order to trigger shallow navigations.We need to differentiate between internal navigations (navigations within the component) and external navigations (navigation outside the scope of the component) as we want to use shallow navigations for the former and normal
router.pushnavigations for the latter.To achieve that, the clerk-js router now sends a
metadataobject with each navigation that can be used by the consuming framework wrapper, enabling more fine-grained control over the type of navigation.Shallow navigations and nextjs
We want to be as little intrusive as possible, so when trigger shallow navigations, we need to make sure to preserve the default next router behavior. When calling the
window.historyAPIs, we should respect howwindowHistorySupportand let any changes to the URL update the next hooks as normal.next@14.1.0.nullas the first argument for WHS to workwindow.history.stateRefs:
See inline comments for more details.
usePathnameWithoutCatchAll
This hook let us automatically determine the path a component is mounted on, while taking into account that components can be mounted in catch-all routes, so simply using
usePathname()is not enough.For example, imagine we are using path-based routing and we have a UserProfile component mounted at
/user/[[...rest]]/page.tsx. The possible paths the component can use would be/userand/user/security, but the base path needs to be set as/useralways for our internal router to work.We're now saving the initial value in a
refso it never gets updated after the initial (browser) navigation to the page. For details on what this hook does, please refer to the inline comments.Description
Checklist
npm testruns as expected.npm run buildruns as expected.Type of change
Packages affected
@clerk/backend@clerk/chrome-extension@clerk/clerk-js@clerk/clerk-expo@clerk/fastifygatsby-plugin-clerk@clerk/localizations@clerk/nextjs@clerk/clerk-react@clerk/remix@clerk/clerk-sdk-node@clerk/shared@clerk/themes@clerk/typesbuild/tooling/chore