Skip to content

Use useGoBack for course back navigation instead of hardcoded HOME#14403

Open
nucleogenesis wants to merge 3 commits intolearningequality:release-v0.19.xfrom
nucleogenesis:14222--bugfix--back-arrow-dont-go-home
Open

Use useGoBack for course back navigation instead of hardcoded HOME#14403
nucleogenesis wants to merge 3 commits intolearningequality:release-v0.19.xfrom
nucleogenesis:14222--bugfix--back-arrow-dont-go-home

Conversation

@nucleogenesis
Copy link
Member

Summary

CourseWelcomePage hardcoded its back arrow to always navigate to the Home page,
regardless of where the user came from. This fix adopts the existing
useGoBack / usePreviousRoute pattern (used in Facility and Coach plugins)
for course navigation:

  1. New CourseRootPage wrapper component calls usePreviousRoute() and renders <router-view />
  2. Course routes are nested as children of CourseRootPage, enabling previous route tracking
  3. CourseWelcomePage uses useGoBack({ fallbackRoute: HOME }) instead of a hardcoded HOME link

This follows the same pattern as UsersRootPage (Facility), QuizResourceSelection and
LessonResourceSelection (Coach).

References

Fixes #14222

Review guidance

QA guidance

I took these steps to confirm the fix

Setup prerequisites:

  • A facility with at least one class
  • A learner enrolled in that class
  • At least one course assigned to that class
  • Content channels imported so the course has content

Test path 1: From Classes page

  1. Sign in as a learner with assigned courses
  2. Navigate to Classes > [Your Class]
  3. Click a course card
  4. On the CourseWelcomePage, click the back arrow
  5. Expected: returns to the class page, not Home

Test path 2: From Home page

  1. Sign in as the same learner
  2. From the Home page, click a course card
  3. On the CourseWelcomePage, click the back arrow
  4. Expected: returns to Home

Test path 3: Regression tests on 'no classes guard'

This is to ensure that we still correctly redirect people who are not in the class given in their URL

  1. 'Signin' as a user by way of the "Explore without account" in an incognito window
  2. Copy the URL to a course or class page from a regular browser and try to access it as the anonymous user in incognito
  3. See that the user is simply redirected to the Library (this is expected as they are not in any class)

Note that the other case I tested was for a logged-in user trying to go to a class URL for a class they're not in and it resulted in a 404 Error which is right because to the user not in the class, the class doesn't exist.

Code Reviewer notes (from Claude)

  • CourseRootPage is a thin wrapper (~15 lines) following an established pattern — compare with
    UsersRootPage in Facility or QuizResourceSelection in Coach
  • Course routes were restructured from flat to nested under CourseRootPage, with the
    noClassesGuard handler consolidated on the parent route. URL paths are unchanged.
  • We initially explored the useContentLink query-param approach (used by TopicsPage for deep
    content browsing), but useGoBack is a better fit here — CourseWelcomePage is simple
    "go back one level" navigation, not deep content browsing
  • The useGoBack pattern relies on onBeforeRouteUpdate firing on CourseRootPage when
    CourseUnitView does router.replace to CourseWelcomePage (both are child routes).
    This sets previousRoute, enabling router.back() to return to the correct origin page.
    When no previous route exists (direct link/refresh), it falls back to HOME.

AI usage

I used Claude Code to investigate the root cause, trace the navigation chain, and explore
two approaches: query-param threading via useContentLink and the useGoBack /
usePreviousRoute pattern. After testing both, we chose useGoBack as the better fit
for this use case. I reviewed the generated code and verified it follows the same pattern
used elsewhere in the codebase.

nucleogenesis and others added 2 commits March 18, 2026 10:45
CourseWelcomePage hardcoded its back arrow to always navigate to HOME,
ignoring where the user came from. Fix by:

- Adding CourseRootPage as a route-level wrapper that calls
  usePreviousRoute(), providing previous route tracking for all
  course child routes
- Nesting course routes as children of CourseRootPage
- Replacing the hardcoded homePageLink in CourseWelcomePage with
  useGoBack(), falling back to HOME when no previous route exists

This follows the same pattern used in Facility (UsersRootPage) and
Coach (QuizResourceSelection, LessonResourceSelection) plugins.

Fixes learningequality#14222

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The Kolibri router's handler system only extracts handlers from
top-level routes, not children. Since course routes are now nested
under CourseRootPage, the noClassesGuard handler was not firing.
Switch to Vue Router's native beforeEnter guard on the parent route,
which fires for all child route navigations.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@github-actions github-actions bot added APP: Learn Re: Learn App (content, quizzes, lessons, etc.) DEV: frontend SIZE: medium labels Mar 18, 2026
Copy link
Contributor

@rtibblesbot rtibblesbot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clean bugfix that correctly adopts the established usePreviousRoute/useGoBack pattern for course back navigation.

CI: Python tests passing. Frontend tests, linting, and WHL build still pending — verify before merge.

  • suggestion (1): Bare /course path is now routable — see inline comment on classesRoutes.js:90
  • praise (2): See inline comments

@rtibblesbot's comments are generated by an LLM, and should be evaluated accordingly

How was this generated?

Reviewed the pull request diff checking for:

  • Correctness: bugs, edge cases, undocumented behavior, resource leaks, hardcoded values
  • Design: unnecessary complexity, naming, readability, comment accuracy, redundant state
  • Architecture: duplicated concerns, minimal interfaces, composition over inheritance
  • Testing: behavior-based assertions, mocks only at hard boundaries, accurate coverage
  • Completeness: missing dependencies, unupdated usages, i18n, accessibility, security
  • Principles: DRY (same reason to change), SRP, Rule of Three (no premature abstraction)
  • Checked CI status and linked issue acceptance criteria
  • For UI changes: inspected screenshots for layout, visual completeness, and consistency

name: PageNames.COURSE_WELCOME,
path: '/course/:courseSessionId([a-f0-9]{32})/welcome',
component: CourseWelcomePage,
path: '/course',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: The parent route path: '/course' is now a routable URL, but it has no name, no redirect, and no default child. If a user navigates to /course directly, they'll see CourseRootPage rendering an empty <router-view /> — a blank page.

No UI link currently points to bare /course, so this is unlikely to be hit in practice. But a defensive redirect (e.g., to HOME) would prevent the blank page if someone bookmarks or manually enters the URL. Low priority — just something to be aware of.

export default {
name: 'CourseRootPage',
setup() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

praise: Minimal wrapper following the exact same pattern as UsersRootPage in Facility — just usePreviousRoute() + <router-view />. Good restraint keeping it thin.

:appBarBgColor="$themeTokens.surface"
:appBarHoverBgColor="$themePalette.grey.v_100"
:appearanceOverrides="{ backgroundColor: $themeTokens.surface }"
@navIconClick="goBack"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

praise: Good switch from :route to @navIconClick. ImmersiveToolbar renders a static <router-link> when route is provided, but useGoBack needs runtime logic to choose between router.back() and the fallback — so the event handler is the correct mechanism.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copy link
Contributor

@rtibblesbot rtibblesbot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clean follow-up addressing the prior suggestion.

Delta from prior review

  • RESOLVED: bare /course blank page — redirect: '/' added (d5be2cb)
  • New: beforeEnter consolidation moves the noClassesGuard to the parent route, eliminating six identical handler wrappers. Good simplification.

CI: build assets still in progress — verify before merge.

No new findings.


@rtibblesbot's comments are generated by an LLM, and should be evaluated accordingly

How was this generated?

Compared the current PR state against findings from a prior review:

  • Retrieved prior bot reviews deterministically via the GitHub API
  • Classified each prior finding as RESOLVED, UNADDRESSED, ACKNOWLEDGED, or CONTESTED
  • Only raised NEW findings for newly introduced code
  • Reviewed the pull request diff checking for correctness, design, architecture, testing, completeness, and adherence to DRY/SRP principles
  • Checked CI status and linked issue acceptance criteria

return;
}
next();
},
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

praise: Clean consolidation — six identical handler wrappers replaced with a single beforeEnter on the parent. The guard only needs to check class membership on entry to the /course subtree, not on every sibling navigation, so this is both simpler and semantically correct.

@github-actions
Copy link
Contributor

github-actions bot commented Mar 18, 2026

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

APP: Learn Re: Learn App (content, quizzes, lessons, etc.) DEV: frontend SIZE: medium

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Courses - Clicking the back arrow always brings the user back to the 'Home' page

3 participants