Files
Lee RobinsonandGitHub 27d2fa2838 docs: remove Vercel mentions and improve deployment page (#78557)
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.


![image](https://github.com/user-attachments/assets/6dff819b-c46f-4b1a-833c-0827c6ef8735)

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.


![image](https://github.com/user-attachments/assets/6d3291b8-f9bd-47e7-a21e-b843c0e1ef0c)


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.
2025-04-25 15:28:09 -05:00

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
```