Commit graph

45 commits

Author SHA1 Message Date
Zack Tanner
c116da32de
fix double redirect when using a loading boundary (#63786)
### What & Why
When an RSC triggers `navigate` after the shell has already been sent to
the client, a meta tag is inserted to signal to the browser it needs to
perform an MPA navigation. This is primarily used for bot user agents,
since we wouldn't have been able to provide a proper redirect status
code (since it occurred after the initial response was sent).

However, the router would trigger a SPA navigation, while the `<meta>`
tag lagged to perform an MPA navigation, resulting in 2 navigations to
the same URL.

### How
When the client side code attempts to handle the redirect, we treat it
like an MPA navigation. This will suspend in render and trigger a
`location.push`/`location.replace` to the targeted URL. As a result,
only one of these navigation events will win.

Fixes #59800
Fixes #62463

Closes NEXT-2952
Closes NEXT-2719
2024-03-28 16:08:39 -07:00
Zack Tanner
4caaccbdf6
fix flakey navigation test (#62598)
This test pretty consistently fails locally and in CI with the following
error in the request handler:

> Target page, context or browser has been closed


[x-ref](https://github.com/vercel/next.js/actions/runs/8069442877/job/22047444250#step:27:798)
<!-- Thanks for opening a PR! Your contribution is much appreciated.
To make sure your PR is handled as smoothly as possible we request that
you follow the checklist sections below.
Choose the right checklist for the change(s) that you're making:

## For Contributors

### Improving Documentation

- Run `pnpm prettier-fix` to fix formatting issues before opening the
PR.
- Read the Docs Contribution Guide to ensure your contribution follows
the docs guidelines:
https://nextjs.org/docs/community/contribution-guide

### Adding or Updating Examples

- The "examples guidelines" are followed from our contributing doc
https://github.com/vercel/next.js/blob/canary/contributing/examples/adding-examples.md
- Make sure the linting passes by running `pnpm build && pnpm lint`. See
https://github.com/vercel/next.js/blob/canary/contributing/repository/linting.md

### Fixing a bug

- Related issues linked using `fixes #number`
- Tests added. See:
https://github.com/vercel/next.js/blob/canary/contributing/core/testing.md#writing-tests-for-nextjs
- Errors have a helpful link attached, see
https://github.com/vercel/next.js/blob/canary/contributing.md

### Adding a feature

- Implements an existing feature request or RFC. Make sure the feature
request has been accepted for implementation before opening a PR. (A
discussion must be opened, see
https://github.com/vercel/next.js/discussions/new?category=ideas)
- Related issues/discussions are linked using `fixes #number`
- e2e tests added
(https://github.com/vercel/next.js/blob/canary/contributing/core/testing.md#writing-tests-for-nextjs)
- Documentation added
- Telemetry added. In case of a feature if it's used or not.
- Errors have a helpful link attached, see
https://github.com/vercel/next.js/blob/canary/contributing.md


## For Maintainers

- Minimal description (aim for explaining to someone not on the team to
understand the PR)
- When linking to a Slack thread, you might want to share details of the
conclusion
- Link both the Linear (Fixes NEXT-xxx) and the GitHub issues
- Add review comments if necessary to explain to the reviewer the logic
behind a change

### What?

### Why?

### How?

Closes NEXT-
Fixes #

-->


Closes NEXT-2626
2024-02-27 20:52:51 +00:00
Zack Tanner
48bad4e894
fix router crash on revalidate + popstate (#62383)
### What
When the popstate action is fired (as is the case in a browser back
button), if the page you're going back to has missing cache node data,
the router will crash.

### Why
Almost all router actions will suspend at the app-router level with the
exception of `ACTION_RESTORE`. This was to address an issue where
suspending in the router would add enough delay for browser scroll
restoration behavior not to work.

As a result, when going back to the page with missing data, app-router
wouldn't suspend but layout-router would suspend on the missing data
while triggering a lazy fetch. We trigger a server-patch with the
applied lazy data, but when React replays the render, it will replay the
branch without the cache node data applied. This results in the router
getting caught in a loop of suspending, applying the cache node,
replaying the branch without the cache node, and eventually crashing due
to an error thrown by React to prevent re-suspending indefinitely.

### How
This adds a property to the cache node to signal if the lazy data has
been resolved. If it has been, we won't call the server patch action
again.

Fixes #61336
Closes NEXT-2438
2024-02-27 10:15:36 -08:00
Jiachi Liu
e5d604f33b
Upgrade vendored react (#62326)
### React upstream changes

- https://github.com/facebook/react/pull/28333
- https://github.com/facebook/react/pull/28334
- https://github.com/facebook/react/pull/28378
- https://github.com/facebook/react/pull/28377
- https://github.com/facebook/react/pull/28376
- https://github.com/facebook/react/pull/28338
- https://github.com/facebook/react/pull/28331
- https://github.com/facebook/react/pull/28336
- https://github.com/facebook/react/pull/28320
- https://github.com/facebook/react/pull/28317
- https://github.com/facebook/react/pull/28375
- https://github.com/facebook/react/pull/28367
- https://github.com/facebook/react/pull/28380
- https://github.com/facebook/react/pull/28368
- https://github.com/facebook/react/pull/28343
- https://github.com/facebook/react/pull/28355
- https://github.com/facebook/react/pull/28374
- https://github.com/facebook/react/pull/28362
- https://github.com/facebook/react/pull/28344
- https://github.com/facebook/react/pull/28339
- https://github.com/facebook/react/pull/28353
- https://github.com/facebook/react/pull/28346
- https://github.com/facebook/react/pull/25790
- https://github.com/facebook/react/pull/28352
- https://github.com/facebook/react/pull/28326
- https://github.com/facebook/react/pull/27688
- https://github.com/facebook/react/pull/28329
- https://github.com/facebook/react/pull/28332
- https://github.com/facebook/react/pull/28340
- https://github.com/facebook/react/pull/28327
- https://github.com/facebook/react/pull/28325
- https://github.com/facebook/react/pull/28324
- https://github.com/facebook/react/pull/28309
- https://github.com/facebook/react/pull/28310
- https://github.com/facebook/react/pull/28307
- https://github.com/facebook/react/pull/28306
- https://github.com/facebook/react/pull/28315
- https://github.com/facebook/react/pull/28318
- https://github.com/facebook/react/pull/28226
- https://github.com/facebook/react/pull/28308
- https://github.com/facebook/react/pull/27563
- https://github.com/facebook/react/pull/28297
- https://github.com/facebook/react/pull/28286
- https://github.com/facebook/react/pull/28284
- https://github.com/facebook/react/pull/28275
- https://github.com/facebook/react/pull/28145
- https://github.com/facebook/react/pull/28301
- https://github.com/facebook/react/pull/28224
- https://github.com/facebook/react/pull/28152
- https://github.com/facebook/react/pull/28296
- https://github.com/facebook/react/pull/28294
- https://github.com/facebook/react/pull/28279
- https://github.com/facebook/react/pull/28273
- https://github.com/facebook/react/pull/28269
- https://github.com/facebook/react/pull/28376
- https://github.com/facebook/react/pull/28338
- https://github.com/facebook/react/pull/28331
- https://github.com/facebook/react/pull/28336
- https://github.com/facebook/react/pull/28320
- https://github.com/facebook/react/pull/28317
- https://github.com/facebook/react/pull/28375
- https://github.com/facebook/react/pull/28367
- https://github.com/facebook/react/pull/28380
- https://github.com/facebook/react/pull/28368
- https://github.com/facebook/react/pull/28343
- https://github.com/facebook/react/pull/28355
- https://github.com/facebook/react/pull/28374
- https://github.com/facebook/react/pull/28362
- https://github.com/facebook/react/pull/28344
- https://github.com/facebook/react/pull/28339
- https://github.com/facebook/react/pull/28353
- https://github.com/facebook/react/pull/28346
- https://github.com/facebook/react/pull/25790
- https://github.com/facebook/react/pull/28352
- https://github.com/facebook/react/pull/28326
- https://github.com/facebook/react/pull/27688
- https://github.com/facebook/react/pull/28329
- https://github.com/facebook/react/pull/28332
- https://github.com/facebook/react/pull/28340
- https://github.com/facebook/react/pull/28327
- https://github.com/facebook/react/pull/28325
- https://github.com/facebook/react/pull/28324
- https://github.com/facebook/react/pull/28309
- https://github.com/facebook/react/pull/28310
- https://github.com/facebook/react/pull/28307
- https://github.com/facebook/react/pull/28306
- https://github.com/facebook/react/pull/28315
- https://github.com/facebook/react/pull/28318
- https://github.com/facebook/react/pull/28226
- https://github.com/facebook/react/pull/28308
- https://github.com/facebook/react/pull/27563
- https://github.com/facebook/react/pull/28297
- https://github.com/facebook/react/pull/28286
- https://github.com/facebook/react/pull/28284
- https://github.com/facebook/react/pull/28275
- https://github.com/facebook/react/pull/28145
- https://github.com/facebook/react/pull/28301
- https://github.com/facebook/react/pull/28224
- https://github.com/facebook/react/pull/28152
- https://github.com/facebook/react/pull/28296
- https://github.com/facebook/react/pull/28294
- https://github.com/facebook/react/pull/28279
- https://github.com/facebook/react/pull/28273
- https://github.com/facebook/react/pull/28269

Closes NEXT-2542


Disable ppr test for strict mode for now, @acdlite will check it and
we'll sync again
2024-02-23 12:46:58 +01:00
Leah
60f0837b67
refactor(tests): make chain more "correct" (#51728)
### Why?

I really dislike the way `.chain` works right now, it shouldn't mutate
the `BrowserInterface`, this PR changes it so it's just a pure chain
without weird side effects.

One example with the current version (before this PR):
```
const el = browser.elementByCss('#version-2')
await el.text()
// throws
await el.text()
```

### Additional Changes

- removes selenium (which is completely unused)
- updates playwright
- makes the playwright tracing not error all the time
2024-02-14 20:14:24 +01:00
Wyatt Johnson
252d9cf453
Navigation Signals in PPR (#60450)
### What

This adds support for navigation signals like `notFound()` and
`redirect(url)` when Partial Prerendering has been enabled.

### Why

Navigation API's like `notFound()` and `redirect(url)` throw errors in
order to interrupt the rendering of components. When a page both invokes
API's that cause the render to be marked as dynamic (like
`unstable_noStore()`) and also a navigation API, these errors may race
to the end. In the case where the navigation error does not beat out the
error emitted by dynamic API's will still trigger the detection warning
that's present to warn you about situations where you may have
accidentally caught the error.

### How

This resolves this issue by explicitly checking for navigation signals
(errors) thrown during the render, and not displaying the "caught
dynamic API" error and console warning.

Closes NEXT-2037
2024-02-06 12:25:50 -07:00
Zack Tanner
a19b3bc6fb
fix navigation issue when dynamic param casing changes (#61726)
### What
When navigating to a page with dynamic params using a certain casing,
and then following a link to another page using _different_ casing for
the same param, the router would get stuck in an infinite suspense
cycle.

### Why
On the client we normalize cache keys by lowercasing the values for
dynamic segments. However the RSC data for each segment wouldn't have
this same casing logic applied. This is causing the router to not
recognize that there is already RSC data available for that segment,
resulting in an infinite suspense cycle.

### How
The `toLowerCase()` logic shouldn't be needed here. Technically we could
leave this in place and update `matchSegment` to also apply the
lowercase logic, but currently there are too many utility functions that
parse segments to comfortably make that change. I confirmed that the bug
related to why we lowercased these router cache keys is no longer
present after making this change.

Fixes #61722
Closes NEXT-2377
2024-02-06 08:59:18 -08:00
Zack Tanner
da842e167a
fix loading issue when navigating to page with async metadata (#61687)
### What
Client-side transitioning to a page that triggered a loading boundary
with async metadata would cause the transition to stall, potentially
getting stuck in a refetch loop.

### Why
In layout-router, we trigger a "lazy fetch" when we encounter a segment
that we don't have cache nodes for. This calls out to the server and
suspends until the data fetch is resolved, and applied to the router
tree. However after suspending but before updating the client router, we
set `childNode.lazyData` to null. When we unsuspend from the server
patch action, `childNode.rsc` might still be missing and clearing
`lazyData` means we've blown away the reference to the fetch we already
had pending, triggering a refetch loop.

### How
This removes the logic that mutates the cache node in render, as this is
not concurrent safe, and doesn't appear to be needed for anything.

Fixes #61117
Closes NEXT-2361

---------

Co-authored-by: Jiachi Liu <inbox@huozhi.im>
2024-02-06 07:10:53 -08:00
Wyatt Johnson
55917c064e
Transition some check calls in tests to retry (#60489)
Closes NEXT-2049
2024-01-10 14:12:40 -07:00
Wyatt Johnson
26a2f603cc
Handle pages double render for useParams in tests (#60486)
Closes NEXT-2048
2024-01-10 13:19:24 -07:00
Zack Tanner
a578cc8192
fix inconsistent scroll restoration behavior (#59366)
### What?
While scrolled on a page, and when following a link to a new page and
clicking the browser back button or using `router.back()`, the scroll
position would sometimes restore scroll to the incorrect spot (in the
case of the test added in this PR, it'd scroll you back to the top of
the list)

### Why?
The refactor in #56497 changed the way router actions are processed:
specifically, all actions were assumed to be async, even if they could
be handled synchronously. For most actions this is fine, as most are
currently async. However, `ACTION_RESTORE` (triggered when the
`popstate` event occurs) isn't async, and introducing a small amount of
delay in the handling of this action can cause the browser to not
properly restore the scroll position

### How?
This special-cases `ACTION_RESTORE` to synchronously process the action
and call `setState` when it's received, rather than creating a promise.
To consistently reproduce this behavior, I added an option to our
browser interface that'll allow us to programmatically trigger a CPU
slowdown.

h/t to @alvarlagerlof for isolating the offending commit and sharing a
minimal reproduction.

Closes NEXT-1819
Likely addresses #58899 but the reproduction was too complex to verify.
2023-12-07 11:17:15 -08:00
François Best
e4158f6cec
fix: Don't reset shallow URL updates on prefetch (#58297)
## Description

Between 14.0.2-canary.6 and 14.0.2-canary.7, a change was introduced in vercel/next.js#56497 that turned the Redux store state into a Promise, rather than a synchronous state update.

This caused the `sync` function -- used to send state updates to the Redux Devtools -- to be recreated on every dispatch, which in turn, by referential instability, caused the `HistoryUpdater` component to re-render and trigger a `history.replaceState` with no particular change, but with the internal `canonicalUrl`.

When an app does a soft/shallow navigation by calling history methods directly (currently the only way to do shallow search params updates in the app router), these changes would have been overwritten by any prefetch (eg: hovering or mounting a Link), which is usually a no-op for the navigation state.

This PR changes the `sync` function to take the state as an argument rather than as a closure. The whole app router state is also unwrapped only once, and fed to the HistoryUpdater. Changes to its contents made by reducers will cause the HistoryUpdater effect to re-run, triggering history updates and a call to the sync function.

## Context

I maintain [`next-usequerystate`](https://github.com/47ng/next-usequerystate), which is used in the Vercel dashboard, and which is impacted by this change (see 
[#388](https://github.com/47ng/next-usequerystate/issues/388)).

## History

@timneutkens introduced the `sync` function and the whole Redux devtools reducer in vercel/next.js#39866, with the note:

> a new hook useReducerWithReduxDevtools has been added, we'll probably want to put this behind a compile-time flag when the new router is marked stable but until then it's useful to have it enabled by default (only 
when you have Redux Devtools installed ofcourse). 

If a different direction is needed to keep sending `RENDER_SYNC` actions to Redux devtools, I'll be happy to rework this PR to move the `sync` function into the action queue.

## Changes

- [x] Added e2e test. Requires a `start` mode as prefetch links are disabled in development. Test was verified to fail from next@>=12.0.2-canary.7 without the fix.


Co-authored-by: Zack Tanner <1939140+ztanner@users.noreply.github.com>
2023-11-14 19:29:18 +00:00
Jiachi Liu
9af75d4b2d
Fix client chunk loading encoding for dynamic route (#57960)
We had added encoding the client component assets loaded from RSC manifest that we need to encode them to make sure when they're loaded on server and sent to client, the client will receive the encoded one. But the override of the webpack chunk loading method could be loaded later than react related chunks, that when client component is loaded first (e.g. `next/script`) and it triggers react loaded ealier than the overriding. Then the chunk could be encoded incorrectly.

Discussed with @gnoff and put this out as the 1st step solution to ensure the order. in the future we can try to get rid of the encoding by providing safer url

Fixes #57829
2023-11-02 23:09:25 +00:00
Zack Tanner
3264d91dab
memoize useParams (#56771)
`useParams` is not referentially equal between renders which can lead to unexpected behavior when used as a dep. 
This memoizes the response from `useParams` similar to `useSearchParams`.

[slack x-ref](https://vercel.slack.com/archives/C04DUD7EB1B/p1697145987740229)
2023-10-13 07:47:05 +00:00
Boris Besemer
a2f9ef5a34
fix(next/client): keep hash when navigating from app to pages router (#56223)
### What?

Fixes the pages router not receiving a hash when being linked from the
app router.

### Why?

The hash being removed breaks sites that rely on it for client side
features.

### How?

The hash gets omitted from the URL when used as a key for the
preflightCache. Once it's clear that it's an external URL and that it's
not empty we can use the initial href to send the hash as well.

Not completely sure if there's an edge case that might break, I added an
extra check for when the hash is only used to scroll the page.

This might need an additional test case just for
`navigate-reducer.test.tsx`.

Fixes #56212

---------

Co-authored-by: Zack Tanner <zacktanner@gmail.com>
Co-authored-by: JJ Kasper <jj@jjsweb.site>
2023-10-02 14:43:04 -07:00
Zack Tanner
d330f7b02c
fix: ensure mpa navigation render side effects are only fired once (#55032)
This is to fix an issue where these redirect side effects can be fired multiple times when the router reducer state changes. This block is still run when the router state updates, which can lead to superfluous attempts to redirect to a page.

With these changes, we keep track of the page that is being redirected to. If a re-render occurs while that request is in flight, we don't trigger the side effects. 

[Slack x-ref](https://vercel.slack.com/archives/C04DUD7EB1B/p1694049914264839)
2023-09-07 20:53:07 +00:00
Max Leiter
4c3b7f9b7a
Export RedirectType from next/navigation (#54729)
A continuation of #51864 with RedirectType used in an e2e test and some
ts-ignores removed from the codebase. Happy to split it into two PRs but
I left comments in the two consequential files

---------
2023-08-29 11:05:44 -07:00
Shohei Maeda
efd8d22654
Add new permanentRedirect function in App Router (#54047)
for internal:
https://vercel.slack.com/archives/C03S8ED1DKM/p1691700057242999

### Problem

- The existing [`redirect()`
function](https://nextjs.org/docs/app/api-reference/functions/redirect)
can't control the status code.
- The existing [`redirect()`
function](https://nextjs.org/docs/app/api-reference/functions/redirect)
returns a 307 HTTP redirect response while it returns a 308-equivalent
meta tag `<meta http-equiv="refresh" content="0;url=/foo"/>` in
streaming response (e.g., suspense boundary), making the behavior
inconsistent.

### Solution

Adding a new `permanentRedirect()` function and changing the meta tag
default accordingly.

| func   |      HTTP status      |  meta tag |
|---|:---:|---|
| `redirect()` | 307 | `<meta http-equiv="refresh"
content="1;url=/foo"/>` |
| `permanentRedirect()` | 308 | `<meta http-equiv="refresh"
content="0;url=/foo"/>` |

ref.
https://developers.google.com/search/docs/crawling-indexing/301-redirects

---------

Co-authored-by: JJ Kasper <jj@jjsweb.site>
Co-authored-by: Tim Neutkens <tim@timneutkens.nl>
Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2023-08-28 14:22:43 -07:00
Zack Tanner
e08839a5a9
fix infinite navigate events when Promise is proxied (#54394)
### What
When the global `window.Promise` is proxied, things that rely on custom Promise properties (e.g. the `status` field) break. In the case of navigation events, the prefetch cache is never identified as being fulfilled, so navigation hangs in an infinite loop.

### How?
This ensures that the value being stored in the prefetch cache have the expected Promise signature even when proxied. 

x-ref: https://github.com/vercel/next.js/discussions/53746 
[slack x-ref](https://vercel.slack.com/archives/C03S8ED1DKM/p1692626697034029)
2023-08-24 16:22:48 +00:00
Jiachi Liu
1fefb4a8d2
Reland "Refine the not-found rendering process for app router" (#52985)
Reland #52790
Reverts vercel/next.js#52977

was failed due to failed job
[vercel/next.js/actions/runs/5616458194/job/15220295829](https://github.com/vercel/next.js/actions/runs/5616458194/job/15220295829)

Should be fine to resolve with
https://github.com/vercel/next.js/pull/52979 now

Fixes #52718
Fixes #52739

---------

Co-authored-by: Alex Kirszenberg <alex.kirszenberg@vercel.com>
Co-authored-by: Tobias Koppers <tobias.koppers@googlemail.com>
2023-07-21 10:09:30 -07:00
JJ Kasper
d7335b75d1
Revert "Refine the not-found rendering process for app router" (#52977)
Reverts vercel/next.js#52790

Reverting temporarily as this breaks turbopack's not found handling due
to the app tree being generated there not having the necessary parallel
routes in the `_not-found` entry x-ref:
0df8aac935/packages/next-swc/crates/next-core/src/app_structure.rs (L677-L681)

x-ref:
https://github.com/vercel/next.js/actions/runs/5616458194/job/15220295829
2023-07-20 20:39:05 -07:00
Jiachi Liu
cb24c555a6
Refine the not-found rendering process for app router (#52790)
### What

This PR changes the flow of not-found rendering process. 

### Why

`not-found.js` was rendered in two ways before:
* 1 is SSR rendering the not-found as 404
* 2 is triggering the error on RSC rendering then the error will be
preserved in inline flight data, on the client it will recover the error
and trigger the proper error boundary.

The solution has been through a jounery:
No top-level not found boundary -> introduce metadata API -> then we
create a top level root not found boundary -> then we delete it due to
duplicated rendering of root layout -> now this

So the solution before this PR is still having a root not found boundary
wrapped in the `AppRouter`, it's being used in a lot of places including
HMR. As we discovered it's doing duplicated rendering of root layout,
then we removed it and it started failing with rendering `not-found` but
missing root layout. In this PR we redesign the process.

### How

Now the rendering architecture looks like:

* For normal root not-found and certain level of not-found boundary
they're still covered by `LayoutRouter`
* For other error renderings including not-found
* Fully remove the top level not-found boundary, when it renders with
404 error it goes to render the fallback page
* During rendering the fallback page it will check if it should just
renders a 404 error page or render nothing and let the error from inline
flight data to trigger the error boundary

pseudo code
```
try {
  render AppRouter > PageComponent
} catch (err) {
  create ErrorComponent by determine err
  render AppRouter > ErrorComponent
}
```

In this way if the error is thrown from top-level like the page itself
or even from metadata, we can still catch them and render the proper
error page based on the error type.

The problematic is the HMR: introduces a new development mode meta tag
`<meta name="next-error">` to indicate it's 404 so that we don't do
refresh. This reverts the change brougt in #51637 as it will also has
the duplicated rendering problem for root layout if it's included in the
top level not found boundary.

Also fixes the root layout missing issue:

Fixes #52718
Fixes #52739

---------

Co-authored-by: Shu Ding <g@shud.in>
2023-07-20 14:12:06 -07:00
Tim Neutkens
5d06b79e92
Support scroll: false for Link component for app router (#51869)
### What

Support `scroll={false}` for Link component in app router. This can be
used when you don't need to scroll back to top again when route url
changes. For instance hash query changes, if you want to keep the
scrolling as it is, you can use this option.

### How

Handling the `scroll` option in navigation reducer on client side.  

Fixes #50105
Fixes NEXT-1377

---------

Co-authored-by: Jiachi Liu <inbox@huozhi.im>
2023-07-04 10:25:25 +02:00
Zack Tanner
3427d324d8
fix: app router hash scrolling should respect scroll-padding (#51268)
When navigating to a route with a hash parameter, the layout router
jumps to the element by scrolling to the node's `offsetTop` value.
However, this will ignore `scroll-padding`, which deviates from browser
behavior.

It looks like this isn't an issue in the pages router which currently
makes use of
[`scrollIntoView`](https://github.com/vercel/next.js/blob/canary/packages/next/src/shared/lib/router/router.ts#L2262).

Closes NEXT-1171
Fixes #49612

---------
2023-06-13 20:50:51 -07:00
Jiachi Liu
8a11835fbe
Strip _rsc query for navigation between app and page (#51195)
Fix a missing case from #50970

When navigating from app to page, the `_rsc` query should still be stripped
2023-06-12 20:36:36 +00:00
Jiachi Liu
aa3e043bbf
Add unique search query for RSC requests to be cacable on CDN (#50970)
Adding a `_rsc` query for RSC payload requests so that they can be
differentiated on resources level for CDN cache for the ones that didn't
fully respect to VARY header.

Also stripped them for node/edge servers so that they won't show up in
the url

x-ref:
https://github.com/vercel/next.js/pull/49140#issuecomment-1549405009

Closes #49140
Closes NEXT-1268
2023-06-12 11:52:36 +02:00
Jiachi Liu
f19b31ad93
Fix rsc payload fetch failures due to state tree encoding (#51017)
Encode the state tree where the content could contain unicode when
request the RSC payload, to avoid the fetch failure due to bad encoding
for headers

Fixes #48728
fix NEXT-1258
2023-06-09 12:06:00 +02:00
Keyan Zhang
8e202610a4
App Router: fix relative query/hash handling in next/link and router push/replace (#49521)
## Problem
Relative hash/query handling in `next/link` (e.g. `<Link
href="#hello">`) is broken in App Router, especially if you're on a
nested route.

This wasn't a problem in `/pages` because the href always get fully
resolved in `<NextLink>`; i.e. if you have `<Link href="#hash" />` on
`/hello`, it'll resolve the href to `/hello#hash` and use that
everywhere.

However, in App Router, `<Link>` no longer uses the current location to
resolve the href:
5451564f36/packages/next/src/client/link.tsx (L450-L457)

Therefore navigating with `new URL(href, location.origin)` will skip the
current path and always apply the relative hash/query to the _root_
route:
5451564f36/packages/next/src/client/components/app-router.tsx (L208-L215)

## Solution
Not 100% sure if this is the best solution, but since `app-router` is
already reading `window.location`, I'm using `location.href` as the base
URL to resolve the href.

I grep'd for `location.origin` and checked other callsites; seems like
only `app-router` deals with user specified hrefs.

Fixes https://github.com/vercel/next.js/issues/42157 &
https://github.com/vercel/next.js/issues/44139, and potentially
https://github.com/vercel/next.js/issues/48554 and
https://github.com/vercel/next.js/issues/22838

## Test Plan
```
pnpm testheadless test/e2e/app-dir/navigation
```

---------
2023-05-28 10:29:00 -07:00
Tim Neutkens
21e677e95b
Failing tests for 404 back/forward (#50047)
## What?

After landing #49855 I found a few more edge cases with not-found not
behaving as expected:
- When navigating directly to a not-found page (e.g. `/testabc`) the
error boundary would not reset as there were multiple levels being
triggered at the same time.
- When running in production navigating back/forward to the not found
page caused the page to become empty

Both issues are fixed by this PR. I've added tests for both.

## How?

- Ensures `asNotFound` is not set on the layout-router, it causes all
levels to trigger not-found, even though only app-router needs it
- Ensures navigations to 404 are always a mpaNavigation (browser
navigation) instead of trying to do a client-side navigation (mirrors
what we do in `pages`)

Fixes NEXT-1209
Fixes NEXT-1218
Fixes #49823

<!-- Thanks for opening a PR! Your contribution is much appreciated.
To make sure your PR is handled as smoothly as possible we request that
you follow the checklist sections below.
Choose the right checklist for the change(s) that you're making:

## For Contributors

### Improving Documentation or adding/fixing Examples

- The "examples guidelines" are followed from our contributing doc
https://github.com/vercel/next.js/blob/canary/contributing/examples/adding-examples.md
- Make sure the linting passes by running `pnpm build && pnpm lint`. See
https://github.com/vercel/next.js/blob/canary/contributing/repository/linting.md

### Fixing a bug

- Related issues linked using `fixes #number`
- Tests added. See:
https://github.com/vercel/next.js/blob/canary/contributing/core/testing.md#writing-tests-for-nextjs
- Errors have a helpful link attached, see
https://github.com/vercel/next.js/blob/canary/contributing.md

### Adding a feature

- Implements an existing feature request or RFC. Make sure the feature
request has been accepted for implementation before opening a PR. (A
discussion must be opened, see
https://github.com/vercel/next.js/discussions/new?category=ideas)
- Related issues/discussions are linked using `fixes #number`
- e2e tests added
(https://github.com/vercel/next.js/blob/canary/contributing/core/testing.md#writing-tests-for-nextjs
- Documentation added
- Telemetry added. In case of a feature if it's used or not.
- Errors have a helpful link attached, see
https://github.com/vercel/next.js/blob/canary/contributing.md



## For Maintainers

- Minimal description (aim for explaining to someone not on the team to
understand the PR)
- When linking to a Slack thread, you might want to share details of the
conclusion
- Link both the Linear (Fixes NEXT-xxx) and the GitHub issues
- Add review comments if necessary to explain to the reviewer the logic
behind a change

### What?

### Why?

### How?

Closes NEXT-
Fixes #

-->
2023-05-22 17:04:36 +02:00
Tim Neutkens
c2da56e194
Fix going back to page after applying hash link (#50006)
## What?

@steven-tey noticed that on upstash.com that scrolling to hash keeps
happening regardless of the hash being set:

- Open site
- Click `Pricing` which adds `#pricing` and scrolls to the
`id="pricing"`
- Click `About` 
- Click on the logo

You'll notice that navigating back to the homepage ends up scrolling to
the `id="pricing` instead of to the top of the page.

## How?

This happened because we didn't reset the `hashFragment` and
`segmentPaths` for scrolling when scroll was applied, which means it
would keep that value in the state and would be applied as such on
navigation.

This PR ensures that besides setting `apply` to `false` we also reset
the `hashFragment` and `segmentPaths`.

Fixes NEXT-1205

<!-- Thanks for opening a PR! Your contribution is much appreciated.
To make sure your PR is handled as smoothly as possible we request that
you follow the checklist sections below.
Choose the right checklist for the change(s) that you're making:

## For Contributors

### Improving Documentation or adding/fixing Examples

- The "examples guidelines" are followed from our contributing doc
https://github.com/vercel/next.js/blob/canary/contributing/examples/adding-examples.md
- Make sure the linting passes by running `pnpm build && pnpm lint`. See
https://github.com/vercel/next.js/blob/canary/contributing/repository/linting.md

### Fixing a bug

- Related issues linked using `fixes #number`
- Tests added. See:
https://github.com/vercel/next.js/blob/canary/contributing/core/testing.md#writing-tests-for-nextjs
- Errors have a helpful link attached, see
https://github.com/vercel/next.js/blob/canary/contributing.md

### Adding a feature

- Implements an existing feature request or RFC. Make sure the feature
request has been accepted for implementation before opening a PR. (A
discussion must be opened, see
https://github.com/vercel/next.js/discussions/new?category=ideas)
- Related issues/discussions are linked using `fixes #number`
- e2e tests added
(https://github.com/vercel/next.js/blob/canary/contributing/core/testing.md#writing-tests-for-nextjs
- Documentation added
- Telemetry added. In case of a feature if it's used or not.
- Errors have a helpful link attached, see
https://github.com/vercel/next.js/blob/canary/contributing.md



## For Maintainers

- Minimal description (aim for explaining to someone not on the team to
understand the PR)
- When linking to a Slack thread, you might want to share details of the
conclusion
- Link both the Linear (Fixes NEXT-xxx) and the GitHub issues
- Add review comments if necessary to explain to the reviewer the logic
behind a change

### What?

### Why?

### How?

Closes NEXT-
Fixes #

-->

---------

Co-authored-by: JJ Kasper <jj@jjsweb.site>
2023-05-18 16:33:58 -07:00
Tim Neutkens
babe50364e
Reset not-found and error boundary when navigating (#49855)
## What?

Currently the error boundary state does not reset when a navigation
happens because the `key` does not change. Because of that navigating
using next/link when the error boundary is in the open state ends up not
rendering the contents of the new navigation, instead it keeps the error
boundary contents.

## How?

This PR uses a pattern that is recommended in the React docs (setState
during render) to reset the error boundary if the `usePathname` value
has changed, it is used as a proxy for a new navigation.

Fixes #47862
Fixes NEXT-963
Fixes #49736
Fixes #49732
Fixes #49599


<!-- Thanks for opening a PR! Your contribution is much appreciated.
To make sure your PR is handled as smoothly as possible we request that
you follow the checklist sections below.
Choose the right checklist for the change(s) that you're making:

## For Contributors

### Improving Documentation or adding/fixing Examples

- The "examples guidelines" are followed from our contributing doc
https://github.com/vercel/next.js/blob/canary/contributing/examples/adding-examples.md
- Make sure the linting passes by running `pnpm build && pnpm lint`. See
https://github.com/vercel/next.js/blob/canary/contributing/repository/linting.md

### Fixing a bug

- Related issues linked using `fixes #number`
- Tests added. See:
https://github.com/vercel/next.js/blob/canary/contributing/core/testing.md#writing-tests-for-nextjs
- Errors have a helpful link attached, see
https://github.com/vercel/next.js/blob/canary/contributing.md

### Adding a feature

- Implements an existing feature request or RFC. Make sure the feature
request has been accepted for implementation before opening a PR. (A
discussion must be opened, see
https://github.com/vercel/next.js/discussions/new?category=ideas)
- Related issues/discussions are linked using `fixes #number`
- e2e tests added
(https://github.com/vercel/next.js/blob/canary/contributing/core/testing.md#writing-tests-for-nextjs
- Documentation added
- Telemetry added. In case of a feature if it's used or not.
- Errors have a helpful link attached, see
https://github.com/vercel/next.js/blob/canary/contributing.md



## For Maintainers

- Minimal description (aim for explaining to someone not on the team to
understand the PR)
- When linking to a Slack thread, you might want to share details of the
conclusion
- Link both the Linear (Fixes NEXT-xxx) and the GitHub issues
- Add review comments if necessary to explain to the reviewer the logic
behind a change

### What?

### Why?

### How?

Closes NEXT-
Fixes #

-->
2023-05-18 22:06:57 +02:00
Tim Neutkens
25a9547cad
Remove experimental config from create-next-app (#49241)
## What?

Removes `experimental.appDir` this was leftover from when I flipped the
switch.

Kept the config file as in the future we might add future flags and
such. It also helps that it has the types comment included so you always
get types.

<!-- Thanks for opening a PR! Your contribution is much appreciated.
To make sure your PR is handled as smoothly as possible we request that
you follow the checklist sections below.
Choose the right checklist for the change(s) that you're making:

## For Contributors

### Improving Documentation or adding/fixing Examples

- The "examples guidelines" are followed from our contributing doc
https://github.com/vercel/next.js/blob/canary/contributing/examples/adding-examples.md
- Make sure the linting passes by running `pnpm build && pnpm lint`. See
https://github.com/vercel/next.js/blob/canary/contributing/repository/linting.md

### Fixing a bug

- Related issues linked using `fixes #number`
- Tests added. See:
https://github.com/vercel/next.js/blob/canary/contributing/core/testing.md#writing-tests-for-nextjs
- Errors have a helpful link attached, see
https://github.com/vercel/next.js/blob/canary/contributing.md

### Adding a feature

- Implements an existing feature request or RFC. Make sure the feature
request has been accepted for implementation before opening a PR. (A
discussion must be opened, see
https://github.com/vercel/next.js/discussions/new?category=ideas)
- Related issues/discussions are linked using `fixes #number`
- e2e tests added
(https://github.com/vercel/next.js/blob/canary/contributing/core/testing.md#writing-tests-for-nextjs
- Documentation added
- Telemetry added. In case of a feature if it's used or not.
- Errors have a helpful link attached, see
https://github.com/vercel/next.js/blob/canary/contributing.md



## For Maintainers

- Minimal description (aim for explaining to someone not on the team to
understand the PR)
- When linking to a Slack thread, you might want to share details of the
conclusion
- Link both the Linear (Fixes NEXT-xxx) and the GitHub issues
- Add review comments if necessary to explain to the reviewer the logic
behind a change

### What?

### Why?

### How?

Closes NEXT-
Fixes #

-->

---------

Co-authored-by: JJ Kasper <jj@jjsweb.site>
2023-05-05 00:22:28 -07:00
Shu Ding
e7a233293a
Fix flaky test (#49178)
Found this one being a bit random during dev, but it's trivial. See discussions: https://github.com/vercel/next.js/pull/49168#issuecomment-1533788373
2023-05-03 23:25:46 +00:00
Shu Ding
248f2defc2
Fix React channel env missing in custom server (#49168)
Fixes #48948
([repro](https://github.com/vercel/next.js/issues/48948#issuecomment-1533542001)).
When running inside a custom server with app dir, we should always opt
into the prebundled React with correct channels.

Thanks @karlhorky for help testing it!

Fixes #49169 too.

---------

Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2023-05-04 00:40:23 +02:00
Sophie Alpert
05cd5157e5
app router: Fix infinite redirect loop in MPA navigation (#49058)
Not 100% convinced that this is the correct fix but it's the best I can
think of.

Previously, we would sometimes call location.assign()/.replace()
hundreds of times (or more) as I described in
https://github.com/vercel/next.js/issues/48438 and
https://github.com/vercel/next.js/issues/48309#issuecomment-1512290958.
Sometimes this would just make things slow but the navigation would
eventually succeed; sometimes this would just hang the browser.

Now we trigger it only once (or—for a reason I don't quite
understand—twice in dev, as you can see in the test) and never commit
that render.

This also fixes the bug I mentioned in
https://github.com/vercel/next.js/issues/48438#issuecomment-1528649776
where usePathname() and useSearchParams() would return the page we are
navigating to (even if that's an external page wholly unrelated to our
site!).

Fixes #48309, fixes #48438.

link NEXT-1028

Co-authored-by: Jimmy Lai <laijimmy0@gmail.com>
2023-05-03 11:04:53 +02:00
Tim Neutkens
37f709eeb7
Investigate redirect getting stuck (#48343)
### What?

Fixes a bug where `fetch()` to a page that calls `redirect()` would hang
infinitely.

### How?

The `Location` header was missing. The reason this wasn't surfaced
before is that we also inject the `<meta>` tag to redirect which the
browser would pick up to redirect too.

Fixes NEXT-997

<!-- Thanks for opening a PR! Your contribution is much appreciated.
To make sure your PR is handled as smoothly as possible we request that
you follow the checklist sections below.
Choose the right checklist for the change(s) that you're making:

## For Contributors

### Improving Documentation or adding/fixing Examples

- The "examples guidelines" are followed from our contributing doc
https://github.com/vercel/next.js/blob/canary/contributing/examples/adding-examples.md
- Make sure the linting passes by running `pnpm build && pnpm lint`. See
https://github.com/vercel/next.js/blob/canary/contributing/repository/linting.md

### Fixing a bug

- Related issues linked using `fixes #number`
- Tests added. See:
https://github.com/vercel/next.js/blob/canary/contributing/core/testing.md#writing-tests-for-nextjs
- Errors have a helpful link attached, see
https://github.com/vercel/next.js/blob/canary/contributing.md

### Adding a feature

- Implements an existing feature request or RFC. Make sure the feature
request has been accepted for implementation before opening a PR. (A
discussion must be opened, see
https://github.com/vercel/next.js/discussions/new?category=ideas)
- Related issues/discussions are linked using `fixes #number`
- e2e tests added
(https://github.com/vercel/next.js/blob/canary/contributing/core/testing.md#writing-tests-for-nextjs
- Documentation added
- Telemetry added. In case of a feature if it's used or not.
- Errors have a helpful link attached, see
https://github.com/vercel/next.js/blob/canary/contributing.md



## For Maintainers

- Minimal description (aim for explaining to someone not on the team to
understand the PR)
- When linking to a Slack thread, you might want to share details of the
conclusion
- Link both the Linear (Fixes NEXT-xxx) and the GitHub issues
- Add review comments if necessary to explain to the reviewer the logic
behind a change

### What?

### Why?

### How?

Closes NEXT-
Fixes #

-->
2023-04-13 16:17:15 -07:00
Jiachi Liu
dcc0ef8e47
Hide not ENOENT errors for not found in ipc server (#47854)
Not to log not found errors created from on demand handlers in ipc
server

Remove the not found error trace for dev
```
event - compiled client and server successfully in 57 ms (265 modules)
/Users/huozhi/workspace/next.js/packages/next/src/server/dev/on-demand-entry-handler.ts:450
    throw new PageNotFoundError(normalizedPagePath)
          ^

Error: Cannot find module for page: /not-found
    at findPagePathData (/Users/huozhi/workspace/next.js/packages/next/src/server/dev/on-demand-entry-handler.ts:450:11)
    at Object.ensurePage (/Users/huozhi/workspace/next.js/packages/next/src/server/dev/on-demand-entry-handler.ts:701:30)
    at Server.<anonymous> (/Users/huozhi/workspace/next.js/packages/next/src/server/lib/server-ipc.ts:29:24) {
  code: 'ENOENT'
}
```
2023-04-04 11:46:49 -07:00
Jiachi Liu
5c6b8ac3f2
Fix flaky css test and remove unused tests deps (#47806)
* use `check` to wait for css change
* remove unused swr deps and update them to latest
* remove swr esm test in `app-dir/app/` since it's already covered in
`app-dir/app-external/`

---------
2023-04-01 16:58:32 -07:00
Jiachi Liu
2d796ed594
Fix duplicated default metadata tags (#47690)
Adding default metadata before causes duplicated metadata tags when
adding server inserted html. Remove the ones in the not found boundary
Now we use same way to render metadata to render the default metadata in
error html

Fixes the issue introduced in #47404

---------

Co-authored-by: JJ Kasper <jj@jjsweb.site>
2023-03-30 17:17:52 -07:00
Jiachi Liu
de92781145
Add default meta tags to error page (#47404)
Default tags of `charset` and `viewport` should also be rendered in app
router error pages like not found pages.

Closes NEXT-869

This PR:
* Extract not found boundary to single component
* Add the default tags to `NotFoundErrorBoundary` rendering
* Fix duplicated `noindex` tag for streaming error rendering
2023-03-22 22:44:45 +01:00
Shu Ding
51b1fe3d2f
Emit late streaming meta tags (#47207)
Currently if `notFound()` or `redirect()` is called when the shell was already sent out, we can no longer change the status code and head tags. In that case we inject these specific meta tags into the HTML stream so specific agents can read them.

fix NEXT-220 ([link](https://linear.app/vercel/issue/NEXT-220))
2023-03-17 14:37:00 +00:00
Tim Neutkens
e6bca73d87
Add support for scrolling to hash fragment (#46995)
Adds support for scrolling based on the [hash
fragment](https://en.wikipedia.org/wiki/URI_fragment) in client-side
navigations for the App Router, mirroring browser behavior.

- `#main-content` → scrolls to `id="main-content"` or
`name="main-content"` property
- `#top` → scrolls to the top of the page, this is a special case in
browsers.
- no hash → default scroll behavior, layout that changed

Fixes NEXT-658

<!-- Thanks for opening a PR! Your contribution is much appreciated.
To make sure your PR is handled as smoothly as possible we request that
you follow the checklist sections below.
Choose the right checklist for the change(s) that you're making:

## For Contributors

### Improving Documentation or adding/fixing Examples

- The "examples guidelines" are followed from our contributing doc
https://github.com/vercel/next.js/blob/canary/contributing/examples/adding-examples.md
- Make sure the linting passes by running `pnpm build && pnpm lint`. See
https://github.com/vercel/next.js/blob/canary/contributing/repository/linting.md

### Fixing a bug

- Related issues linked using `fixes #number`
- Tests added. See:
https://github.com/vercel/next.js/blob/canary/contributing/core/testing.md#writing-tests-for-nextjs
- Errors have a helpful link attached, see
https://github.com/vercel/next.js/blob/canary/contributing.md

### Adding a feature

- Implements an existing feature request or RFC. Make sure the feature
request has been accepted for implementation before opening a PR. (A
discussion must be opened, see
https://github.com/vercel/next.js/discussions/new?category=ideas)
- Related issues/discussions are linked using `fixes #number`
- e2e tests added
(https://github.com/vercel/next.js/blob/canary/contributing/core/testing.md#writing-tests-for-nextjs
- Documentation added
- Telemetry added. In case of a feature if it's used or not.
- Errors have a helpful link attached, see
https://github.com/vercel/next.js/blob/canary/contributing.md



## For Maintainers

- Minimal description (aim for explaining to someone not on the team to
understand the PR)
- When linking to a Slack thread, you might want to share details of the
conclusion
- Link both the Linear (Fixes NEXT-xxx) and the GitHub issues
- Add review comments if necessary to explain to the reviewer the logic
behind a change

### What?

### Why?

### How?

Closes NEXT-
Fixes #

-->

fixes #44295

---------

Co-authored-by: JJ Kasper <jj@jjsweb.site>
2023-03-14 13:17:10 +01:00
Jiachi Liu
ab123c1e7c
Add test for next-found and redirect for metadata (#46248)
Add tests for using `redirect` and `notFound` in `generateMetadata`
2023-02-22 18:54:14 +01:00
Hannes Bornö
8fb2f59169
Add status code to app-render redirect response (#45846) 2023-02-13 14:12:16 +01:00
Jiachi Liu
484f4724f4
Separate navigation and hooks tests into new test suites (#45766)
Moving tests to reduce app-dir/app/index.test.ts running duration
2023-02-10 00:38:39 +00:00