mirror of
https://github.com/vercel/next.js.git
synced 2026-09-20 02:25:18 +08:00
e37c6d636c
- Implements `location` scope check (suggested by @bgw in https://github.com/vercel/next.js/pull/92900#discussion_r3107167621), ensuring `location` is a true global variable before reporting. - Implements basic variable tracking (suggested by @icyJoseph in https://github.com/vercel/next.js/pull/93057#issuecomment-4281583840) --------- Co-authored-by: Benjamin Woodruff <benjamin.woodruff@vercel.com>
93 lines
2.5 KiB
Plaintext
93 lines
2.5 KiB
Plaintext
---
|
|
title: No location.assign or location.href navigation to relative URLs
|
|
---
|
|
|
|
> Prevent usage of `location.assign()` or `location.href` assignment to navigate to internal Next.js pages.
|
|
|
|
## Why This Error Occurred
|
|
|
|
`location.assign()` or `location.href = ...` was used to navigate to a relative URL. In Next.js, this bypasses the client-side router, causing a full page reload and losing any prefetched data or state managed by the framework.
|
|
|
|
## Possible Ways to Fix It
|
|
|
|
### During the render phase
|
|
|
|
Use [`redirect()`](/docs/app/api-reference/functions/redirect) from `next/navigation`:
|
|
|
|
```tsx filename="app/page.tsx"
|
|
import { redirect } from 'next/navigation'
|
|
|
|
export default function Page() {
|
|
redirect('/dashboard')
|
|
}
|
|
```
|
|
|
|
```tsx filename="app/components/my-component.tsx"
|
|
'use client'
|
|
|
|
import { redirect } from 'next/navigation'
|
|
|
|
export default function MyComponent({
|
|
isAuthorized,
|
|
}: {
|
|
isAuthorized: boolean
|
|
}) {
|
|
if (!isAuthorized) {
|
|
redirect('/login')
|
|
}
|
|
return <div>Protected content</div>
|
|
}
|
|
```
|
|
|
|
### In Client Components (event handlers)
|
|
|
|
Use [`useRouter().push()`](/docs/app/api-reference/functions/use-router) from `next/navigation`:
|
|
|
|
```tsx filename="app/components/my-button.tsx"
|
|
'use client'
|
|
|
|
import { useRouter } from 'next/navigation'
|
|
|
|
export default function MyButton() {
|
|
const router = useRouter()
|
|
|
|
return (
|
|
<button onClick={() => router.push('/dashboard')}>Go to Dashboard</button>
|
|
)
|
|
}
|
|
```
|
|
|
|
### External URLs
|
|
|
|
If you are navigating to an external URL (one with a protocol, e.g. `https://`), `location.assign()` and `location.href` are acceptable and will not trigger this rule:
|
|
|
|
```js
|
|
// Allowed — navigating to an external site
|
|
location.href = 'https://example.com'
|
|
window.location.assign(`https://example.org/${path}`)
|
|
|
|
// Allowed — variable with absolute URL prefix
|
|
const url = 'https://example.com/' + path
|
|
location.href = url
|
|
```
|
|
|
|
### No Statically Analyzable Values
|
|
|
|
If the rule cannot statically determine whether a value is absolute or relative (e.g., function calls, event properties), the check is skipped:
|
|
|
|
```js
|
|
// Skipped — cannot determine statically
|
|
const url = getUrl() // Function call
|
|
location.href = url
|
|
|
|
// Skipped — cannot determine statically
|
|
location.href = event.target.href
|
|
```
|
|
|
|
## Useful Links
|
|
|
|
- [Redirecting in Next.js](/docs/app/guides/redirecting)
|
|
- [Linking and Navigating in Next.js](/docs/app/getting-started/linking-and-navigating)
|
|
- [`redirect` API Reference](/docs/app/api-reference/functions/redirect)
|
|
- [`useRouter` API Reference](/docs/app/api-reference/functions/use-router)
|