자동 업그레이드 CLI
npx @next/codemod@canary upgrade latest
수동 업그레이드 CLI
npm install next@latest react@rc react-dom@rc
@next/codemod
CLI: 최신 Next.js와 React 버전으로 쉽게 업그레이드할 수 있게 되었다고 한다.fetch
요청, GET 라우트 핸들러, 클라이언트 탐색이 기본적으로 캐시되지 않는다.unstable_after
API (Experimental): 응답 스트리밍이 끝난 후 코드를 실행instrumentation.js
API (Stable): 서버 생명 주기 관찰을 위한 새로운 APInext/form
): 클라이언트 측 탐색으로 HTML 폼을 향상시킴next.config
: TypeScript 지원을 위한 next.config.ts 지원
npx @next/codemod@canary upgrade latest
cookies()
사용 예시const found = cookies().get(cookieName);
cookies()
사용 예시import { cookies } from 'next/headers';
export async function AdminPanel() {
const cookieStore = await cookies();
const token = cookieStore.get('token');
// ...
}
npx @next/codemod@canary next-async-request-api .
fetch
를 사용하는 타사 라이브러리와의 상호 작용을 재평가했다고 한다.fetch
Requests are no longer cached by defaultfetch
요청, GET Route Handlers, 클라이언트 라우터 캐시의 기본 캐싱 설정을 "기본적으로 캐시됨"에서 "기본적으로 캐시되지 않음" 으로 변경했다. fetch('https://...', { cache: 'force-cache' | 'no-store' });
cache
옵션 내용은 아래와 같다.no-store
가 사용된다. 즉, fetch 요청은 기본적으로 캐시되지 않는다.GET
Route Handlers are no longer cached by defaultexport dynamic = 'force-static'
)sitemap.ts
, opengraph-image.tsx
, icon.tsx
와 같은 특별한 Route Handlers 및 기타 메타데이터 파일은 동적 함수나 동적 구성 옵션을 사용하지 않는 한 기본적으로 정적이라 한다.Next.js v14.2.0에서는 Router Cache의 사용자 정의 구성을 허용하기 위해 실험적인 staleTimes
플래그를 도입했었다.
클라이언트 측 route cache는 방문한 경로와 미리 가져온 경로를 클라이언트에 캐시하여, 빠른 네비게이션 경험을 제공하기 위해 설계된 캐싱 레이어이다.
커뮤니티 피드백을 기반으로, Next.js v14.2에서는 experimental staleTimes
옵션을 추가하여 클라이언트 측의 router cache의 무효화 기간을 구성할 수 있도록 했다.
기본적으로, prefetch prop
을 사용하지 않고 <Link>
컴포넌트를 통해 미리 가져온 경로는 30초 동안 캐시되며, prefetch prop
이 true
로 설정된 경우에는 5분 동안 캐시된다.
- next.config.js
에서는 사용자 정의 재유효화 시간을 정의하여 이러한 기본값을 덮어쓸 수 있다.
/** @type {import('next').NextConfig} */
const nextConfig = {
experimental: {
staleTimes: {
dynamic: 30, // <Link>에서 prefetch prop이 지정되지 않은 경우에 사용된다. 기본값: 30초
static: 180, // <Link>에서 prefetch prop이 true로 설정되거나 router.prefetch를 호출한 경우에 사용된다. (기본값 5분)
},
},
}
module.exports = nextConfig
prefetch prop
가 지정되지 않은 <Link>
에서는 30초동안 캐시된 페이지를 빠르게 확인할 수 있다.prefetch prop
이 true
로 설정되거나, router.prefetch
를 호출한 경우는 180초동안 캐시된 페이지를 빠르게 확인할 수 있다.loading.js
는 5분 동안 캐시됨 (또는 staleTimes.static 구성의 값).
stable
버전으로 출시하기로 결정했다고 한다.codemods
와 자동화 도구를 제공했다고 한다. (맨 처음 내용)
Next.js 14.1 Hydration Error Message (이미지 출처 : https://nextjs.org/blog/next-15)
Next.js 15 Hydration Error Message (이미지 출처 : https://nextjs.org/blog/next-15)
Next.js의 next dev --turbo
명령이 안정화되어, 이제 개발 과정에서 성능을 대폭 개선할 수 있다.
vercel.com
에서 다음과 같은 성능 향상을 얻었다고 한다.자세한 내용은 Turbopack Dev 관련 블로그 포스트에서 확인할 수 있다.
개발 중에 Static Route Indicator라는 시각적 표시가 추가되어, 정적 라우트와 동적 라우트를 쉽게 구분할 수 있게 되었다. 이를 통해 페이지의 렌더링 방식을 이해하고, 성능을 최적화할 수 있다.
또한 next build
출력을 통해 모든 경로의 렌더링 전략을 확인할 수도 있다.
이 업데이트는 Next.js에서 가시성을 높이기 위한 노력의 일환으로, 개발자가 애플리케이션을 모니터링, 디버깅, 최적화하는 데 도움을 주기 위해 제공되었다. 더불어 향후 개발자 도구도 추가될 예정이라고 한다.
unstable_after
(Experimental)unstable_after
는 사용자 응답 후에 비동기 작업을 수행할 수 있도록 해주는 기능이다. 이 API는 특히 응답과 직접 관련이 없는 로그 기록, 분석, 외부 시스템 동기화 같은 작업을 사용자가 기다리지 않게 할 때 유용하다.
기존 서버리스 함수는 응답이 완료되면 즉시 작업을 중지하므로, 응답 이후에 작업을 처리하는 데 어려움이 있었다. unstable_after
는 이러한 문제를 해결하여 응답이 완료된 후에 추가 작업을 예약할 수 있게 해 준다. 이로써 응답 후에 실행할 보조 작업들이 주 응답을 차단하지 않고 수행할 수 있다.
이 방식은 응답 성능을 향상시키고, 응답 이후 실행할 작업(예: 로그 기록, 외부 API 호출 등)을 사용자가 기다리지 않게 처리할 수 있도록 도와줍니다. after
를 사용해 응답 후 비동기적으로 실행되는 작업을 설정하면, 사용자 경험을 저하시키지 않으면서 필요한 작업을 실행할 수 있다.
next.config.js
설정: next.config.js
에 아래와 같이 설정을 추가const nextConfig = {
experimental: {
after: true,
},
};
export default nextConfig;
Server Components
, Server Actions
, Route Handlers
, 또는 Middleware
에서 unstable_after
를 호출할 수 있다.after
함수 안의 log()
는 응답이 사용자에게 완료된 후에 실행된다. 즉, return <>{children}</>;
을 통해 화면에 children
이 렌더링되고, 그 후 log()
함수가 비동기적으로 실행된다.after(() => { log(); });
에서 정의된 log()
함수는 응답이 끝난 후에 실행될 보조 작업으로 예약된다. 즉, children
이 렌더링된 후 사용자가 화면을 볼 수 있게 된 상태에서 log()
가 실행되는 것이다.import { unstable_after as after } from 'next/server';
import { log } from '@/app/utils';
export default function Layout({ children }) {
// 보조 작업
after(() => {
log();
});
// 주 작업
return <>{children}</>;
}
instrumentation.js
(Stable)instrumentation.js
파일에서 register()
API를 사용하면 Next.js 서버의 생명주기(라이프사이클)를 모니터링할 수 있다. 이를 통해 성능을 모니터링하고 오류의 근원을 추적할 수 있으며, OpenTelemetry와 같은 관찰 가능성(Observability) 라이브러리와의 통합도 지원한다.onRequestError
Hook: Sentry와 협력하여 만든 이 새로운 onRequestError
hook을 사용하면 서버에서 발생하는 모든 오류에 대해 다음을 수행할 수 있다:export async function onRequestError(err, request, context) {
await fetch('https://...', {
method: 'POST',
body: JSON.stringify({ message: err.message, request, context }),
headers: { 'Content-Type': 'application/json' },
});
}
onRequestError
함수는 서버에서 발생한 오류를 추적할 수 있도록 하는 선택적 함수로, 이 함수를 사용하면 서버 오류를 원하는 관측 도구(예: Sentry)에 기록할 수 있다.onRequestError
에서 비동기 작업(예: 오류 정보를 외부 서버에 전송)을 실행하는 경우, 반드시 await
를 사용하여 해당 작업이 완료될 때까지 기다려야 한다. 이는 오류가 발생했을 때 onRequestError
가 비동기 작업을 완료할 시간을 확보하기 위해 필요하다.onRequestError
에 전달되는 오류 인스턴스는 원본 오류와 다를 수 있다. 특히 서버 컴포넌트 렌더링 중 오류가 발생한 경우, React가 오류를 내부적으로 처리할 수 있기 때문이다. 이 경우, digest
속성을 통해 오류의 실제 유형을 식별할 수 있다. digest
는 원래 발생한 오류의 특성을 파악하는 데 유용한 정보이다.
<Form>
Component<Form>
컴포넌트는 HTML <form>
요소를 확장하여 사전 로딩(prefetching), 클라이언트 사이드 네비게이션, 점진적 향상(Progressive Enhancement)을 제공한다. 이 컴포넌트는 검색 결과 페이지와 같이 페이지를 이동하는 폼에 특히 유용하다.import Form from 'next/form';
export default function Page() {
return (
<Form action="/search">
<input name="query" />
<button type="submit">Submit</button>
</Form>
);
}
next.config.ts
(Typescript 지원을 위한 next.config.ts
)next.config.ts
파일을 지원하며, NextConfig
타입을 제공하여 자동 완성 및 타입 안전한 옵션 구성을 돕는다.import type { NextConfig } from 'next';
const nextConfig: NextConfig = {
/* 구성 옵션 */
};
export default nextConfig;
self-hosting
시, Cache-Control
지시문을 보다 세밀하게 제어할 수 있도록 expireTime
설정이 가능해졌다.stale-while-revalidate
기간을 쉽게 조정할 수 있다.self-hosting
시 이미지 최적화를 위해 sharp
을 수동 설치하지 않아도 된다.Next.js v15
에서는 서버 실행 시 자동으로 sharp
을 활용하여 이미지 최적화를 지원한다.
Server Action
은 여전히 HTTP로 접근 가능한 엔드포인트로 취급되므로 보안 관리를 주의해야 한다.Server Action
은 빌드 시 제거된다.Next.js
가 안전하고 예측 불가능한 ID를 생성한다.// app/actions.js
'use server';
// 이 action은 애플리케이션에서 사용되고 있기 때문에, Next.js는 클라이언트가 이 Server Action을 참조하고 호출할 수 있도록
// 보안 ID를 생성합니다.
export async function updateUserAction(formData) {}
// 이 action은 애플리케이션에서 사용되지 않기 때문에, Next.js는 `next build` 중 이 코드를 자동으로 제거하며
// 공개 엔드포인트를 생성하지 않습니다.
export async function deleteUserAction(formData) {}
됨
Pages Router
와 App Router
에서 번들링을 세부적으로 설정할 수 있게 되었다. serverExternalPackages
를 사용해 특정 패키지를 번들링에서 제외할 수 있다.const nextConfig = {
bundlePagesRouterDependencies: true,
serverExternalPackages: ['package-name'],
};
export default nextConfig;
※ Cold Start
ESLINT_USE_FLAT_CONFIG=false
설정을 적용하여 전환을 돕는다.또한, —ext
와 —ignore-path
와 같은 더 이상 사용되지 않는 옵션들은 next lint
실행 시 제거된다. 이러한 옵션들은 ESLint 10에서 최종적으로 지원되지 않으므로, 빠른 마이그레이션(데이터나 소프트웨어를 한 시스템에서 다른 시스템으로 이동하는 것)을 권장한다.
이번 업데이트의 일환으로, React Hooks 사용을 위한 새 규칙이 포함된 eslint-plugin-react-hooks
버전 5.0.0으로도 업그레이드되었습니다. 모든 변경 사항은 eslint-plugin-react-hooks@5.0.0
의 변경 로그에서 확인할 수 있습니다.
Hot Module Replacement (HMR)
기능은 fetch 요청의 응답을 재사용하여 개발 성능을 향상시키고 API 호출 비용을 줄인다.const nextConfig = {
experimental: {
// Next.js가 페이지 생성에 실패했을 때, 빌드가 실패하기 전에 몇 번 재시도할지 설정합니다.
staticGenerationRetryCount: 1
// 한 워커(worker)당 처리할 페이지 수를 설정합니다.
staticGenerationMaxConcurrency: 8
// 새로운 export 워커를 생성하기 위한 최소 페이지 수를 설정합니다.
staticGenerationMinPagesPerWorker: 25
},
};
export default nextConfig;