### What?
Adds the error boundary used to catch `redirect()` above the root
layout.
### Why?
Currently calling `redirect()` in the root layout causes `NEXT_REDIRECT`
to bubble up to the error boundary because we didn't have a
redirect-boundary above the place where the root layout is rendered
client-side.
### How?
- Moved redirect-boundary into a separate file
- Added redirect-boundary around the `cache.subTreeData` in app-router
(around the root layout)
fix NEXT-315 ([link](https://linear.app/vercel/issue/NEXT-315))
Fixes#42556
I've verified the reproduction shown in #42556 has been fixed earlier,
there was another report about calling `redirect()` in the root layout
and that's what this PR fixes.
Since that issue has many comments here's some additional context:
- `redirect()` can only be called during React component rendering.
- This means you can't run `redirect()` in `onClick` or `useEffect()`
handlers.
- Calling `redirect()` in a server component or during prerendering of
client components it will add the right meta tag to trigger a redirect
- `<meta httpEquiv="refresh" content={`0;url=${redirectUrl}`}>`
- Because of streaming rendering by the time your code runs the browser
will have already received the start of the stream and headers will have
been sent, as such you can't modify the headers, hence why the meta tag
is used instead of `location`.
- Calling `redirect()` in client components is supported while
rendering, e.g. if you have a condition:
```tsx
'use client'
import { useState } from 'react'
import { redirect } from 'next/navigation'
export function ClientComponent() {
const [clicked, setClicked] = useState()
if(clicked) {
redirect('/another-page')
}
return <>
<button onClick={() => setClicked(true)}>Click to redirect</button>
</>
}
```
<!-- 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: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
This marks all pages in development as supporting dynamic HTML. Detection for runtime violations of dynamic generation is completed during the production build.
Fixes#46356
fix NEXT-644 ([link](https://linear.app/vercel/issue/NEXT-644))
Co-authored-by: Tim Neutkens <6324199+timneutkens@users.noreply.github.com>
Co-authored-by: JJ Kasper <22380829+ijjk@users.noreply.github.com>
We shouldn't detect icon/og/etc. metadata image convention as image dynamic routes under `pages/` dir, they should be only apply in `app/` dir. This PR changed the normalization rule that we only apply them when page is from `app/`. So when you're using `icon.js` under `pages/` it won't get effected.
We introduced static route `robots.txt` and dynamic route `robots.js` for metadata, it should still allow users to create their own customized version. This issue is caused by a route conflicts. Only append `/route` to page path when there's not ending with `/route`
Fixes#47198
Closes NEXT-850
When a user exports a default function from a `route.ts` file, they may
think that this would be handled in the same way that our `pages/api/`
routes handled it. App Routes require an exported function for each HTTP
method instead.
This adds warnings to the development console when a user provides a
default export (or no HTTP method at all).
Future ideas:
- Error during production build when these conditions are met
fix#46375
fix NEXT-660 ([link](https://linear.app/vercel/issue/NEXT-660))
---------
Co-authored-by: JJ Kasper <jj@jjsweb.site>
### What?
Makes searchParams part of the cache key for dynamic rendering
responses.
### Why?
Current the cache key only includes the pathname and not the
searchParams. This causes issues in a few cases:
- Navigation to `/dashboard` then clicking a link to
`/dashboard?sort=asc` works, but then when navigating back the cache
node for `/dashboard?sort=asc` is used instead of the content for
`/dashboard`.
- Navigation between different searchParams always had to be a hard
navigation as reusing a cache node would result in the wrong result.
### How?
Changed the leaf node's name from `''` to `'__PAGE__'` so that it can be
distinguished. Then used that `__PAGE__` marker to include the
searchParams into the cache key for that leaf node in all places it's
used.
Ideally the `__PAGE__` key becomes something that can't be addressed in
the pathname, since it still has to be serializable I'm thinking a
number would be best.
Given that the server just provides the cache key and the client only
reasons about rendering the tree the current approach of stringifying
the searchParams and making that part of the cache key could be replaced
with a hash of the stringified result instead.
fix NEXT-685 ([link](https://linear.app/vercel/issue/NEXT-685))
Fixes#45026
Fixes NEXT-688
Fixes#46503
This ensures revalidate can be fetch specific instead of cache key
specific and adds a test case to ensure config based revalidate isn't
overridden by fetch based revalidate.
* Add `manifest.webmanifest` and `manifest.(j|t)xs?` support for
manifest.json route
* Add `Manifest` type for it for autocomplete purpose.
Remove the exports for `SitemapFile` and `RobotsFile` globally, will
discuss how to re-export them with better naming later
Small fix for `Robots` typing, should allow `string | string[]` for user
agent of single Robots
Closes NEXT-839
---------
This serves to correct a specific issue related to multiple locales being specified in the pathname as well as some general i18n improvements.
- Multiple locales are now parsed correctly (only taking the first locale, treating the rest of the string as the pathname)
- `LocaleRouteNormalizer` has been split into `I18NProvider` and `LocaleRouteNormalizer` (tests added)
- Adjusted the `I18NProvider.analyze` method (previously `LocaleRouteNormalizer.match`) to require the `defaultLocale: string | undefined` to ensure consistent behaviour
- Added more comments around i18n
Currently all import CSS resources, including CSS modules, are imported lazily. This means that they can't be chunked as by definition of "lazy" they can be loaded separately.
This PR changes it to always use "eager" so if they're in the same entry, these CSS resources can be chunked together and reduce the total amount of requests. However the downside will be tree shaking, as not all modules in a chunk are used by one entry. Two entries can only share a part of it.
Since CSS modules won't have side effects this should be a good trade off.
## Bug
- [ ] Related issues linked using `fixes #number`
- [x] Integration tests added
- [ ] Errors have a helpful link attached, see [`contributing.md`](https://github.com/vercel/next.js/blob/canary/contributing.md)
## Feature
- [ ] Implements an existing feature request or RFC. Make sure the feature request has been accepted for implementation before opening a PR.
- [ ] Related issues linked using `fixes #number`
- [ ] [e2e](https://github.com/vercel/next.js/blob/canary/contributing/core/testing.md#writing-tests-for-nextjs) tests added
- [ ] Documentation added
- [ ] Telemetry added. In case of a feature if it's used or not.
- [ ] Errors have a helpful link attached, see [`contributing.md`](https://github.com/vercel/next.js/blob/canary/contributing.md)
## Documentation / Examples
- [ ] Make sure the linting passes by running `pnpm build && pnpm lint`
- [ ] The "examples guidelines" are followed from [our contributing doc](https://github.com/vercel/next.js/blob/canary/contributing/examples/adding-examples.md)
Co-authored-by: JJ Kasper <22380829+ijjk@users.noreply.github.com>
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))
Generated metadata icons through api routes instead of using webpack
emitting file. Each metadata image file will go through
`next-metadata-image-loader` to get the image basic info, and then it
will go through `next-metadata-route-loader` to be converted as a
routes.
Related to NEXT-264
Closes NEXT-810
When calling the server (via `callServer`), we concat all closure values
(`$$bound`) and arguments of the function call into one array on the
client. Hence on the server, we will have to compile the function
differently to support that.
With this change, the compiled function will have a `$$with_bound` flag
to indicate that if it accepts closure values. If so, the only argument
passed will be an array like `[...bound_values, ...fn_args]`, and we
compile the function parameters to `(closure, arg1 = closure[N], arg2 =
closure[N + 1], ...)` where `N` is the number of the closure
identifiers. This way we can still fill these arguments by only pass an
"bound + args" array. If it doesn't accept closure values, it will be
directly called with `...fn_args` so no compilation change needed.
The reason that we use `arg1 = closure[N]` is that this can support
complex patterns in parameters such as `f(closure, {a} = closure[1], [b]
= closure[2])`.
fix NEXT-487 ([link](https://linear.app/vercel/issue/NEXT-487))
Ensures that using `searchParams` opts into dynamic rendering.
Fixes#43077
fix NEXT-601 ([link](https://linear.app/vercel/issue/NEXT-601))
<!--
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:
-->
## Bug
- [ ] Related issues linked using `fixes #number`
- [ ] Integration tests added
- [ ] Errors have a helpful link attached, see
[`contributing.md`](https://github.com/vercel/next.js/blob/canary/contributing.md)
## Feature
- [ ] Implements an existing feature request or RFC. Make sure the
feature request has been accepted for implementation before opening a
PR.
- [ ] Related issues linked using `fixes #number`
- [ ]
[e2e](https://github.com/vercel/next.js/blob/canary/contributing/core/testing.md#writing-tests-for-nextjs)
tests added
- [ ] Documentation added
- [ ] Telemetry added. In case of a feature if it's used or not.
- [ ] Errors have a helpful link attached, see
[`contributing.md`](https://github.com/vercel/next.js/blob/canary/contributing.md)
## Documentation / Examples
- [ ] Make sure the linting passes by running `pnpm build && pnpm lint`
- [ ] The "examples guidelines" are followed from [our contributing
doc](https://github.com/vercel/next.js/blob/canary/contributing/examples/adding-examples.md)
x-ref: [slack
thread](https://vercel.slack.com/archives/C03S8ED1DKM/p1678838567947919)
Follow-up to https://github.com/vercel/next.js/pull/46317. The issue is
that, if:
- `experimental.clientRouterFilter` is enabled
- `i18n` is enabled with `defaultLocale` set
- Next.js router navigates to a path that (1) is the same as
`defaultLocale` and (2) will be redirected,
then:
- **Expected:** Should hard-navigate to this path without any locale
prefix (and then redirect occurs)
- **Actual:** Hard-navigates to this path with `defaultLocale` prefix,
even though it's not needed (and then redirect occurrs)
### Solution
This PR fixes the above issue by adding `defaultLocale` to `addLocale`
which is passed to `handleHardNavigation`. [`addLocale` skips adding the
locale if `locale` is equal to
`defaultLocale`](02125cf3b1/packages/next/src/shared/lib/router/utils/add-locale.ts (L17)).
### Fixing a bug
- [x] Related issues linked using `fixes #number`
- [x] Tests added. See:
https://github.com/vercel/next.js/blob/canary/contributing/core/testing.md#writing-tests-for-nextjs
Co-authored-by: JJ Kasper <jj@jjsweb.site>
In short, this PR adds a 3rd layer to the server compiler. This extra
layer is for marking the modules when re-entering the server layer from
a client component. It is almost identical to the existing server layer
and it should have all the same bundling and runtime behaviors, but it's
still special because it's not allowed to enter the client layer again
from there.
Because of that, we create the extra entry for that new layer when the
client layer compilation finishes in the `finishModules` phase. The new
entry is handled normally as it's in the server layer. But the original
module in the client layer will be compiled specially as special no-op
exports, and will then be connected via the `callServer` wrapper.
fix NEXT-809 ([link](https://linear.app/vercel/issue/NEXT-809)).
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>
This moves the position of action handling so it can continue page
rendering afterwards. And a `asNotFound` option is added to
`LayoutRouter` to indicate the router to opt into the root not-found
boundary, so not found pages can be programmatically rendered instead of
relying on route mismatching (this is also needed by NEXT-463 later).
Fixes NEXT-467.
Support top-level `robots.[ext]` and `sitemap.[ext]` with dynamic api
routes
* Use isAppRoute to determine api routes and metadata routes as metadata
routes are normalized as `<metadata>/route`
* Normalize path to auto append extension to pathname for sitemap.js and
robots.js
* Add typings `SitemapFile` and `RobotsFile`
* move the normalize logic together, reuse the `absolutePathToPage`.
Changes less when touching both dev-server/hot-reloader and next-server,
use the same utils to handle paths
Closes NEXT-262
---------
This PR implements the route announcer for app directory. It almost uses
the same logic as the route announcer inside pages, with one notable
difference that the inner content node is now inside a shadow root. This
makes sure that it does as little impact as possible, to the
application. This is important as we no longer have the `__next`
wrapper.
Another thing worth mentioning is that the announced title is a global
singleton of the website. It shouldn't be affected by the concept of
layouts, but should be triggered when the router state (not just URL)
changes.
Closes NEXT-208.
---------
Co-authored-by: JJ Kasper <jj@jjsweb.site>
Set the output bundle file path to `/<metadata route>/route.js` to align with other custom app routes, in order to make it easier being handled by app routes in both nextjs and vercel
Generate `/favicon.ico` route when favicon.ico is placed into `app/`.
Still collect favicon metadata image information through
metadata-image-loader but don't emit the file to static dist anymore.
Also collect favicon through metadata routes, and render it as static
routes. Also remove the `hash` we generated before, not needed anymore.
Change metadata static routes rendering process: collect static metadata
assets, read the buffer of the file data and return it in the response.
Closes NEXT-791
This PR adds Zod to the precompiled libraries, and use it to create schemas for the router state tree for validation. In other planned features/changes, Zod will also be used to do run-time data validation.
Fixes NEXT-135.
Support top level static `robots.txt` and `sitemap.xml` as metadata
route in app directory. When those files are placed in top root
directory
Refactored a bit the page files matching logic, to reuse it between dev
server and build
Closes NEXT-267
This ensures we leverage the fetch cache when calling
`generateStaticParams` and also ensures paths with
`generateStaticParams` without `dynamicParams = false` don't error when
only partial params are provided.
x-ref: [slack
thread](https://vercel.slack.com/archives/C035J346QQL/p1678149362238089)
Add unique identifier `@app@` / `@pages@` / `@root@` for entry key of on
demand entries, so that they'll be unique for each path when the page
key is similar bewteen app and pages like (`"app/page"` and
`"pages/page"` will both end up with `/page`)
## Bug
Follow up for #46736
Closes NEXT-472
- [x] Related issues linked using `fixes #number`
- [x] Integration tests added
- [ ] Errors have a helpful link attached, see
[`contributing.md`](https://github.com/vercel/next.js/blob/canary/contributing.md)
---------
This PR adds the support for unnamed default export expression support
`export default async function () {}` in a "use server" entry, with
corresponding test.
Also fixed an existing bug that the default exported action's name
should be aligned with the export name, which is `"default"`.
Closes NEXT-769.
This updates to no longer skip caching POST or authed requests with the
fetch cache and instead we bail when `cookies()` or `headers()` is used
prior which is a better heuristic to signal user specific data would be
related to the fetch request.
x-ref: [slack
thread](https://vercel.slack.com/archives/C042LHPJ1NX/p1678130069138849)
## Bug
- [x] Related issues linked using `fixes #number`
- [x] Integration tests added
- [ ] Errors have a helpful link attached, see
[`contributing.md`](https://github.com/vercel/next.js/blob/canary/contributing.md)
Turbopack uses a different format for its css module classnames [0].
This adds and uses a helper function to the next-font tests to assert
against these classnames when testing with Turbopack. Ideally these
tests could be more behavioral (e.g. asserting on rendered dimensions),
but these can't capture things like fallback fonts.
[0] https://github.com/vercel/turbo/pull/3437
Since we have 2 server compilers (node and edge), the `serverActions`
object will always get overridden by the second compilation during `next
build`. Like the client reference manifest, we need to have 2 objects
for each compiler and merge them when outputting the asset.
Besides that, to avoid `export default` being tree-shaken as unused
export, I changed the loader to use CJS `module.exports` instead. Can't
easily figure out a proper way for now but we plan to create separate
worker for the action endpoint and this will be gone then.
Fixes NEXT-759, read NEXT-761 for the full future plan.
## Bug
- [ ] Related issues linked using `fixes #number`
- [x] Integration tests added
- [ ] Errors have a helpful link attached, see
[`contributing.md`](https://github.com/vercel/next.js/blob/canary/contributing.md)
## Feature
- [ ] Implements an existing feature request or RFC. Make sure the
feature request has been accepted for implementation before opening a
PR.
- [ ] Related issues linked using `fixes #number`
- [ ]
[e2e](https://github.com/vercel/next.js/blob/canary/contributing/core/testing.md#writing-tests-for-nextjs)
tests added
- [ ] Documentation added
- [ ] Telemetry added. In case of a feature if it's used or not.
- [ ] Errors have a helpful link attached, see
[`contributing.md`](https://github.com/vercel/next.js/blob/canary/contributing.md)
## Documentation / Examples
- [ ] Make sure the linting passes by running `pnpm build && pnpm lint`
- [ ] The "examples guidelines" are followed from [our contributing
doc](https://github.com/vercel/next.js/blob/canary/contributing/examples/adding-examples.md)
Use some utils to match multiple dom nodes together
#### Match multiple props for single DOM node
```tsx
const matchDom = createDomMatcher(browser)
await matchDom('meta', 'name="description"', { content: 'description' })
```
#### Match multiple same pattern DOM nodes in html
```tsx
const $ = await next.render$('html')
const matchHtml = createHtmlMatcher($)
await matchHtml('meta', 'name', 'property', {
description: 'description',
og: 'og:description'
})
```
#### Match same pattern DOM nodes in browser after hydration
```tsx
const matchMultiDom = createMultiDomMatcher(browser)
await matchMultiDom('meta', 'property', 'content', {
description: 'description',
'og:title': 'title',
'twitter:title': 'title'
})
```