This enhances the current parsing completed by Next.js of configuration
from app segments. Previously a collection of fragile checks was used to
parse the different segment configuration options which performed no
validation on the inputs.
This uses the `zod` library (which we already use internally) to perform
validation on the configuration exported. A followup PR #70480 will add
more verbose error logging around the validation errors.
## Story Time
Metadata API introduced two exports `metadata` and `generateMetadata` to the pages and layouts under app router, as partial prerendering work is going on and people are desiring to render the metadata asynchronizly, this change will be the preparation for moving to the dynamic & asynchronized land. In short, if we can render the metadata asynchronizedly, it will benefit the performance of the initial page loading and client page transiation a lot. Any slow data fetching can be handled while the essential page "shell" is rendered.
For meta tags, there're few ones will visually affect your web page, such as `<meta name="viewport">`, `<meta name="theme color">` and `<meta name="color-scheme">`, rendering them lately after the page frame is ready might bring flickering to the page such as revreting whole page's theme color or shaking due to viewport updates. Those meta are not majorly the "metadata" for SEO, but more for user experience when opening the page. If we're rendering everything as async meta tags, it won't be ideal due to the flickering on your web pages.
## Solution Preparation
We'll want to render the meta tags separately to make sure the visual ones are rendered as blocking along with web page, and then the ones for SEO or bots can be flushed later by later, like a suspense boundary keeps emitting them into the head of html.
We optionally picked up 3 meta tag "viewport", "theme-color" and "color-scheme" to be render first into the web page with html "shell", to guarantee the layout viewport and basic styling are rendered first.
This PR introduced two module export in the page and layout files: `viewport` and `generateViewport`, in order to separate the visual meta tags from the SEO metadata.
### API
```ts
// page.js | layout.js
export const viewport = {
// viewport meta tag
width: 'device-width',
initialScale: 1,
maximumScale: 1,
interactiveWidget: 'resizes-visual',
// visual meta tags
colorScheme: 'dark',
themeColor: { color: 'cyan', media: '(prefers-color-scheme: dark)' },
}
```
There's also a dynamic API like what we did for metadata API
```ts
// page.js | layout.js
export function generateViewport() {
return { ... }
}
```
## Notice
This PR won't get SEO metadata rendered asyncronizedly, instead it's a preparation for the later work in partial prerendering and async metadata. We'll encourage the Next.js community moving to the new metadata viewport API if you're customzing those 3 meta tags. Usually you don't have to change viewport itself, so mostly like only theme-color and color-scheme could relate to it.
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
---------
### Issue
x-ref:
https://github.com/vercel/next.js/actions/runs/5469070005/jobs/9957658991?pr=52282#step:27:526
metadata tests are failing as flaky recently, then after digging into
it, noticed it as a hmr issue.
**Steps to repro with metadata test app**
The later (after the 1st one) visited page with client components
imports sometimes throw an full reload refresh warning
> Fast Refresh will perform a full reload when you edit a file that's
imported by modules
outside of the React rendering tree.
Turns out there's some unexpected hmr events when `"sync"` event is
triggered, and client tries to apply the updates but then failed. This
PR excludes the triggering by `"sync"` for RSC pages updates. `'sync'`
event with errors/warnings will still be handled and then `'built'`
event will be handled with hot reload updates
Possibly related to #40184
Seems edge runtime started failing for app paths from `path` being added
in https://github.com/vercel/next.js/pull/47829 so this updates to use
the isomorphic version instead and adds a regression test.
Fixes NEXT-866