-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
fix(nuxt): redirect with hash in routeRules #33222
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
|
@nuxt/kit
nuxt
@nuxt/rspack-builder
@nuxt/schema
@nuxt/vite-builder
@nuxt/webpack-builder
commit: |
WalkthroughRedirect handling in packages/nuxt/src/app/middleware/manifest-route-rule.ts was changed to compute a redirect path that uses Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Pre-merge checks and finishing touches❌ Failed checks (1 inconclusive)
✅ Passed checks (4 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: CHILL Plan: Pro 📒 Files selected for processing (1)
🧰 Additional context used📓 Path-based instructions (1)**/*.{ts,tsx}📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Files:
🔇 Additional comments (2)
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. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (2)
packages/nuxt/src/app/middleware/manifest-route-rule.ts (2)
8-16: Consider feature flag protection for this behavioural change.As mentioned in the PR objectives, this change modifies existing redirect behaviour and could potentially cause unexpected results for users who rely on the current behaviour. Consider gating this behind a feature flag to allow gradual rollout.
You could introduce a feature flag check:
if (rules.redirect) { + const preserveHash = process.env.NUXT_PRESERVE_REDIRECT_HASH !== 'false' const hash = window.location.hash const redirectHasHash = rules.redirect.includes('#') + const hashToAppend = preserveHash && !redirectHasHash ? hash : '' if (hasProtocol(rules.redirect, { acceptRelative: true })) { - window.location.href = rules.redirect + (redirectHasHash ? '' : hash) + window.location.href = rules.redirect + hashToAppend return false } - return rules.redirect + (redirectHasHash ? '' : hash) + return rules.redirect + hashToAppend }
15-15: Normalise and percent-encode hash before concatenationpackages/nuxt/src/app/middleware/manifest-route-rule.ts:15 — current:
return rules.redirect + (redirectHasHash ? '' : hash)
- Ensure the fragment has no leading '#' and is percent‑encoded before appending:
const frag = hash.startsWith('#') ? hash.slice(1) : hash; return rules.redirect + (redirectHasHash ? '' : '#' + encodeURIComponent(frag));- Rationale: avoids double "##", malformed '%' sequences and inconsistent browser percent‑encoding for non‑ASCII; use
URL.hashorhistory.pushState()for deterministic history/hashchange behaviour.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
packages/nuxt/src/app/middleware/manifest-route-rule.ts(1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Follow standard TypeScript conventions and best practices
Files:
packages/nuxt/src/app/middleware/manifest-route-rule.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: code
- GitHub Check: build
🔇 Additional comments (2)
packages/nuxt/src/app/middleware/manifest-route-rule.ts (2)
9-10: LGTM! Clean variable declarations for hash preservation logic.The local variables clearly capture the current hash and check if the redirect target already contains a hash fragment.
12-12: Verify hash handling across redirect scenariosCurrent implementation appends window.location.hash when rules.redirect does not include '#' (external targets use window.location.href; internal targets return the redirect string). Location: packages/nuxt/src/app/middleware/manifest-route-rule.ts (lines 8–15).
- Verify behaviour for redirects that already include a fragment, contain query strings (no fragment), are protocol-relative/non-HTTP, or are hash-only (e.g. '#/path').
- Add unit tests covering: external URL with/without fragment, internal route with/without fragment, and hash-only redirects.
CodSpeed Performance ReportMerging #33222 will not alter performanceComparing Summary
|
|
can you reproduce this issue minimally? was just looking at this but things seem to work |
Doesn''t work on my side on the main branch. I'll write a E2E test Edit: Oh i just understood what you said. Yes, i'm write a test for this |
|
It's a bit strange. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (1)
test/basic.test.ts (1)
101-106: Consider using Playwright'spage.waitForURL()instead ofvi.waitFor().Playwright provides a built-in
page.waitForURL()method specifically designed for waiting for URL changes, which offers better error messages and more reliable behaviour than polling withvi.waitFor(). Other tests in this file successfully usepage.waitForURL()(e.g., line 1222).Apply this diff to use the more appropriate Playwright method:
- await vi.waitFor(() => page.url() === url('/#hello'), { timeout: 5_000 }) + await page.waitForURL(url('/#hello'), { timeout: 5_000 })If you're encountering issues with
page.waitForURL()as mentioned in the PR comments, please document the specific problem so it can be investigated further, as this method works correctly in other tests within the same file.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
test/basic.test.ts(2 hunks)test/fixtures/basic/app/pages/index.vue(1 hunks)test/fixtures/basic/app/pages/route-rules/redirect.vue(1 hunks)test/fixtures/basic/nuxt.config.ts(1 hunks)
✅ Files skipped from review due to trivial changes (1)
- test/fixtures/basic/app/pages/route-rules/redirect.vue
🧰 Additional context used
📓 Path-based instructions (3)
**/*.vue
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Use
<script setup lang="ts">and the composition API when creating Vue components
Files:
test/fixtures/basic/app/pages/index.vue
**/*.{ts,tsx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Follow standard TypeScript conventions and best practices
Files:
test/fixtures/basic/nuxt.config.tstest/basic.test.ts
**/*.{test,spec}.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Write unit tests for core functionality using
vitest
Files:
test/basic.test.ts
🧠 Learnings (1)
📚 Learning: 2025-07-18T16:46:07.446Z
Learnt from: CR
PR: nuxt/nuxt#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-07-18T16:46:07.446Z
Learning: Applies to **/*.{test,spec}.{ts,tsx,js,jsx} : Write unit tests for core functionality using `vitest`
Applied to files:
test/basic.test.ts
🧬 Code graph analysis (1)
test/basic.test.ts (1)
test/utils.ts (1)
renderPage(12-51)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (20)
- GitHub Check: test-fixtures (windows-latest, built, rspack, default, manifest-on, json, lts/-1)
- GitHub Check: test-fixtures (windows-latest, built, webpack, async, manifest-on, json, lts/-1)
- GitHub Check: test-fixtures (windows-latest, built, vite, async, manifest-on, json, lts/-1)
- GitHub Check: test-fixtures (windows-latest, dev, vite, async, manifest-on, json, lts/-1)
- GitHub Check: test-fixtures (windows-latest, dev, vite, default, manifest-off, json, lts/-1)
- GitHub Check: test-fixtures (ubuntu-latest, built, rspack, async, manifest-on, json, lts/-1)
- GitHub Check: test-fixtures (ubuntu-latest, built, vite, default, manifest-off, json, lts/-1)
- GitHub Check: test-fixtures (ubuntu-latest, dev, vite, default, manifest-on, json, lts/-1)
- GitHub Check: test-fixtures (ubuntu-latest, built, webpack, async, manifest-on, json, lts/-1)
- GitHub Check: test-fixtures (ubuntu-latest, built, vite, async, manifest-on, js, lts/-1)
- GitHub Check: test-fixtures (ubuntu-latest, built, vite, async, manifest-off, json, lts/-1)
- GitHub Check: test-fixtures (ubuntu-latest, dev, vite, async, manifest-on, json, lts/-1)
- GitHub Check: test-fixtures (ubuntu-latest, built, vite, async, manifest-on, json, lts/-1)
- GitHub Check: test-fixtures (ubuntu-latest, built, vite, default, manifest-on, json, lts/-1)
- GitHub Check: test-fixtures (ubuntu-latest, dev, vite, async, manifest-on, js, lts/-1)
- GitHub Check: release-pkg-pr-new
- GitHub Check: typecheck (windows-latest, bundler)
- GitHub Check: test-benchmark
- GitHub Check: typecheck (ubuntu-latest, bundler)
- GitHub Check: code
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
| if (rules.redirect) { | ||
| if (hasProtocol(rules.redirect, { acceptRelative: true })) { | ||
| window.location.href = rules.redirect | ||
| const path = rules.redirect.includes('#') ? rules.redirect : (rules.redirect + to.hash) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should we also support redirecting with a query string?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah... that's a good question...
Anchors whether present or not won't deeply affect the application while query string can trigger unwanted side-effects
🔗 Linked issue
fix #33217 (comment)
resolves #32802
📚 Description
Should we put it under a flag to avoid unexpected behavior for our users ?