Skip to content

fix(runtime-utils): ensure RouterLink stub works with pages: false#1687

Open
yamachi4416 wants to merge 1 commit intonuxt:mainfrom
yamachi4416:router-link-stub-without-page
Open

fix(runtime-utils): ensure RouterLink stub works with pages: false#1687
yamachi4416 wants to merge 1 commit intonuxt:mainfrom
yamachi4416:router-link-stub-without-page

Conversation

@yamachi4416
Copy link
Copy Markdown
Member

@yamachi4416 yamachi4416 commented May 6, 2026

🔗 Linked issue

resolves #1685

📚 Description

fallback RouterLink stub to previous behavior when pages is false

@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new Bot commented May 6, 2026

Open in StackBlitz

npm i https://pkg.pr.new/@nuxt/test-utils@1687
npm i https://pkg.pr.new/vitest-environment-nuxt@1687

commit: a2ba551

@yamachi4416 yamachi4416 marked this pull request as ready for review May 6, 2026 01:24
@yamachi4416 yamachi4416 requested a review from danielroe as a code owner May 6, 2026 01:24
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 6, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: ff21c0ff-7025-4699-8e68-767f6ee0688e

📥 Commits

Reviewing files that changed from the base of the PR and between a6420cd and a2ba551.

📒 Files selected for processing (11)
  • examples/app-vitest-workspace/app2/nuxt.config.ts
  • examples/app-vitest-workspace/app2/test/nuxt/components.spec.ts
  • examples/app-vitest-workspace/app4/app/pages/index.vue
  • examples/app-vitest-workspace/app4/nuxt.config.ts
  • examples/app-vitest-workspace/app4/test/nuxt/pages-off/nuxt-link.spec.ts
  • examples/app-vitest-workspace/app4/test/nuxt/pages-on/nuxt-link.spec.ts
  • examples/app-vitest-workspace/app4/tsconfig.json
  • examples/app-vitest-workspace/app4/vitest.pages-off.config.ts
  • examples/app-vitest-workspace/app4/vitest.pages-on.config.ts
  • examples/app-vitest-workspace/package.json
  • src/runtime-utils/components/RouterLink.ts

📝 Walkthrough

Walkthrough

This PR introduces a new app4 configuration to the Vitest workspace with separate test scenarios for pages-on and pages-off modes. The primary logic change implements a dynamic fallback mechanism in RouterLink to handle cases where useLink is unavailable in test environments, addressing a regression in RouterLink stub behavior. Additional test suites for NuxtLink and Breadcrumb/Header components are added to app2 and app4. Configuration files (tsconfig, Vitest configs) and package.json scripts are updated to support the new app4 setup and per-app dev:prepare tasks.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

The RouterLink.ts change introduces conditional logic with a helper function and fallback rendering path that requires careful analysis (~15 minutes), while the remaining additions—test files, configuration files, and npm scripts—follow consistent patterns with relatively straightforward implementations (~10 minutes).

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the primary fix: ensuring RouterLink stub works when pages is false, which directly addresses the main objective.
Description check ✅ Passed The description references the linked issue (#1685) and explains the core objective of restoring fallback behavior for RouterLink stub when pages is false.
Linked Issues check ✅ Passed The PR fully addresses issue #1685 by implementing fallback behavior in RouterLink stub to handle cases where the router is not injected, preventing TypeError when useLink cannot access routerKey.
Out of Scope Changes check ✅ Passed All changes are directly related to fixing RouterLink stub behavior without router injection. Code changes, test files, and configuration updates in app4 and app2 all support the core objective.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
src/runtime-utils/components/RouterLink.ts (1)

29-48: 💤 Low value

Hoist useRouter() out of the render function.

useRouter() (and the underlying useNuxtApp()) are composables intended to run during setup, where the current instance and injection context are guaranteed. Invoking them on every render inside the returned function is both wasteful (re-resolves the Nuxt app/router each tick) and inconsistent with the useLink branch below, which captures link once in setup. The router instance is stable for the component's lifetime, so resolve it once.

♻️ Proposed refactor
     if (!useLink) {
       const navigate = () => {}
+      const router = useRouter()
       return () => {
-        const route = useRouter().resolve(props.to)
+        const route = router.resolve(props.to)

         return props.custom
           ? slots.default?.({ href: route.href, navigate, route })
           : h(
               'a',
               {
                 href: route.href,
                 onClick: (e: MouseEvent) => {
                   e.preventDefault()
                   return navigate()
                 },
               },
               slots,
             )
       }
     }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/runtime-utils/components/RouterLink.ts` around lines 29 - 48, Hoist the
call to useRouter() out of the inner render so the router instance is captured
once during setup (similar to the useLink branch): call const router =
useRouter() in the outer scope, then use router.resolve(props.to) inside the
returned render function (or compute a reactive/readonly route if needed)
instead of calling useRouter() on every render; update references to route.href,
navigate, props.to and keep the empty navigate function and custom/anchor render
logic unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@src/runtime-utils/components/RouterLink.ts`:
- Around line 29-48: Hoist the call to useRouter() out of the inner render so
the router instance is captured once during setup (similar to the useLink
branch): call const router = useRouter() in the outer scope, then use
router.resolve(props.to) inside the returned render function (or compute a
reactive/readonly route if needed) instead of calling useRouter() on every
render; update references to route.href, navigate, props.to and keep the empty
navigate function and custom/anchor render logic unchanged.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 6cf3bad4-a06c-4bbc-969b-f1a3ef19791c

📥 Commits

Reviewing files that changed from the base of the PR and between c193a99 and a6420cd.

📒 Files selected for processing (6)
  • examples/app-vitest-workspace/app2/nuxt.config.ts
  • examples/app-vitest-workspace/app2/test/nuxt/components.spec.ts
  • examples/nuxt-ui/components/SomeBreadcrumb.vue
  • examples/nuxt-ui/pages/index.vue
  • examples/nuxt-ui/tests/mount.spec.ts
  • src/runtime-utils/components/RouterLink.ts

@yamachi4416 yamachi4416 force-pushed the router-link-stub-without-page branch from a6420cd to b203962 Compare May 6, 2026 01:37
@yamachi4416
Copy link
Copy Markdown
Member Author

I’m going to update the branch and add a few more tests.

@yamachi4416 yamachi4416 marked this pull request as draft May 6, 2026 13:14
@yamachi4416 yamachi4416 force-pushed the router-link-stub-without-page branch from b203962 to a2ba551 Compare May 6, 2026 14:49
@yamachi4416
Copy link
Copy Markdown
Member Author

Thank you for the review.
Updated the branch, reorganized the tests, and added test case for RouterLink stubs with autoImport: false.

@yamachi4416 yamachi4416 marked this pull request as ready for review May 6, 2026 14:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

RouterLink stub in mountSuspended throws Cannot read properties of undefined (reading 'resolve') since 4.0.3

2 participants