Skip to content

feat(nuxt): upgrade to vue-router v5#34181

Merged
danielroe merged 7 commits intomainfrom
refactor/upgrade-vue-router-5
Feb 24, 2026
Merged

feat(nuxt): upgrade to vue-router v5#34181
danielroe merged 7 commits intomainfrom
refactor/upgrade-vue-router-5

Conversation

@posva
Copy link
Copy Markdown
Member

@posva posva commented Jan 26, 2026

📚 Description

This is a WIP PR to upgrade to vue-router 5 and remove the dependency on unplugin-vue-router.
Should be merged after vue-router 5 is released (without the beta tag)

@posva posva requested a review from danielroe as a code owner January 26, 2026 14:37
@bolt-new-by-stackblitz
Copy link
Copy Markdown

Review PR in StackBlitz Codeflow Run & review this pull request in StackBlitz Codeflow.

@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new bot commented Jan 26, 2026

Open in StackBlitz

@nuxt/kit

npm i https://pkg.pr.new/@nuxt/kit@34181

@nuxt/nitro-server

npm i https://pkg.pr.new/@nuxt/nitro-server@34181

nuxt

npm i https://pkg.pr.new/nuxt@34181

@nuxt/rspack-builder

npm i https://pkg.pr.new/@nuxt/rspack-builder@34181

@nuxt/schema

npm i https://pkg.pr.new/@nuxt/schema@34181

@nuxt/vite-builder

npm i https://pkg.pr.new/@nuxt/vite-builder@34181

@nuxt/webpack-builder

npm i https://pkg.pr.new/@nuxt/webpack-builder@34181

commit: 940857d

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Jan 26, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Imports and type imports for router utilities were changed from unplugin-vue-router to vue-router/unplugin, including createRoutesContext and resolveOptions. The prepare:types hook was updated: generated-file comments now reference vue-router, references to unplugin-vue-router/client were removed, and Volar plugin configurations (vue-router/volar/sfc-route-blocks and conditionally vue-router/volar/sfc-typed-router) are injected into tsConfig.vueCompilerOptions. The TypeScript resolver defaults no longer include unplugin-vue-router/client.

🚥 Pre-merge checks | ✅ 2 | ❌ 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 (2 passed)
Check name Status Explanation
Title check ✅ Passed The pull request title clearly and concisely describes the main objective: upgrading to vue-router v5, which aligns with the primary changes made across multiple files updating imports and removing unplugin-vue-router dependencies.
Description check ✅ Passed The pull request description appropriately explains the WIP nature of the upgrade to vue-router 5 and removal of unplugin-vue-router dependency, which directly relates to the changeset.

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

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch refactor/upgrade-vue-router-5

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.

@codspeed-hq
Copy link
Copy Markdown

codspeed-hq bot commented Jan 26, 2026

Merging this PR will not alter performance

✅ 20 untouched benchmarks
⏩ 3 skipped benchmarks1


Comparing refactor/upgrade-vue-router-5 (940857d) with main (7b49d0c)

Open in CodSpeed

Footnotes

  1. 3 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.


/**
* Enable the new experimental typed router using [unplugin-vue-router](https://github.com/posva/unplugin-vue-router).
* Enable the new experimental typed router using vue-router.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I would happily enable this by default in a future minor if you consider it stable enough.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Oh that’s true. I think that if we keep some intermediate types as internal, this should be good to go stable

@posva
Copy link
Copy Markdown
Member Author

posva commented Jan 26, 2026

I also think we could automatically add the volar plugin to the tsconfig

# Conflicts:
#	package.json
#	packages/nuxt/package.json
#	packages/schema/package.json
#	pnpm-lock.yaml
…router-5

# Conflicts:
#	packages/nuxt/package.json
#	pnpm-lock.yaml
@danielroe danielroe changed the title refactor: upgrade to vue-router 5, remove uvr feat(nuxt): upgrade to vue-router v5 Feb 24, 2026
@danielroe danielroe enabled auto-merge February 24, 2026 13:36
Copy link
Copy Markdown
Contributor

@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)
packages/nuxt/src/pages/module.ts (1)

327-344: Make Volar plugin injection idempotent.

If this hook runs more than once or users already configure these plugins, blindly pushing can duplicate entries and create noisy tsconfig diffs. Consider de‑duplicating by name before pushing.

♻️ Suggested idempotent plugin insertion
       // Add vue-router volar plugins to tsconfig
       tsConfig.vueCompilerOptions ||= {}
       tsConfig.vueCompilerOptions.plugins ||= []
-
-      // Always add <route> block support
-      tsConfig.vueCompilerOptions.plugins.push('vue-router/volar/sfc-route-blocks')
+      const plugins = tsConfig.vueCompilerOptions.plugins
+      const hasPlugin = (name: string) =>
+        plugins.some(p => (typeof p === 'string' ? p === name : p?.name === name))
+      const addPlugin = (plugin: string | { name: string; options?: Record<string, any> }) => {
+        const name = typeof plugin === 'string' ? plugin : plugin.name
+        if (!hasPlugin(name)) { plugins.push(plugin as any) }
+      }
+
+      // Always add <route> block support
+      addPlugin('vue-router/volar/sfc-route-blocks')
 
       // Add typed useRoute() when typedPages is enabled
       if (useExperimentalTypedPages) {
-        tsConfig.vueCompilerOptions.plugins.push({
+        addPlugin({
           name: 'vue-router/volar/sfc-typed-router',
           options: { rootDir: nuxt.options.rootDir },
         })
       }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/nuxt/src/pages/module.ts` around lines 327 - 344, The prepare:types
hook currently always pushes volar plugins into
tsConfig.vueCompilerOptions.plugins causing duplicates; update the
nuxt.hook('prepare:types', ...) logic to make insertion idempotent by checking
tsConfig.vueCompilerOptions.plugins for existing entries before pushing: treat
string entries (like 'vue-router/volar/sfc-route-blocks') and object entries
(match by name property, e.g. 'vue-router/volar/sfc-typed-router') as already
present and only push when missing, preserving existing plugin objects and
options (use the existing array on tsConfig.vueCompilerOptions.plugins and
perform a de-duplication check by value/name prior to push).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@packages/nuxt/src/pages/module.ts`:
- Around line 327-344: The prepare:types hook currently always pushes volar
plugins into tsConfig.vueCompilerOptions.plugins causing duplicates; update the
nuxt.hook('prepare:types', ...) logic to make insertion idempotent by checking
tsConfig.vueCompilerOptions.plugins for existing entries before pushing: treat
string entries (like 'vue-router/volar/sfc-route-blocks') and object entries
(match by name property, e.g. 'vue-router/volar/sfc-typed-router') as already
present and only push when missing, preserving existing plugin objects and
options (use the existing array on tsConfig.vueCompilerOptions.plugins and
perform a de-duplication check by value/name prior to push).

ℹ️ Review info

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7a2129e and cd7f202.

📒 Files selected for processing (1)
  • packages/nuxt/src/pages/module.ts

Copy link
Copy Markdown
Contributor

@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)
packages/nuxt/src/pages/module.ts (1)

327-345: Avoid duplicate Volar plugins in tsconfig.

If users already add these plugins, the current push calls can create duplicates. Consider de‑duping by name before pushing.

Suggested tweak
       tsConfig.vueCompilerOptions ||= {}
       tsConfig.vueCompilerOptions.plugins ||= []
+      const plugins = tsConfig.vueCompilerOptions.plugins
+      const hasPlugin = (name: string) =>
+        plugins.some(p => (typeof p === 'string' ? p === name : p?.name === name))

       // Always add <route> block support
-      tsConfig.vueCompilerOptions.plugins.push('vue-router/volar/sfc-route-blocks')
+      if (!hasPlugin('vue-router/volar/sfc-route-blocks')) {
+        plugins.push('vue-router/volar/sfc-route-blocks')
+      }

       // Add typed useRoute() when typedPages is enabled
       if (useExperimentalTypedPages) {
-        tsConfig.vueCompilerOptions.plugins.push({
-          name: 'vue-router/volar/sfc-typed-router',
-          options: { rootDir: nuxt.options.rootDir },
-        })
+        if (!hasPlugin('vue-router/volar/sfc-typed-router')) {
+          plugins.push({
+            name: 'vue-router/volar/sfc-typed-router',
+            options: { rootDir: nuxt.options.rootDir },
+          })
+        }
       }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/nuxt/src/pages/module.ts` around lines 327 - 345, In the
nuxt.hook('prepare:types', ...) block avoid pushing duplicate Volar plugins into
tsConfig.vueCompilerOptions.plugins by checking existing entries (which may be
strings or objects) before pushing: verify that
'vue-router/volar/sfc-route-blocks' is not already present as a string, and when
useExperimentalTypedPages is true check that no plugin object has name ===
'vue-router/volar/sfc-typed-router' before adding the typed-router plugin;
perform these membership checks on tsConfig.vueCompilerOptions.plugins and only
push when the plugin is absent.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@packages/nuxt/src/pages/module.ts`:
- Around line 327-345: In the nuxt.hook('prepare:types', ...) block avoid
pushing duplicate Volar plugins into tsConfig.vueCompilerOptions.plugins by
checking existing entries (which may be strings or objects) before pushing:
verify that 'vue-router/volar/sfc-route-blocks' is not already present as a
string, and when useExperimentalTypedPages is true check that no plugin object
has name === 'vue-router/volar/sfc-typed-router' before adding the typed-router
plugin; perform these membership checks on tsConfig.vueCompilerOptions.plugins
and only push when the plugin is absent.

ℹ️ Review info

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between cd7f202 and 940857d.

📒 Files selected for processing (1)
  • packages/nuxt/src/pages/module.ts

@danielroe danielroe added this pull request to the merge queue Feb 24, 2026
Merged via the queue into main with commit 0cbc4ad Feb 24, 2026
102 of 104 checks passed
@danielroe danielroe deleted the refactor/upgrade-vue-router-5 branch February 24, 2026 16:08
@github-actions github-actions bot mentioned this pull request Feb 24, 2026
This was referenced Mar 8, 2026
@Anoesj
Copy link
Copy Markdown
Contributor

Anoesj commented Mar 11, 2026

Exciting! Thanks for finalizing this @posva and @danielroe! Very curious about user feedback on the Volar plugins.

@adamdehaven
Copy link
Copy Markdown
Contributor

After upgrading to nuxt@4.4.2 with this change, our experimental.typedPages are no longer working.

@posva @danielroe Is this expected after the removal of unplugin-vue-router ?

image

@Anoesj
Copy link
Copy Markdown
Contributor

Anoesj commented Mar 26, 2026

@adamdehaven Could you create an issue with a repro? Note that online repro's don't always work, so a repository is fine too.

@adamdehaven
Copy link
Copy Markdown
Contributor

Odd... working on a net-new install 🤔
Renovate failing me in a monorepo maybe? Debugging...

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants