콘텐츠로 이동

업그레이드: 버전 9

Source URL: https://nextjs.org/docs/pages/guides/upgrading/version-9

GuidesUpgradingVersion 9

마지막 업데이트 2026년 2월 20일

버전 9로 업그레이드하려면 다음 명령을 실행하세요:

터미널

npm i next@9

터미널

yarn add next@9

터미널

pnpm up next@9

터미널

bun add next@9

참고: TypeScript를 사용 중이라면 @types/react@types/react-dom도 해당 버전에 맞게 함께 업그레이드하세요.

사용자 지정 App 파일(pages/_app.js)을 확인하세요

섹션 제목: “사용자 지정 App 파일(pages/_app.js)을 확인하세요”

이전에 사용자 지정 <App> 예제를 그대로 복사했다면 getInitialProps를 제거할 수 있을지도 모릅니다.

가능하다면 pages/_app.js에서 getInitialProps를 제거하는 것이 새로운 Next.js 기능을 활용하는 데 중요합니다!

다음 getInitialProps는 아무 작업도 하지 않으므로 제거할 수 있습니다:

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

@zeit/next-typescript는 더 이상 필요하지 않습니다

섹션 제목: “@zeit/next-typescript는 더 이상 필요하지 않습니다”

Next.js는 이제 @zeit/next-typescript 사용을 무시하고 제거하라는 경고를 표시합니다. next.config.js에서 이 플러그인을 제거하세요.

사용자 지정 .babelrc(있는 경우)에서 @zeit/next-typescript/babel에 대한 참조도 삭제하세요.

fork-ts-checker-webpack-plugin의 사용 역시 next.config.js에서 제거해야 합니다.

TypeScript 정의는 next 패키지에 함께 게시되므로 충돌을 피하려면 @types/next를 제거해야 합니다.

다음 타입들이 변경되었습니다:

이 목록은 커뮤니티가 업그레이드를 돕기 위해 만들었습니다. 다른 차이점을 발견하면 다른 사용자들에게 도움이 되도록 이 목록에 풀 리퀘스트를 보내 주세요.

이전:

import { NextContext } from 'next'
import { NextAppContext, DefaultAppIProps } from 'next/app'
import { NextDocumentContext, DefaultDocumentIProps } from 'next/document'

이후

import { NextPageContext } from 'next'
import { AppContext, AppInitialProps } from 'next/app'
import { DocumentContext, DocumentInitialProps } from 'next/document'

config 키는 이제 페이지에서 export하는 항목입니다

섹션 제목: “config 키는 이제 페이지에서 export하는 항목입니다”

이제 페이지에서 config라는 이름의 사용자 정의 변수를 export(export { config } / export const config ...)할 수 없습니다. 이 export된 변수는 Opt-in AMP 및 API Route 기능 같은 페이지 수준 Next.js 구성을 지정하는 데 사용됩니다.

Next.js와 무관한 용도의 config export는 다른 이름으로 변경해야 합니다.

next/dynamic은 로딩 중 기본으로 “loading…”을 렌더링하지 않습니다

섹션 제목: “next/dynamic은 로딩 중 기본으로 “loading…”을 렌더링하지 않습니다”

동적 컴포넌트는 로딩 중 기본적으로 아무것도 렌더링하지 않습니다. loading 속성을 설정해 이 동작을 계속 사용자 정의할 수 있습니다:

import dynamic from 'next/dynamic'
const DynamicComponentWithCustomLoading = dynamic(
() => import('../components/hello2'),
{
loading: () => <p>Loading</p>,
}
)

withAmp는 export된 구성 객체로 대체되었습니다

섹션 제목: “withAmp는 export된 구성 객체로 대체되었습니다”

Next.js에는 이제 페이지 수준 구성 개념이 있으므로 일관성을 위해 withAmp 고차 컴포넌트가 제거되었습니다.

이 변경은 Next.js 프로젝트 루트에서 다음 명령을 실행하면 자동으로 마이그레이션됩니다.

터미널

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

수동으로 마이그레이션하거나 codemod가 생성할 결과를 확인하려면 아래를 참고하세요:

변경 전

import { withAmp } from 'next/amp'
function Home() {
return <h1>My AMP Page</h1>
}
export default withAmp(Home)
// or
export default withAmp(Home, { hybrid: true })

변경 후

export default function Home() {
return <h1>My AMP Page</h1>
}
export const config = {
amp: true,
// or
amp: 'hybrid',
}

next export는 더 이상 페이지를 index.html로 내보내지 않습니다

섹션 제목: “next export는 더 이상 페이지를 index.html로 내보내지 않습니다”

이전에는 pages/about.js를 내보내면 out/about/index.html이 생성되었습니다. 이제 이 동작이 out/about.html을 생성하도록 변경되었습니다.

이전 동작으로 되돌리려면 다음 내용을 포함한 next.config.js를 생성하세요:

next.config.js

module.exports = {
trailingSlash: true,
}

pages/api/의 페이지는 이제 API Routes로 간주됩니다. 이 디렉터리의 페이지는 더 이상 클라이언트 번들을 포함하지 않습니다.

next/dynamic은 한 번에 여러 모듈 로드를 지원하지 않습니다

섹션 제목: “next/dynamic은 한 번에 여러 모듈 로드를 지원하지 않습니다”

한 번에 여러 모듈을 로드하는 기능은 next/dynamic에서 사용 중단되어 React(React.lazy, Suspense) 구현과 더 유사해졌습니다.

이 동작에 의존하는 코드를 업데이트하는 것은 비교적 간단합니다! 애플리케이션 마이그레이션을 돕기 위해 변경 전/후 예제를 제공했습니다:

변경 전

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

변경 후

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