feat: SPA navigation for post-auth redirects#1647
Open
arbrandes wants to merge 4 commits intoopenedx:frontend-basefrom
Open
feat: SPA navigation for post-auth redirects#1647arbrandes wants to merge 4 commits intoopenedx:frontend-basefrom
arbrandes wants to merge 4 commits intoopenedx:frontend-basefrom
Conversation
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## frontend-base #1647 +/- ##
================================================
Coverage ? 92.12%
================================================
Files ? 92
Lines ? 2045
Branches ? 585
================================================
Hits ? 1884
Misses ? 158
Partials ? 3 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
jesusbalderramawgu
approved these changes
Mar 13, 2026
Contributor
jesusbalderramawgu
left a comment
There was a problem hiding this comment.
thank you, this is a great catch
b04929e to
4ff413c
Compare
When a user navigates to a protected SPA route while logged out, the authenticatedLoader redirects to /authn/login?next=%2Fsome-path. Previously, this relative next param was sent to the LMS backend, which resolved it against itself and returned an absolute LMS URL — causing a full page navigation away from the SPA shell. Now, when next starts with /, it is stripped from the API payload and handled locally: after login/registration succeeds, fetchAuthenticatedUser refreshes the auth cache so authenticatedLoader allows the target route, RedirectLogistration uses <Navigate> for SPA navigation, and hydrateAuthenticatedUser runs in the background to populate the full user profile (avatar, etc.) in the header. Also applies the same relative-path SPA navigation pattern to ProgressiveProfilingPageModal and replaces the hardcoded LMS dashboard fallback in the registration API with getUrlByRouteRole for consistency. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Routes are nested by default, but navigation constants used absolute paths like '/login', causing navigate() and <Navigate> to go to /login instead of /authn/login. Replace path constants in navigation calls with getUrlByRouteRole() where possible, which resolves the URL for a given route role from the route config. Path constants are still generally useful, but are now all relative (and camelCase). Centralize route roles, path segments, and the dashboard role in src/constants.ts. Last but not least, prefer SPA navigation (<Navigate>, useNavigate) over window.location.href where the target URL may be internal. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When the backend returns the LMS dashboard URL as redirect_url after login or registration, replace it with getUrlByRouteRole(dashboardRole) so that RedirectLogistration can use <Navigate> for SPA navigation instead of a full page reload. Also hydrate the authenticated user before SPA navigation so the shell header displays the user's name. This applies the same fetchAuthenticatedUser/hydrateAuthenticatedUser pattern already used for the localNextPath flow to any redirect URL that starts with '/'. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
ba527eb to
b611c4d
Compare
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.
Description
When a user navigates to a protected SPA route while logged out,
authenticatedLoaderredirects to/authn/login?next=/some-path. Previously, this relativenextparam was forwarded to the LMS backend, which resolved it against itself and returned an absolute LMS URL, causing a full page navigation away from the SPA shell. Now the relative path is stripped from the API payload and handled locally after login/registration succeeds, using<Navigate>for seamless SPA navigation.This also revealed that the authn app's navigation was still using absolute path constants like
'/login', which don't resolve correctly under the/authnroute prefix. All navigation now goes throughgetUrlByRouteRole()to resolve URLs from the route config, and components likeUnAuthOnlyRoute,ChangePasswordPrompt, andProgressiveProfilinguse SPA navigation instead ofwindow.location.hrefwhen the target is internal.Finally, when the LMS backend returns its own dashboard URL as
redirect_urlafter login or registration, it is normalized to the role-based dashboard URL via a sharednormalizeRedirectUrl()utility, soRedirectLogistrationcan navigate without a full page reload.Depends on openedx/frontend-base#183, and indirectly on openedx/frontend-app-learner-dashboard#806.
Note to reviewer
Start the review with
src/constants.tsandsrc/routes.tsx. It makes the rest easier to understand.Testing
Set up a complete frontend-template-site with all the latest changes in frontend-base, authn, and learner-dashboard. After that, make sure login and registration still work, including by manually navigating to
/learner-dashboardwithout having logged in first (if you installed openedx/frontend-app-learner-dashboard#806).LLM usage notice
Built with assistance from Claude models (mostly Opus 4.6).