Discovered while working on https://github.com/vercel/next.js/pull/14848
when asPath is the same but href is different it should use `replaceState` instead of `pushState`, so that browser back/forward behavior is preserved. Currently it's comparing a path that includes basepath with one that excludes it, so `pushState` is always used. This makes sure the behavior is the same as when running next.js without a basepath
Currently following links are broken when using `basePath`:
```jsx
// pages/hello.js
<Link href="#hashlink">
<a id="hashlink">Hash Link</a>
</Link>
```
with `basePath: '/docs'`, this will navigate to `/docs/docs/hello#hashlink` instead of `/docs/hello#hashlink`
I have a further optimization that builds on this branch that removes `url.parse` and `url.resolve` in favor for `new URL()` in router and link. Will PR when this gets merged.
Fast Refresh doesn't appear to work with older version (16.8.x) versions of React. I was able to reproduce this via this issue https://github.com/vercel/next.js/issues/14895
I updated all examples I found of React `16.8.x` to `^16.13.1` so that future installs will auto bump to the latest minor version. Previously the pinned version was causing the lock of version.
This updates the scroll position saving to occur as the scroll position changes instead of trying to do it when the navigation is changing since the `popState` event doesn't allow us to update the leaving history state once the `popState` has occurred.
The order of events that was previously attempted to save scroll position on a `popState` event (back/forward navigation)
1. history.state is already updated with state from `popState`
2. we replace state with the currently rendered page adding scroll info
3. we replace state again with the `popState` event state overriding scroll info
Using this approach the above event order is no longer in conflict since we don't attempt to populate the state with scroll position while it's leaving the state and instead do it while it is still the active state in history
This approach resembles existing solutions:
https://www.npmjs.com/package/scroll-behaviorhttps://twitter.com/ryanflorence/status/1029121580855488512
Fixes: https://github.com/vercel/next.js/issues/13990Fixes: #12530
x-ref: https://github.com/vercel/next.js/pull/14075
Fixes: #13512
Defined and exported type for `metric` used in [reportWebVitals](https://nextjs.org/docs/advanced-features/measuring-performance)
```
export function reportWebVitals(metric) {
if (metric.label === 'custom') {
console.log(metric) // The metric object ({ id, name, startTime, value, label }) is logged to the console
}
}
```
One can now do
```
import { NextWebVitalsMetric } from 'next/app'
export function reportWebVitals(metric: NextWebVitalsMetric ) {
if (metric.label === 'custom') {
console.log(metric) // The metric object ({ id, name, startTime, value, label }) is logged to the console
}
}
```
Convert `Link` to a function component. Prefetch logic and memoized url formatting now meshes nicely with React hooks. Class methods were hoisted to module scope to preserve performance characteristics.
Since the no-op rewrite is a valid rewrite used to check pages/assets before adding a 404-rewrite this makes sure we don't show the rewriting to auto-export dynamic pages warning from it
Closes: https://github.com/vercel/next.js/issues/14736
This makes sure to base64 encode the `.env*` file contents before passing them in the URL for the serverless-loader since `!` is a special character in this case which can cause webpack to fail to build
Closes: https://github.com/vercel/next.js/issues/14749
* avoid pulling code in the bundle for `trailingSlash` logic when it's not enabled
* avoid cloning the url an extra time if normalizing the path doesn't change it
Avoid trailing slashes on urls that look like files. The redirect for `trailingSlash: true` will now look like:
```
Redirects
┌ source: /:path*/:file.:ext/
├ destination: /:path*/:file.:ext
└ permanent: true
┌ source: /:path*/:notfile([^/.]+)
├ destination: /:path*/:notfile/
└ permanent: true
```
The default still looks like:
```
Redirects
┌ source: /:path+/
├ destination: /:path+
└ permanent: true
```
After this gets merged, I have a few optimizations planned on the normalization code that should reduce the client bundle a little and that consolidates the `trailingSlash` and `exportTrailingSlash` options
The existing example gives an error on every hot reload, perhaps because of the way that an initial `useEffect` hook imports the `GLTFLoader` and it doesn't redo that on hot reload?
Putting the component using the `useLoader` hook in a dynamic import seems to fix this.
Open to better suggestions, this is kind of awkward to use still...
This updates `fetchNextData` to re-use the `getDataHref` function from `page-loader` which has more verbose handling to ensure the correct `/_next/data` URL is built. Re-using this logic ensures the `/_next/data` URL can still be built even when a mismatching `href` and `as` value is provided to `next/link`.
This also fixes a case in `getDataHref` where optional values that weren't provided would fail to build the data href since the check requiring the param be present while interpolating the route values hasn't been updated to allow missing params for optional values.
An additional test case has been added to the prerender suite to ensure the `/_next/data` URL is built correctly when mismatching `href` and `as` values are provided
x-ref: https://github.com/vercel/next.js/discussions/14536
x-ref: https://github.com/vercel/next.js/discussions/9081#discussioncomment-31160
Closes: https://github.com/vercel/next.js/issues/14668
Add tests and fix for when the url contains query parameters.
`router` now uses the same method for formatting url+as pair as `Link`, will be able to share code after https://github.com/vercel/next.js/pull/14633 is merged
We've been meaning to change this code for a while 👍
- Changed the name from spr to incremental
- Changed the code to be a class instead of using module scope variables