مهم‌ترین تغییرات Next.js 16

Next.js 16 فقط یک شماره‌ی جدید نیست. چند تغییر مهم در ابزار ساخت، مدل کش، مسیریابی و APIهای اصلی دارد. در این درس این تغییرات را یکجا مرور می‌کنیم تا بدانید چه چیزی نسبت به نسخه‌های قبلی فرق کرده و هر موضوع را در کدام درس دوره به‌طور کامل یاد می‌گیریم. هدف این درس نقشه‌ی کلی است، نه آموزش عمیق هر مورد.

پیش‌نیاز

  • درس «اجرای پروژه، اسکریپت‌ها و Turbopack»
  • درس «ساخت پروژه با create-next-app»

چرا این درس مهم است؟

بسیاری از آموزش‌ها، مقاله‌ها و کدهای آماده در اینترنت برای نسخه‌های ۱۳ تا ۱۵ نوشته شده‌اند. اگر بدون آگاهی از تغییرات نسخه‌ی ۱۶ از آن‌ها کپی کنید، با خطا یا رفتار غیرمنتظره روبه‌رو می‌شوید. دانستن این فهرست به شما کمک می‌کند کد قدیمی را تشخیص بدهید.

اطلاعات این درس بر پایه‌ی راهنمای رسمی ارتقا به نسخه‌ی ۱۶ در مستندات Next.js است. چون نسخه‌های فرعی ۱۶ هم منتشر می‌شوند، ممکن است برخی جزئیات در آن‌ها بهبود پیدا کنند. هر جا رفتار یک قابلیت به نسخه‌ی فرعی یا پیکربندی بستگی داشته باشد، در درس مربوط به آن اشاره می‌کنیم.

نمای کلی تغییرات

حوزه تغییر در Next.js 16 کجا کامل یاد می‌گیریم؟
ابزار ساخت Turbopack پایدار و پیش‌فرض برای dev و build همین درس و درس قبل
APIهای درخواست دسترسی همگام به params، searchParams، cookies() و headers() کاملاً حذف شد «مسیرهای پویا، params ناهمگام و مسیرهای تودرتو»
کش مدل صریح‌تر با Cache Components؛ use cache، cacheLife و cacheTag پایدار شدند؛ APIهای جدید updateTag و refresh فصل «Cache و Revalidation در Next.js 16»
Middleware نام middleware منسوخ شد و proxy جایگزین آن است «نقش proxy.ts در Next.js 16»
مسیریابی Prefetch هوشمندتر: حذف تکرار Layout و Prefetch تدریجی «Prefetching و رفتار Navigation»
React React 19.2 و پشتیبانی پایدار از React Compiler (پیش‌فرض نیست) «React Compiler در حد کاربردی و متناسب با نسخه»
تصاویر مقدارهای پیش‌فرض جدید و محدودیت‌های امنیتی بیشتر در next/image «next/image و تنظیمات تصاویر در Next.js 16»
Lint فرمان next lint حذف شد و next build دیگر lint اجرا نمی‌کند «TypeScript، ESLint و Format کردن کد در Next.js 16»
حداقل نسخه‌ها Node.js نسخه‌ی 20.9 و TypeScript نسخه‌ی 5.1 درس «پیش‌نیازها و آماده‌سازی محیط توسعه»

۱. Turbopack به‌صورت پیش‌فرض

در نسخه‌های قبلی برای استفاده از Turbopack باید گزینه‌ی --turbopack می‌دادید. حالا هم next dev و هم next build به‌صورت پیش‌فرض از آن استفاده می‌کنند، پس در پروژه‌ی جدید لازم نیست چیزی به اسکریپت‌ها اضافه شود. چند نکته:

  • اگر پروژه تنظیمات سفارشی webpack داشته باشد، next build با Turbopack شکست می‌خورد تا پیکربندی اشتباه ناخواسته اجرا نشود. راه‌حل‌ها: مهاجرت پیکربندی به Turbopack، اجرا با --turbopack و نادیده‌گرفتن تنظیم Webpack، یا برگشت به Webpack با --webpack. همین ممکن است وقتی هم رخ بدهد که خودتان Webpack را پیکربندی نکرده‌اید و یک افزونه آن را اضافه کرده است.
  • پیکربندی Turbopack از experimental.turbopack به گزینه‌ی سطح بالای turbopack منتقل شده است.
  • طبق مستندات فعلی، ذخیره‌ی دیسکی نتایج کامپایل (Filesystem Caching) هم برای dev و هم برای build فعال است تا اجراهای بعدی سریع‌تر شوند. این بخش از مستندات در نسخه‌های فرعی تغییر کرده است، پس رفتار دقیق آن را از مستندات نسخه‌ی خودتان بررسی کنید.
ts
// next.config.ts
import type { NextConfig } from "next";

const nextConfig: NextConfig = {
  // Next.js 15: experimental: { turbopack: { ... } }
  // Next.js 16: در سطح بالا
  turbopack: {
    // گزینه‌ها
  },
};

export default nextConfig;

۲. APIهای درخواست فقط ناهمگام هستند

در Next.js 15 این APIها ناهمگام شدند، اما برای دوره‌ی انتقال هنوز دسترسی همگام موقت پشتیبانی می‌شد. در Next.js 16 دسترسی همگام کاملاً حذف شده است. یعنی این موارد را فقط با await می‌توان خواند:

  • cookies()، headers() و draftMode()
  • params در layout، page، route و چند فایل ویژه‌ی دیگر
  • searchParams در page

نمونه‌ی ساده‌ی یک صفحه‌ی پویا در پروژه‌ی DevNotes:

tsx
// app/posts/[slug]/page.tsx
type PostPageProps = {
  params: Promise<{ slug: string }>;
};

export default async function PostPage({ params }: PostPageProps) {
  const { slug } = await params;

  return <h1>نوشته: {slug}</h1>;
}

در این کد params یک Promise است و باید قبل از استفاده await شود، بنابراین کامپوننت هم async تعریف شده است. این الگو را در فصل «Routing و Navigation» به‌طور کامل تمرین می‌کنیم. اگر کد قدیمی را با روش همگام (مثلاً params.slug) ببینید، در Next.js 16 باید اصلاح شود.

۳. تغییرات کش و Cache Components

مهم‌ترین تغییر مفهومی نسخه‌ی ۱۶ در بخش کش است. موارد اصلی:

  • گزینه‌ی cacheComponents: یک گزینه‌ی سطح بالا در next.config.ts برای انتخاب مدل جدید کش و رندر. پرچم‌های آزمایشی قبلی مثل experimental.ppr، experimental.dynamicIO و experimental.useCache حذف شده‌اند و cacheComponents جای آن‌ها را می‌گیرد. روشن‌کردن آن فقط یک تغییر نام ساده نیست و می‌تواند رفتار برنامه را تغییر بدهد؛ مثلاً ممکن است داده‌ی کش‌نشده خارج از Suspense خطای Build ایجاد کند.
  • cacheLife و cacheTag: پایدار شده‌اند و پیشوند unstable_ لازم نیست.
  • revalidateTag: حالا آرگومان دوم، یعنی پروفایل cacheLife، می‌خواهد. شکل تک‌آرگومانی منسوخ است و در TypeScript خطا می‌دهد.
  • updateTag: API جدید فقط برای Server Actions که بعد از تغییر داده، کش را منقضی و همان لحظه تازه می‌کند تا کاربر تغییر خودش را فوراً ببیند.
  • refresh: API جدید در Server Actions برای تازه‌کردن Router سمت کلاینت.
ts
// قبل
revalidateTag("posts");

// Next.js 16
revalidateTag("posts", "max");

این APIها هرکدام رفتار و کاربرد جداگانه‌ای دارند و جایگزین یکدیگر نیستند. در فصل «Cache و Revalidation در Next.js 16» با درس‌های «معرفی cacheComponents و تفاوت رفتار برنامه با روشن یا خاموش بودن آن»، «دستور use cache و کاربرد آن در کش‌کردن تابع یا کامپوننت»، «revalidateTag، پروفایل‌های بازاعتبارسنجی و updateTag» و «refresh، به‌روزرسانی رابط کاربری و تفاوت آن با Revalidation» همه‌ی این‌ها را با مثال یاد می‌گیریم.

یک نکته‌ی مهم برای پروژه‌ی ما: cacheComponents فعال‌شدنش اختیاری است. همان‌طور که در درس «ساخت پروژه با create-next-app» دیدیم، تنظیمات پیشنهادی ابزار ساخت پروژه آن را روشن می‌کند، ولی ما پروژه را با آن خاموش ساختیم و در زمان مناسب فعالش می‌کنیم.

Partial Prerendering نیز در نسخه‌ی ۱۶ با همین cacheComponents فعال می‌شود و با شکل آزمایشی نسخه‌های Canary قبلی Next.js 15 فرق دارد. در درس «داده‌های پویا، connection()، Suspense و Partial Prerendering» به آن می‌پردازیم.

۴. middleware به proxy تغییر نام داد

فایل middleware.ts و تابع middleware منسوخ شده‌اند و نام جدید proxy.ts و تابع proxy است. نام جدید نقش آن را روشن‌تر می‌کند: این فایل در مرز شبکه و برای تصمیم‌های مسیریابی اجرا می‌شود.

ts
// proxy.ts
import { NextResponse, type NextRequest } from "next/server";

export function proxy(request: NextRequest) {
  return NextResponse.next();
}
  • Runtime فایل proxy برابر nodejs است و قابل تغییر نیست.
  • Edge runtime در proxy پشتیبانی نمی‌شود. اگر به آن نیاز دارید، هنوز باید از middleware استفاده کنید.
  • گزینه‌های پیکربندی هم تغییر نام داده‌اند؛ مثلاً skipMiddlewareUrlNormalize حالا skipProxyUrlNormalize است.

کاربرد درست، matcher و محدودیت‌های این فایل را در فصل «Proxy و کنترل دسترسی» می‌بینیم.

۵. مسیریابی و Navigation سریع‌تر

سیستم Prefetch بازنویسی شده است. دو بهبود اصلی:

  • حذف تکرار Layout: وقتی چند آدرس Layout مشترک دارند، آن Layout فقط یک‌بار دانلود می‌شود.
  • Prefetch تدریجی: فقط بخش‌هایی که هنوز در کش نیستند Prefetch می‌شوند، نه کل صفحه.

برای استفاده از این بهبودها کدی را تغییر نمی‌دهید. ممکن است تعداد درخواست‌های Prefetch در ابزار Network مرورگر بیشتر ولی حجم هر درخواست کمتر دیده شود؛ این رفتار طبیعی است. جزئیات در درس «Prefetching و رفتار Navigation» می‌آید.

۶. React 19.2 و React Compiler

App Router در Next.js 16 از آخرین نسخه‌ی Canary ریکت استفاده می‌کند که قابلیت‌های React 19.2 را شامل می‌شود، از جمله View Transitions، useEffectEvent و Activity. این‌ها بیشتر مربوط به خود React هستند و در این دوره فقط در حد نیاز به آن‌ها اشاره می‌کنیم.

پشتیبانی داخلی از React Compiler پایدار شده است. این ابزار کامپوننت‌ها را خودکار Memoize می‌کند تا رندر اضافه کم شود. اما به‌صورت پیش‌فرض روشن نیست؛ باید گزینه‌ی reactCompiler: true را در پیکربندی بگذارید و بسته‌ی babel-plugin-react-compiler را نصب کنید. روشن‌کردن آن زمان کامپایل را بیشتر می‌کند. در درس «React Compiler در حد کاربردی و متناسب با نسخه» بررسی می‌کنیم کِی ارزش استفاده دارد.

۷. تغییرات next/image

چند مقدار پیش‌فرض و محدودیت next/image عوض شده است:

مورد تغییر
images.minimumCacheTTL پیش‌فرض از ۶۰ ثانیه به ۴ ساعت رسید
images.imageSizes مقدار 16 از پیش‌فرض حذف شد
images.qualities پیش‌فرض فقط [75] است و مقدار quality نامجاز به نزدیک‌ترین مقدار مجاز تبدیل می‌شود
تصاویر محلی با Query String نیازمند تنظیم images.localPatterns هستند
بهینه‌سازی IP محلی به‌صورت پیش‌فرض مسدود است
images.maximumRedirects از نامحدود به حداکثر ۳ تغییر مسیر رسید
next/legacy/image و images.domains منسوخ شدند؛ به‌جای آن‌ها next/image و images.remotePatterns

این موارد را در درس «next/image و تنظیمات تصاویر در Next.js 16» در جای خودشان استفاده می‌کنیم.

۸. حذف next lint و ESLint Flat Config

فرمان next lint حذف شده است و next build هم lint را اجرا نمی‌کند. باید ESLint (یا Biome) را مستقیماً با اسکریپت npm run lint اجرا کنید. افزونه‌ی ESLint مخصوص Next.js هم به‌صورت پیش‌فرض از فرمت جدید Flat Config (فایل eslint.config.mjs) استفاده می‌کند. بنابراین هر جا کد قدیمی با .eslintrc یا گزینه‌ی eslint داخل next.config دیدید، مال نسخه‌های قبلی است.

۹. چند تغییر دیگر که خوب است بدانید

  • اجرای هم‌زمان dev و build: این دو حالا خروجی‌های جدا دارند (خروجی dev در .next/dev است) و یک مکانیزم قفل از اجرای چند نمونه‌ی هم‌زمان روی یک پروژه جلوگیری می‌کند.
  • Parallel Routes: هر Slot حالا حتماً به فایل default.js نیاز دارد و بدون آن Build شکست می‌خورد. این موضوع جزو مباحث عمیق این دوره نیست.
  • خروجی next build: معیارهای size و First Load JS از گزارش حذف شدند، چون در معماری مبتنی بر Server Components دقیق نبودند. برای سنجش عملکرد، از ابزارهایی مثل Lighthouse استفاده کنید. این موضوع را در فصل «معماری، عملکرد، دسترس‌پذیری و تست» پی می‌گیریم.
  • حذف Runtime Config: serverRuntimeConfig و publicRuntimeConfig حذف شده‌اند و باید از متغیرهای محیطی استفاده کنید. درس «متغیرهای عمومی و محرمانه» به این موضوع می‌پردازد.
  • حذف AMP: پشتیبانی از AMP کاملاً حذف شد.
  • رفتار Scroll: Next.js دیگر مقدار scroll-behavior شما را هنگام جابه‌جایی بین صفحات موقتاً تغییر نمی‌دهد. برای رفتار قبلی باید روی تگ html ویژگی data-scroll-behavior="smooth" را بگذارید.
  • Build Adapters API: یک API برای پلتفرم‌های استقرار و ابزارهای سفارشی که در این دوره به آن نیاز نداریم.

این تغییرات در DevNotes چه اثری دارند؟

  • همه‌ی صفحات پویا با params ناهمگام نوشته می‌شوند.
  • رفتار پایه‌ی کش را اول بدون cacheComponents می‌بینیم و بعد در فصل کش آن را آگاهانه فعال می‌کنیم.
  • برای محدودکردن مسیرهای مدیریت از proxy.ts استفاده می‌کنیم، نه middleware.ts.
  • برای lint از npm run lint استفاده می‌کنیم و Build آن را اجرا نمی‌کند.
  • برای ساخت و اجرا به Turbopack تکیه می‌کنیم.

جمع‌بندی

  • Turbopack در Next.js 16 پیش‌فرض است و Build با تنظیمات سفارشی Webpack باید آگاهانه مدیریت شود.
  • دسترسی همگام به params، searchParams، cookies() و headers() حذف شده و فقط روش ناهمگام معتبر است.
  • مدل کش با cacheComponents، use cache، cacheLife، cacheTag، updateTag و refresh بازطراحی شده؛ revalidateTag هم حالا آرگومان دوم می‌خواهد.
  • middleware به proxy تبدیل شده و Runtime آن Node.js است.
  • Prefetch هوشمندتر شده، React Compiler پایدار ولی خاموش است و next/image پیش‌فرض‌های جدیدی دارد.
  • next lint حذف شده و AMP و Runtime Config دیگر وجود ندارند.
  • در درس بعد، «آزمون فصل اول»، آنچه در این فصل یاد گرفتید را با یک آزمون ۶ سؤالی می‌سنجیم.