feat: add redirectStatusCode option#3685
Conversation
WalkthroughA new optional property, Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant App
participant I18nContext
participant RuntimeConfig
participant Router
User->>App: Initiates navigation
App->>I18nContext: Retrieve redirectStatusCode
I18nContext->>RuntimeConfig: Get redirectStatusCode from config
App->>Router: navigateTo(destination, { redirectCode: redirectStatusCode })
Router-->>User: Performs redirect with specified status code
Suggested labels
Poem
📜 Recent review detailsConfiguration used: CodeRabbit UI 📒 Files selected for processing (3)
🚧 Files skipped from review as they are similar to previous changes (2)
⏰ Context from checks skipped due to timeout of 90000ms (5)
🔇 Additional comments (1)
✨ Finishing Touches
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. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (2)
src/constants.ts (1)
64-64: Consider adding validation for HTTP redirect status codes.The default value is appropriate. However, consider validating that when
redirectStatusCodeis provided, it's a valid HTTP redirect status code (e.g., 301, 302, 303, 307, 308).Example validation could be added during option processing:
const validRedirectCodes = [301, 302, 303, 307, 308]; if (options.redirectStatusCode && !validRedirectCodes.includes(options.redirectStatusCode)) { throw new Error(`Invalid redirectStatusCode: ${options.redirectStatusCode}. Must be one of: ${validRedirectCodes.join(', ')}`); }src/types.ts (1)
174-174: Missing JSDoc forredirectStatusCodeoption
The newredirectStatusCodeproperty should include a JSDoc comment explaining its purpose, default behavior when not set, and allowed HTTP status codes.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
src/constants.ts(1 hunks)src/prepare/runtime-config.ts(1 hunks)src/runtime/context.ts(2 hunks)src/runtime/utils.ts(1 hunks)src/types.ts(2 hunks)
🔇 Additional comments (4)
src/prepare/runtime-config.ts (1)
14-14: LGTM! Correct integration into runtime configuration.The addition follows the established pattern for passing configuration options to the runtime config.
src/runtime/context.ts (2)
44-44: LGTM! Correct interface extension.The type definition properly allows
undefinedwhich is consistent with the optional nature of this configuration.
105-105: LGTM! Proper initialization pattern.The initialization follows the established pattern for other context properties.
src/types.ts (1)
360-360: Correctly exposedredirectStatusCodein public runtime config
TheI18nPublicRuntimeConfignow properly includes the new option.
| } | ||
|
|
||
| return navigateTo(destination) | ||
| return navigateTo(destination, { redirectCode: ctx.redirectStatusCode }) |
There was a problem hiding this comment.
💡 Verification agent
🧩 Analysis chain
Verify that navigateTo handles undefined redirectCode gracefully.
The implementation correctly uses the new redirectStatusCode option. The naming change from redirectStatusCode to redirectCode aligns with the navigateTo API.
Run the following script to verify the navigateTo function signature and confirm it properly handles undefined values for redirectCode:
🏁 Script executed:
#!/bin/bash
# Description: Verify navigateTo function signature and redirectCode parameter handling
# Search for navigateTo function definition and usage
rg -A 10 "function navigateTo|export.*navigateTo" --type ts
echo "---"
# Look for redirectCode parameter usage in navigateTo
rg -A 5 -B 5 "redirectCode" --type tsLength of output: 1318
🌐 Web query:
What is the TypeScript signature of the navigateTo function in Nuxt 3? Specifically, what is the type of the redirectCode option parameter?
💡 Result:
TypeScript Signature of navigateTo in Nuxt 3
The navigateTo function in Nuxt 3 is used for programmatic navigation both on the server and client sides. Its TypeScript signature is as follows:
function navigateTo(
to: RouteLocationRaw | undefined | null,
options?: NavigateToOptions
): Promise<void | NavigationFailure | false> | false | void | RouteLocationRaw
interface NavigateToOptions {
replace?: boolean
redirectCode?: number
external?: boolean
open?: OpenOptions
}
type OpenOptions = {
target: string
windowFeatures?: OpenWindowFeatures
}[1]
Type of the redirectCode Option
The redirectCode property in the NavigateToOptions interface is of type number. It allows you to specify the HTTP status code used for redirection when the navigation is handled on the server (for instance, during SSR or API requests). By default, Nuxt uses a status code of 302 (temporary redirect), but you can override it, for example, with 307 for a temporary redirect that preserves the request method, or 308 for a permanent redirect[1][6][7].
Example usage:
await navigateTo('/another-page', {
redirectCode: 307
})[6]
Summary Table
| Option | Type | Description |
|---|---|---|
| redirectCode | number | HTTP status code for server-side redirects (e.g., 302, 307, 308) |
The redirectCode is optional and only relevant in server-side navigation scenarios[1][6].
Citations:
- 1: https://nuxt.com/docs/api/utils/navigate-to
- 2:
navigateTodoesn't return promise, thus cannot be awaited nuxt/bridge#1226 - 3: https://nuxt.com/docs/getting-started/error-handling
- 4:
navigateTowithopenandnameparams opens a home url. nuxt/nuxt#28130 - 5: https://nuxt.com/docs/api/components/nuxt-link
- 6: https://masteringnuxt.com/blog/how-to-redirect-in-nuxt-every-single-way
- 7: Some page recalls navigateTo again with 302 redirectCode. #2528
- 8: https://nuxt.com/docs/api/utils/dollarfetch
- 9: https://deltener.com/blog/creating-redirects-with-nuxt/
- 10: https://nuxt.com/llms-full.txt
Verified navigateTo Redirect Option
- The
navigateTosignature in Nuxt 3 declaresoptions?: { redirectCode?: number; … }, so passingctx.redirectStatusCode(even ifundefined) is handled gracefully. - Suggest adding a simple validation to ensure
ctx.redirectStatusCodeis a valid HTTP status code (e.g. between 300 and 399, or 307/308) before passing it tonavigateTo.
Affected location:
- src/runtime/utils.ts line 289
🤖 Prompt for AI Agents
In src/runtime/utils.ts at line 289, the call to navigateTo passes
ctx.redirectStatusCode directly as redirectCode without validation. To fix this,
add a check to ensure ctx.redirectStatusCode is a valid HTTP redirect status
code (typically between 300 and 399, or specifically 307 or 308) before passing
it. If it is invalid or undefined, omit the redirectCode option or set it to a
default valid value to prevent potential unexpected behavior.
|
Thank you for your PR! This looks like a good option to add, as you have already noted we will need to add documentation and some tests before we can merge this 🙏 Also, this PR may get delayed a bit since I am working on changes that may overlap with it in #3687. |
|
Thank you for the info @BobbieGoede. |
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (1)
specs/routing_strategies/redirect_status_code.spec.ts (1)
23-35: Solid test coverage for core functionality with room for enhancement.The test cases effectively verify that:
- The new
redirectStatusCodeoption works for general redirects- Existing
rootRedirectconfiguration remains unaffectedConsider adding these test scenarios for more comprehensive coverage:
- Testing redirects with different source locales
- Validating behavior with invalid status codes
- Testing interaction with browser language detection when enabled
test('does not affect root redirect option', async () => { const rootRes = await fetch('/', { redirect: 'manual' }) expect(rootRes.status).toEqual(418) expect(rootRes.headers.get('location')).toEqual('/en/test-route') }) + + test('works with different source paths', async () => { + const res = await fetch('/contact', { redirect: 'manual' }) + expect(res.status).toBe(307) + expect(res.headers.get('location')).toEqual('/en/contact') + })
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
specs/routing_strategies/redirect_status_code.spec.ts(1 hunks)
🔇 Additional comments (1)
specs/routing_strategies/redirect_status_code.spec.ts (1)
6-21: Well-designed test setup for isolating the new feature.The configuration effectively isolates the
redirectStatusCodefeature by disabling browser language detection and using distinct status codes (307 for general redirects vs 418 for root redirects) to verify that the new option works correctly without interfering with existing functionality.
redirectStatusCode option
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (1)
src/runtime/server/plugin.ts (1)
118-120: Implementation looks correct, but consider adding validation.The implementation correctly applies the configured redirect status code when no root redirect is applicable. However, consider adding validation to ensure the
redirectStatusCodeis a valid HTTP status code.- } else if (runtimeI18n.redirectStatusCode) { - redirectCode = runtimeI18n.redirectStatusCode + } else if (runtimeI18n.redirectStatusCode) { + // Validate that it's a valid HTTP redirect status code (3xx) + if (runtimeI18n.redirectStatusCode >= 300 && runtimeI18n.redirectStatusCode < 400) { + redirectCode = runtimeI18n.redirectStatusCode + } }Alternatively, validation could be performed at the configuration level rather than runtime for better performance.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
specs/routing_strategies/redirect_status_code.spec.ts(1 hunks)src/runtime/context.ts(2 hunks)src/runtime/server/plugin.ts(3 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
- src/runtime/context.ts
- specs/routing_strategies/redirect_status_code.spec.ts
🧰 Additional context used
🧠 Learnings (1)
src/runtime/server/plugin.ts (2)
Learnt from: BobbieGoede
PR: nuxt-modules/i18n#3587
File: src/runtime/plugins/route-locale-detect.ts:24-31
Timestamp: 2025-05-05T20:42:02.900Z
Learning: In nuxt-modules/i18n's route detection, the `detectLocale` function returns a string representing the locale code, not an object. This string can be passed directly to `ctx.setLocale`.
Learnt from: BobbieGoede
PR: nuxt-modules/i18n#3587
File: src/runtime/plugins/route-locale-detect.ts:24-31
Timestamp: 2025-05-05T20:42:02.900Z
Learning: In nuxt-modules/i18n's route detection, the `detectLocale` function returns a string representing the locale code, not an object. This string can be passed directly to `ctx.setLocale`.
⏰ Context from checks skipped due to timeout of 90000ms (3)
- GitHub Check: test (lts/*, ubuntu-latest)
- GitHub Check: test (lts/*, windows-latest)
- GitHub Check: lint (lts/*, ubuntu-latest)
🔇 Additional comments (2)
src/runtime/server/plugin.ts (2)
41-42: LGTM: Good addition of fallback locale detection.The addition of a fallback locale yield ensures that the detection process always has a fallback option available, improving the robustness of locale detection.
101-101: LGTM: Proper defensive programming with logical OR assignment.Using the logical OR assignment operator to ensure
localedefaults todefaultLocalewhen no supported locale is found is a good defensive programming practice.
|
Thank you for updating the PR! I have made some small changes and also modified the test to use the nitro context detection. The goal is to remove the option to disable nitro context detection in the future (just adding context why I did not add a separate fixture with it disabled). |
🔗 Linked issue
No linked issue.
📚 Description
This PR introduces a new
redirectCodeoption, allowing developers to specify the HTTP status code used for localization redirects (e.g., 303 for redirects). This adds flexibility to how redirects are handled.This is my first contribution to
nuxt-i18n, so please feel free to share any feedback or suggestions — I'd really appreciate it!Summary by CodeRabbit
Summary by CodeRabbit
New Features
Enhancements
Tests