انتقل إلى المحتوى

دليل الانتقال إلى Next.js 16: ترقية خطوة بخطوة

الانتقال إلى Next.js 16 لا يقتصر على تحديث الإصدار. نستعرض تغييرات Turbopack وواجهات async وProxy والتخزين المؤقت وتحسين الصور.

تاريخ النشر: آخر تحديث:

للانتقال إلى Next.js 16 حدّث بيئة التشغيل أولًا (Node.js 20.9.0 وTypeScript 5.1.0 على الأقل)، ثم شغّل أداة codemod الرسمية، وعالج يدويًا التغييرات الجذرية: Turbopack كأداة بناء افتراضية، وتحوّل params وsearchParams وcookies() وheaders() إلى واجهات غير متزامنة بالكامل، واستبدال middleware.ts بملف proxy.ts، وإزالة أمر next lint، والقيم الافتراضية الجديدة في مكون next/image الخاص بالصور. أما Cache Components وReact Compiler فالأفضل تفعيلهما لاحقًا بعد استقرار الترحيل.

تحديث مشروع Next.js بين الإصدارات الرئيسية لا يكون في العادة ببساطة تشغيل npm install next@latest ثم متابعة العمل. فعندما يكون المشروع مستخدماً في بيئة production ويعتمد على authentication أو middleware أو caching أو image optimization أو إعدادات build مخصصة، يمكن أن يؤثر تحديث framework مباشرة في بنية التطبيق.

وإصدار Next.js 16 مثال واضح على ذلك.

صدر الإصدار الأول من Next.js 16 في أكتوبر 2025، وجعل Turbopack أداة bundler الافتراضية، وأعاد النظر في نموذج caching، وقدم دعماً لـ React Compiler إلى جانب تحسينات في routing وعدد من breaking changes التي قد تتطلب تعديلات مباشرة في الكود أثناء الترحيل (migration). ولم يتوقف التطوير عند ذلك، إذ صدر Next.js 16.3 في 3 أغسطس 2026 مع تحسينات إضافية في الأداء وتجربة المطور.

لذلك لن نكتفي في هذا المقال بالسؤال: «ما الجديد في Next.js 16؟». السؤال الأكثر أهمية هو:

ما الذي يمكن أن يتعطل عند نقل مشروع قائم من Next.js 15 إلى Next.js 16، وكيف يمكن تنفيذ migration بطريقة آمنة ومنظمة؟

ابدأ بفحص بيئة التشغيل

قبل بدء migration، أول ما أفضّل مراجعته ليس framework نفسه، بل بيئة التشغيل. والسبب أن Next.js 16 غيّر أيضاً الحد الأدنى لمتطلبات النظام.

يتطلب Next.js 16 إصدار Node.js 20.9.0 على الأقل، وTypeScript 5.1.0 على الأقل. ولم يعد Node.js 18 مدعوماً.

ابدأ بفحص إصدار Node.js الحالي:

node -v

إذا كان المشروع يستخدم Docker، فلا يكفي تحديث البيئة المحلية فقط. يجب أيضاً مراجعة Node image داخل Dockerfile، وCI/CD pipeline، وإصدار Node.js الموجود على خادم الإنتاج (production server).

على سبيل المثال، إذا كان Dockerfile القديم يحتوي على:

FROM node:18-alpine

فيجب نقله إلى إصدار مدعوم من Node 20 عند الانتقال إلى الإصدار 16.

هذه واحدة من أكثر النقاط التي يسهل تجاهلها في major framework migrations: يعمل التطبيق محلياً بشكل طبيعي بينما لا تزال بيئة production build تستخدم إصداراً قديماً من بيئة Node.js التشغيلية.

رسم توضيحي للترقية من الإصدار 15 إلى الإصدار 16 من إطار العمل

كيف ننتقل إلى Next.js 16؟

يوفر فريق Next.js أداة codemod مخصصة لهذه العملية.

إذا كنت تستخدم npm:

npx @next/codemod@canary upgrade latest

أما إذا كنت تفضّل التحديث يدوياً:

npm install next@latest react@latest react-dom@latest

وفي المشاريع التي تستخدم TypeScript، يجب أيضاً تحديث حزم أنواع React:

npm install -D @types/react@latest @types/react-dom@latest

أفضّل عادة البدء باستخدام codemod كلما كان ذلك ممكناً. فهو لا يغيّر إصدارات dependencies فقط، بل يمكنه أيضاً تحديث Turbopack configuration، ونقل استخدام next lint إلى ESLint CLI، وتحويل convention الخاص بـ middleware إلى proxy، وتنظيف بعض إعدادات experimental القديمة.

لكن هناك فرق مهم:

يسهّل codemod عملية migration، لكنه لا ينفذها بالكامل بدلاً منك.

يجب الاستمرار في اختبار custom Webpack configuration والحزم الخارجية وطبقة authentication وسلوك caching بشكل يدوي.

Turbopack أصبح الخيار الافتراضي

هذه من أهم التغييرات التي يجب الانتباه إليها عند الانتقال إلى الإصدار 16.

ابتداءً من Next.js 16 أصبح Turbopack هو bundler الافتراضي لكل من أمري next dev وnext build معًا. ولم تعد هناك حاجة إلى تمرير --turbo أو --turbopack بشكل منفصل.

الاستخدام السابق:

{
  "scripts": {
    "dev": "next dev --turbopack",
    "build": "next build --turbopack"
  }
}

الاستخدام الجديد:

{
  "scripts": {
    "dev": "next dev",
    "build": "next build"
  }
}

المشكلة تبدأ في المشاريع التي تحتوي على إعدادات Webpack مخصصة (custom Webpack configuration).

إذا كان next.config.js يحتوي على تعريف مخصص لـ webpack()، فقد يؤدي انتقال Next.js 16 مباشرة إلى Turbopack إلى نتائج غير متوقعة. وفي بعض الحالات يمكن أن يوقف Next.js عملية build بدلاً من الاستمرار باستخدام configuration غير متوافق.

إذا كنت بحاجة إلى الاستمرار باستخدام Webpack:

next dev --webpack
next build --webpack

أصبح Turbopack ناضجاً إلى حد كبير، لكنه لا يقدم بعد بديلاً مطابقاً بالكامل لكل إضافات Webpack البرمجية. لذلك يجب فحص المشاريع الكبيرة التي تعتمد على Sentry أو custom loaders أو عمليات Sass مخصصة أو إضافات Webpack أخرى قبل الترحيل.

بدلاً من اتباع منطق «وصل Turbopack، إذن سأحذف Webpack مباشرة»، أفضّل أولاً مقارنة development وproduction build باستخدام الأداتين.

أصبحت params وsearchParams وcookies() وheaders() غير متزامنة بالكامل

كان Next.js 15 قد بدأ بالفعل في تهيئة المطورين لهذا التغيير.

أصبحت request-time API مثل params وsearchParams وcookies() وheaders() وdraftMode() غير متزامنة (asynchronous) منذ الإصدار 15. ولكن كان من الممكن استخدام الوصول المتزامن مؤقتاً للحفاظ على التوافق مع الإصدارات السابقة.

في Next.js 16 انتهى هذا الدعم.

تمت إزالة الوصول المتزامن بالكامل.

على سبيل المثال، كان من الممكن سابقاً كتابة:

export default function Page({
  params,
}: {
  params: { slug: string }
}) {
  const { slug } = params

  return <div>{slug}</div>
}

أما في Next.js 16 فيجب أن يصبح:

export default async function Page({
  params,
}: {
  params: Promise<{ slug: string }>
}) {
  const { slug } = await params

  return <div>{slug}</div>
}

وينطبق الأمر نفسه على cookies().

الاستخدام السابق:

import { cookies } from 'next/headers'

const cookieStore = cookies()
const token = cookieStore.get('token')

الاستخدام الجديد:

import { cookies } from 'next/headers'

const cookieStore = await cookies()
const token = cookieStore.get('token')

في مشاريع App Router الكبيرة، ستكون هذه من أولى النقاط التي أبحث عنها بعد الترحيل.

ولا يقتصر الأمر على ملفات page.tsx وحدها. فقد يتم استخدام params أيضاً داخل layouts وRoute Handlers وgenerateMetadata وOpen Graph image routes وأجزاء أخرى من التطبيق.

كما يمكن لـ Next.js إنشاء type helper مثل PageProps وLayoutProps وRouteContext باستخدام:

npx next typegen

middleware.ts يفسح المجال لـ proxy.ts

هناك تغيير ملحوظ آخر يتعلق بالتسمية.

في Next.js 16 أصبح convention الخاص بـ middleware.ts deprecated، وحل محله ملف proxy.ts الجديد. والهدف هو توضيح أن هذه الطبقة ليست middleware عامة على طريقة Express، بل تعمل عند network boundary أمام التطبيق.

سابقاً:

// middleware.ts

export function middleware(request: NextRequest) {
  // ...
}

الآن:

// proxy.ts

export function proxy(request: NextRequest) {
  // ...
}

كما يوجد codemod منفصل لتنفيذ migration:

npx @next/codemod@canary middleware-to-proxy .

ولا يقتصر التغيير على اسم الملف. بل يُنصح أيضاً بتغيير اسم الدالة المصدّرة من middleware إلى proxy بالمثل.

لكن النقطة الأكثر أهمية تتعلق ببيئة التشغيل (runtime).

يعمل proxy.ts على Node.js runtime ولا يمكن تغيير runtime يدوياً. لذلك يجب تقييم Middleware implementations الحالية التي تعتمد على Edge runtime بشكل منفصل.

إذا كان المشروع يستخدم Middleware بشكل مكثف في authentication أو locale redirects أو rewrites أو authorization، فيجب اختبار هذا الجزء بعناية.

تمت إزالة next lint

قد يبدو هذا التغيير بسيطاً، لكنه قد يؤدي بسهولة إلى تعطل خط التكامل المستمر (CI pipeline).

في Next.js 16 تمت إزالة:

next lint

كما أن next build لم يعد يشغّل lint تلقائياً. فقد تم فصل عملية linting عن framework build، وأصبح من المتوقع استخدام ESLint CLI مباشرة.

إذا كان package.json يحتوي على:

{
  "scripts": {
    "lint": "next lint"
  }
}

يمكن تغييره مثلاً إلى:

{
  "scripts": {
    "lint": "eslint ."
  }
}

كما يمكن أن يساعد migration codemod في هذا التحويل.

إذا كان CI/CD pipeline يشغّل npm run lint قبل build، فيجب إضافة هذه النقطة إلى قائمة التحقق الخاصة بالترحيل.

تغيرت القيم الافتراضية في next/image

أجرى Next.js 16 أيضاً بعض التغييرات على القيم الافتراضية الخاصة بتحسين الصور (image optimization).

على سبيل المثال، ارتفعت القيمة الافتراضية لـ images.minimumCacheTTL من 60 ثانية إلى 4 ساعات. كما أصبحت [75] هي القيمة الافتراضية لجودة الصور بدلاً من النطاق الأوسع السابق.

إذا كان المشروع يستخدم:

<Image
  src="/product.jpg"
  width={800}
  height={600}
  quality={100}
  alt="Product"
/>

وأردت الحفاظ على quality={100}، فقد تحتاج إلى تعريف ذلك صراحة في configuration:

const nextConfig = {
  images: {
    qualities: [50, 75, 100],
  },
}

export default nextConfig

هناك أيضاً breaking change آخر يتعلق باستخدام query string داخل روابط الصور المحلية (local image URLs).

على سبيل المثال:

<Image
  src="/assets/product.jpg?v=2"
  width={500}
  height={500}
  alt="Product"
/>

إذا كنت تستخدم URLs من هذا النوع، فقد تحتاج الآن إلى تعريف images.localPatterns بشكل مناسب.

هذه النقطة مهمة بشكل خاص في مشاريع e-commerce وCMS، حيث تكون image URLs ديناميكية في كثير من الأحيان.

Cache Components وrevalidateTag() وupdateTag(): تخزين مؤقت أكثر وضوحًا

كان caching من أكثر المواضيع إرباكاً في الإصدارات الرئيسية الأخيرة من إطار Next.js البرمجي.

أسئلة مثل «لماذا تم cache لهذا fetch؟» و«لماذا أصبح هذا route static؟» و«لماذا لم تظهر revalidation مباشرة؟» مألوفة تقريباً لكل من عمل مع موجّه التطبيقات (App Router).

في Next.js 16 تتجه هذه المنظومة إلى نموذج أكثر وضوحًا (explicit).

يمكن تفعيل Cache Components عبر:

const nextConfig = {
  cacheComponents: true,
}

export default nextConfig

ثم يسمح directive "use cache" بالتحكم بشكل أوضح في component أو function التي يجب تخزينها مؤقتاً. كما انتقل نهج experimental.ppr السابق إلى نموذج Cache Components الجديد.

هناك نقطة مهمة هنا:

لست مضطراً إلى استخدام Cache Components لمجرد أنك تنتقل إلى الإصدار 16.

أثناء migration، لا أفضّل إعادة تصميم caching architecture بالكامل في الإيداع (commit) نفسه. من الأفضل أولاً تثبيت migration إلى framework الجديد، ثم التعامل مع Cache Components كمهمة منفصلة.

الجمع بين major version migration وتغيير caching architecture في الوقت نفسه يجعل تحديد مصدر الخطأ أكثر صعوبة.

تغير revalidateTag() ووصل updateTag(): هناك أيضاً تغييرات مهمة على مستوى واجهات التخزين المؤقت (caching API).

أصبح الأسلوب الموصى به لـ revalidateTag() هو استخدام معامل ثانٍ لتحديد cacheLife profile:

import { revalidateTag } from 'next/cache'

revalidateTag('blog-posts', 'max')

يؤدي ذلك إلى اعتبار cache الحالي stale وفق أسلوب stale-while-revalidate، ثم جلب المحتوى الجديد في الخلفية (background).

أما الاستخدام بمعامل واحد فأصبح مهملًا (deprecated).

كما يقدم Next.js 16 API جديداً باسم updateTag().

'use server'

import { updateTag } from 'next/cache'

export async function updateProfile() {
  // database update

  updateTag('user-profile')
}

تم تصميم updateTag() للحالات التي يجب أن يرى فيها المستخدم أحدث نسخة من البيانات فوراً بعد إجراء تعديل. ويمكن استخدام هذه الواجهة فقط داخل إجراءات الخادم (Server Actions).

يمكن تلخيص الفرق بالنسبة لي كالتالي:

استخدم revalidateTag() للمحتوى مثل المدونات والكتالوجات والتوثيق، حيث لا تمثل بضع ثوانٍ من التأخير مشكلة. واستخدم updateTag() عندما يحتاج المستخدم إلى رؤية تغييره فوراً.

React Compiler أصبح Stable، لكنك لست مضطراً لتفعيله

أصبح دعم React Compiler مستقرًا (stable) في الإصدار 16.

يهدف React Compiler إلى تقليل عمليات render غير الضرورية من خلال memoization تلقائية للمكونات (components). لكنه غير مفعّل افتراضياً.

لتفعيله:

const nextConfig = {
  reactCompiler: true,
}

export default nextConfig

كما يجب تثبيت حزمة compiler:

npm install -D babel-plugin-react-compiler

وأفضّل اتباع النهج نفسه هنا أثناء migration:

أكمل أولاً migration إلى Next.js 16 وتأكد من application behavior، ثم قيّم React Compiler كخطوة optimization منفصلة.

يضيف React Compiler عملاً إضافياً إلى build pipeline، ولذلك يمكن أن ترتفع مدة البناء في بيئتي التطوير والإنتاج.

ما الذي يجب اختباره بعد الانتقال إلى Next.js 16؟

نجاح code compilation لا يعني أن migration اكتملت.

قبل الانتقال إلى production أفضّل التحقق من النقاط التالية:

  •  هل تستخدم Node.js وTypeScript وReact وNext.js بإصدارات مدعومة؟
  •  هل تعمل development وproduction build بشكل صحيح مع Turbopack؟
  •  إذا كان هناك custom Webpack configuration، فهل تمت مراجعة توافقه مع Turbopack؟
  •  هل تمت إزالة الاستخدامات المتزامنة لـ params وsearchParams وcookies() وheaders() وdraftMode()؟
  •  هل تمت مراجعة migration من middleware.ts إلى proxy.ts؟
  •  هل تعمل authentication وredirects وrewrites وlocale routing بشكل صحيح؟
  •  هل تم تحديث scripts وCI pipelines التي تستخدم next lint؟
  •  هل تم اختبار quality وcache وlocal URL الخاصة بـ next/image؟
  •  هل يعمل ISR وcache invalidation وتحديث البيانات بعد Server Actions كما هو متوقع؟
  •  هل تم اختبار dynamic routes وgenerateMetadata؟
  •  هل تم فحص صفحات production المهمة باستخدام Lighthouse ومسارات استخدام حقيقية؟

ومن الأفضل أيضاً تنفيذ migration في branch منفصل ومقارنة build الجديد على Next.js 16 بالإصدار الحالي على Next.js 15 بدلاً من تنفيذ التحديث مباشرة في فرع الإنتاج (production branch).

كيف ينبغي التخطيط للانتقال إلى Next.js 16؟

لا ينبغي أن يكون الانتقال إلى إصدار رئيسي جديد هدفاً بحد ذاته. بالنسبة إلى تطبيق Next.js يتم تطويره باستمرار وسيظل مستخدماً لفترة طويلة، فإن البقاء قريباً من الإصدار الرئيسي الحالي يمكن أن يوفر مزايا مهمة من حيث تحديثات الأمان وتطور إطار العمل ودعم المنظومة المحيطة (ecosystem).

لكن migration غير المخطط لها قد تضيف مخاطر غير ضرورية في تطبيقات production الكبيرة التي تعتمد بشكل كبير على custom Webpack plugins أو Edge Middleware أو السلوك القديم لإطار العمل.

لذلك من الأفضل التعامل مع major version migration كمشروع تقني صغير، وليس كمجرد تحديث عادي للاعتماديات (dependencies).

للوهلة الأولى يبرز Next.js 16 بميزات مثل Turbopack وReact Compiler وCache Components وغيرها. لكن عند migration لمشروع قائم، فإن breaking changes هي النقاط التي تحتاج إلى أكبر قدر من الاهتمام.

جعل Turbopack الخيار الافتراضي يؤثر على build pipeline، وasync Request APIs تؤثر على App Router code، والانتقال إلى proxy.ts يغيّر request layer، كما تؤثر تغييرات ESLint على CI/CD، ويمكن أن تؤثر caching APIs الجديدة مباشرة في استراتيجية تحديث البيانات.

أفضل ترتيب يمكن اتباعه واضح وبسيط:

التوافق أولاً، ثم الترحيل، ثم التحسين.

ابدأ بتحديث dependencies وبيئة التشغيل، ثم عالج breaking changes وتأكد من أن سلوك التطبيق الحالي ما زال يعمل كما هو متوقع. وبعد استقرار migration يمكن تفعيل ميزات مثل Turbopack وCache Components وReact Compiler بشكل تدريجي ومدروس.

لأن الانتقال إلى Next.js 16 واستخدام جميع ميزاته الجديدة في الوقت نفسه ليسا الشيء نفسه.

وبفضل codemods وأدوات upgrade التي يوفرها Next.js، فإن الانتقال من Next.js 15 إلى 16 لا يجب أن يكون معقداً أو مؤلماً إذا تم تنفيذ الخطوات بالترتيب الصحيح.

إذا كنت ترغب في تطوير تطبيق ويب قابل للتوسع وعالي الأداء باستخدام تقنيات حديثة، أو تحديث البنية التقنية لمشروع قائم، فيمكن لـ Detartech التعامل مع المشروع بشكل متكامل من خلال حلول تطوير الويب التي يقدمها.

إذا أردت تطبيق ترحيل كهذا في مشروعك، اطّلع على خدمة تطوير الويب لدينا، وعلى صفحتي تقنية Next.js وTypeScript في موقعنا.

الأسئلة الشائعة

ما إصدار Node.js المطلوب لتشغيل Next.js 16؟ يلزم Node.js 20.9.0 وTypeScript 5.1.0 على الأقل، ولم يعد Node.js 18 مدعومًا. ولا يكفي تحديث البيئة المحلية، بل يجب مراجعة صورة Node في ملف Dockerfile وخط CI/CD وخادم الإنتاج أيضًا.

هل الانتقال إلى Turbopack إلزامي في Next.js 16؟ لا. فهو الأداة الافتراضية لأمري next dev وnext build، لكن يمكن مواصلة البناء عبر Webpack بالأمر next build --webpack عند وجود إعدادات مخصصة. والأفضل مقارنة البناء بالأداتين أولًا.

ماذا أفعل بملف middleware.ts في الإصدار 16؟ أصبح هذا الملف مهملًا وحل محله ملف proxy.ts، ويُنصح بتغيير اسم الدالة المصدّرة إلى proxy كذلك. ويعمل proxy.ts في بيئة تشغيل Node.js دون إمكانية تغييرها، لذلك يجب فحص التطبيقات المعتمدة على بيئة Edge بشكل منفصل.

هل يجب تفعيل Cache Components وReact Compiler فورًا؟ لا، فهما ليسا شرطًا للانتقال. والأسلم تثبيت الترحيل أولًا ثم تفعيلهما كمهام منفصلة، حتى يسهل تحديد مصدر أي خطأ.

لماذا تعطل خط التكامل المستمر بعد التحديث؟ السبب الشائع هو إزالة أمر next lint، إذ لم يعد next build يشغّل الفحص تلقائيًا. استبدل السكربت بأداة ESLint مباشرة، مثل الأمر eslint . في ملف الحزمة.

خدمات ذات صلة

تقنيات ذات صلة

هل لديك مشروع؟

دعنا نطبق التقنيات المذكورة في هذا المقال على مشروعك.

اطلب استشارة مجانية