mirror of
https://github.com/hanzoai/next.js.git
synced 2026-10-30 14:46:38 +00:00
This PR prunes references to Vercel in the documentation. Some of the mentions were egregious and unneeded. Others were documenting specific behavior for how Next.js runs on Vercel, which is better suited for the Vercel documentation. It also restructures our deployment documentation to remove any previous bias toward Vercel. Rather than separating self-hosting (Node.js server, Docker, static export) into its own section from managed platforms, it now lists them all together. Vercel is listed under "Adapters", alongside Netlify, Cloudflare, and AWS Amplify (in alphabetical order). These are the companies we're working with on the [Deployment Adapters API](https://github.com/vercel/next.js/discussions/77740), who currently maintain their own adapters and will eventually migrate to use this new API. We've [started working on](https://github.com/vercel/next.js/pull/78166) that API. For different features in the docs, like ISR or Middleware, this PR also adds a new feature matrix that shows the different deployment options and whether this feature is supported. For example, features that require using the server are not supported with static exports. Additionally, when there is configuration possible (like changing the caching behavior of ISR) we link back to our guide which explains these options in detail.  This PR also updates the Middleware section of the self-hosting guide to mention [Node.js runtime support](https://nextjs.org/blog/next-15-2#nodejs-middleware-experimental). I've also removed the "Managed Next.js (Vercel)" entry for the docs sidebar, as it is not necessary and Vercel should not have additional priority there over other providers.  Netlify has confirmed they're okay with the specific feature matrix link included in the adapters section, and I did my best to include the Cloudflare and Amplify versions based on their documentation. If any of the providers want to see changes to those links, please let me know and I'll open a PR.
227 lines
6.0 KiB
Plaintext
227 lines
6.0 KiB
Plaintext
---
|
|
title: How to upgrade to version 9
|
|
nav_title: Version 9
|
|
description: Upgrade your Next.js Application from Version 8 to Version 9.
|
|
---
|
|
|
|
To upgrade to version 9, run the following command:
|
|
|
|
```bash filename="Terminal"
|
|
npm i next@9
|
|
```
|
|
|
|
```bash filename="Terminal"
|
|
yarn add next@9
|
|
```
|
|
|
|
```bash filename="Terminal"
|
|
pnpm up next@9
|
|
```
|
|
|
|
```bash filename="Terminal"
|
|
bun add next@9
|
|
```
|
|
|
|
> **Good to know:** If you are using TypeScript, ensure you also upgrade `@types/react` and `@types/react-dom` to their corresponding versions.
|
|
|
|
## Check your Custom App File (`pages/_app.js`)
|
|
|
|
If you previously copied the [Custom `<App>`](/docs/pages/building-your-application/routing/custom-app) example, you may be able to remove your `getInitialProps`.
|
|
|
|
Removing `getInitialProps` from `pages/_app.js` (when possible) is important to leverage new Next.js features!
|
|
|
|
The following `getInitialProps` does nothing and may be removed:
|
|
|
|
```js
|
|
class MyApp extends App {
|
|
// Remove me, I do nothing!
|
|
static async getInitialProps({ Component, ctx }) {
|
|
let pageProps = {}
|
|
|
|
if (Component.getInitialProps) {
|
|
pageProps = await Component.getInitialProps(ctx)
|
|
}
|
|
|
|
return { pageProps }
|
|
}
|
|
|
|
render() {
|
|
// ... etc
|
|
}
|
|
}
|
|
```
|
|
|
|
## Breaking Changes
|
|
|
|
### `@zeit/next-typescript` is no longer necessary
|
|
|
|
Next.js will now ignore usage `@zeit/next-typescript` and warn you to remove it. Please remove this plugin from your `next.config.js`.
|
|
|
|
Remove references to `@zeit/next-typescript/babel` from your custom `.babelrc` (if present).
|
|
|
|
The usage of [`fork-ts-checker-webpack-plugin`](https://github.com/Realytics/fork-ts-checker-webpack-plugin/issues) should also be removed from your `next.config.js`.
|
|
|
|
TypeScript Definitions are published with the `next` package, so you need to uninstall `@types/next` as they would conflict.
|
|
|
|
The following types are different:
|
|
|
|
> This list was created by the community to help you upgrade, if you find other differences please send a pull-request to this list to help other users.
|
|
|
|
From:
|
|
|
|
```tsx
|
|
import { NextContext } from 'next'
|
|
import { NextAppContext, DefaultAppIProps } from 'next/app'
|
|
import { NextDocumentContext, DefaultDocumentIProps } from 'next/document'
|
|
```
|
|
|
|
to
|
|
|
|
```tsx
|
|
import { NextPageContext } from 'next'
|
|
import { AppContext, AppInitialProps } from 'next/app'
|
|
import { DocumentContext, DocumentInitialProps } from 'next/document'
|
|
```
|
|
|
|
### The `config` key is now an export on a page
|
|
|
|
You may no longer export a custom variable named `config` from a page (i.e. `export { config }` / `export const config ...`).
|
|
This exported variable is now used to specify page-level Next.js configuration like Opt-in AMP and API Route features.
|
|
|
|
You must rename a non-Next.js-purposed `config` export to something different.
|
|
|
|
### `next/dynamic` no longer renders "loading..." by default while loading
|
|
|
|
Dynamic components will not render anything by default while loading. You can still customize this behavior by setting the `loading` property:
|
|
|
|
```jsx
|
|
import dynamic from 'next/dynamic'
|
|
|
|
const DynamicComponentWithCustomLoading = dynamic(
|
|
() => import('../components/hello2'),
|
|
{
|
|
loading: () => <p>Loading</p>,
|
|
}
|
|
)
|
|
```
|
|
|
|
### `withAmp` has been removed in favor of an exported configuration object
|
|
|
|
Next.js now has the concept of page-level configuration, so the `withAmp` higher-order component has been removed for consistency.
|
|
|
|
This change can be **automatically migrated by running the following commands in the root of your Next.js project:**
|
|
|
|
```bash filename="Terminal"
|
|
curl -L https://github.com/vercel/next-codemod/archive/master.tar.gz | tar -xz --strip=2 next-codemod-master/transforms/withamp-to-config.js npx jscodeshift -t ./withamp-to-config.js pages/**/*.js
|
|
```
|
|
|
|
To perform this migration by hand, or view what the codemod will produce, see below:
|
|
|
|
**Before**
|
|
|
|
```jsx
|
|
import { withAmp } from 'next/amp'
|
|
|
|
function Home() {
|
|
return <h1>My AMP Page</h1>
|
|
}
|
|
|
|
export default withAmp(Home)
|
|
// or
|
|
export default withAmp(Home, { hybrid: true })
|
|
```
|
|
|
|
**After**
|
|
|
|
```jsx
|
|
export default function Home() {
|
|
return <h1>My AMP Page</h1>
|
|
}
|
|
|
|
export const config = {
|
|
amp: true,
|
|
// or
|
|
amp: 'hybrid',
|
|
}
|
|
```
|
|
|
|
### `next export` no longer exports pages as `index.html`
|
|
|
|
Previously, exporting `pages/about.js` would result in `out/about/index.html`. This behavior has been changed to result in `out/about.html`.
|
|
|
|
You can revert to the previous behavior by creating a `next.config.js` with the following content:
|
|
|
|
```js filename="next.config.js"
|
|
module.exports = {
|
|
trailingSlash: true,
|
|
}
|
|
```
|
|
|
|
### `pages/api/` is treated differently
|
|
|
|
Pages in `pages/api/` are now considered [API Routes](https://nextjs.org/blog/next-9#api-routes).
|
|
Pages in this directory will no longer contain a client-side bundle.
|
|
|
|
## Deprecated Features
|
|
|
|
### `next/dynamic` has deprecated loading multiple modules at once
|
|
|
|
The ability to load multiple modules at once has been deprecated in `next/dynamic` to be closer to React's implementation (`React.lazy` and `Suspense`).
|
|
|
|
Updating code that relies on this behavior is relatively straightforward! We've provided an example of a before/after to help you migrate your application:
|
|
|
|
**Before**
|
|
|
|
```jsx
|
|
import dynamic from 'next/dynamic'
|
|
|
|
const HelloBundle = dynamic({
|
|
modules: () => {
|
|
const components = {
|
|
Hello1: () => import('../components/hello1').then((m) => m.default),
|
|
Hello2: () => import('../components/hello2').then((m) => m.default),
|
|
}
|
|
|
|
return components
|
|
},
|
|
render: (props, { Hello1, Hello2 }) => (
|
|
<div>
|
|
<h1>{props.title}</h1>
|
|
<Hello1 />
|
|
<Hello2 />
|
|
</div>
|
|
),
|
|
})
|
|
|
|
function DynamicBundle() {
|
|
return <HelloBundle title="Dynamic Bundle" />
|
|
}
|
|
|
|
export default DynamicBundle
|
|
```
|
|
|
|
**After**
|
|
|
|
```jsx
|
|
import dynamic from 'next/dynamic'
|
|
|
|
const Hello1 = dynamic(() => import('../components/hello1'))
|
|
const Hello2 = dynamic(() => import('../components/hello2'))
|
|
|
|
function HelloBundle({ title }) {
|
|
return (
|
|
<div>
|
|
<h1>{title}</h1>
|
|
<Hello1 />
|
|
<Hello2 />
|
|
</div>
|
|
)
|
|
}
|
|
|
|
function DynamicBundle() {
|
|
return <HelloBundle title="Dynamic Bundle" />
|
|
}
|
|
|
|
export default DynamicBundle
|
|
```
|