Backالعودة إلى المدونة

الإصدار 13.2 من Next.js

يُقدّم Next.js 13.2 تحسينات كبيرة لموجه التطبيق (App Router) استعدادًا للإصدار المستقر، بما في ذلك دعم تحسين محركات البحث (SEO)، ومعالجات المسارات (Route Handlers)، وMDX لمكونات الخادم (Server Components)، وروابط آمنة بالنوع (Type-Safe Links)، والمزيد.

يتضمن Next.js 13.2 تحسينات كبيرة لموجه التطبيق (app) استعدادًا للإصدار المستقر:

قم بالتحديث اليوم عن طريق تشغيل:

Terminal
npm i next@latest react@latest react-dom@latest eslint-config-next@latest

دعم مدمج لتحسين محركات البحث مع واجهة برمجة تطبيقات البيانات الوصفية الجديدة

صُمم Next.js منذ البداية لـتمكين التحسين لمحركات البحث.

إن تقديم محتوى HTML مقدم التجهيز لا يساعد فقط في تحسين الفهرسة لمحركات البحث، بل يحسن أيضًا أداء تطبيقك. بينما وفر Next.js واجهة برمجة تطبيقات بسيطة لتعديل البيانات الوصفية في تطبيقك (next/head) لعدة إصدارات، أردنا إعادة تصميم وتعزيز كيفية التحسين لمحركات البحث باستخدام موجه التطبيق (app).

تسمح لك واجهة برمجة تطبيقات البيانات الوصفية الجديدة بتعريف البيانات الوصفية (مثل علامات meta و link داخل عنصر head في HTML) باستخدام تكوين بيانات وصفية صريح في أي تخطيط أو صفحة تكون مكون خادم (Server Component).

app/layout.tsx
import type { Metadata } from 'next';
 
export const metadata: Metadata = {
  title: 'الصفحة الرئيسية',
  description: 'مرحبًا بك في Next.js',
};

هذه الواجهة بسيطة وقابلة للتكوين ومصممة لتكون متوافقة مع عرض الخادم المتدفق (streaming server rendering). على سبيل المثال، يمكنك تعيين سمات البيانات الوصفية الشائعة في تخطيط الجذر لتطبيقك بالكامل، وتكوين ودمج كائنات البيانات الوصفية معًا للمسارات الأخرى في تطبيقك.

يتضمن ذلك دعمًا للبيانات الوصفية الديناميكية وكذلك الثابتة:

layout.js / page.js
// بيانات وصفية ثابتة
export const metadata = {
  title: '...',
};
 
// بيانات وصفية ديناميكية
export async function generateMetadata({ params, searchParams }) {
  const product = await getProduct(params.id);
  return { title: product.title };
}

جميع خيارات البيانات الوصفية متاحة، بما في ذلك القدرة على توفير بيانات وصفية مخصصة، مع دعم TypeScript من خلال المكوّن الإضافي TypeScript أو بإضافة النوع Metadata.

على سبيل المثال، يمكنك تعريف صور Open Graph عبر البيانات الوصفية:

app/layout.tsx
export const metadata = {
  openGraph: {
    title: 'Next.js',
    description: 'إطار عمل React للويب',
    url: 'https://nextjs.org',
    siteName: 'Next.js',
    images: [
      {
        url: 'https://nextjs.org/og.png',
        width: 800,
        height: 600,
      },
    ],
    locale: 'en-US',
    type: 'website',
  },
};
 
export default function Layout({ children }) {}

واجهة برمجة تطبيقات البيانات الوصفية متاحة في الإصدار 13.2 لموجه التطبيق (app)، لتحل محل ملف head.js الخاص السابق. وهي غير متاحة لمجلد pages.

تعلم المزيد عن تحسين محركات البحث أو شاهد مرجع واجهة برمجة التطبيقات للبيانات الوصفية. نود أن نشكر next-seo على عملهم في الحزمة المجتمعية وملاحظاتهم على تصميم واجهة برمجة التطبيقات الأولية.

معالجات المسارات المخصصة

كانت واجهات برمجة تطبيقات المسارات (API Routes) أحد الأجزاء المفقودة في الإصدار التجريبي الأول لموجه التطبيق (app)، والتي توجد في مجلد pages/api. أردنا اغتنام هذه الفرصة لإنشاء نسخة جديدة وأكثر حداثة من واجهات برمجة تطبيقات المسارات التي تم دمجها بعمق في نظام التوجيه الجديد لـ app.

تسمح لك معالجات المسارات (Route Handlers) بإنشاء معالجات طلبات مخصصة لمسار معين باستخدام واجهات برمجة تطبيقات الويب Request و Response.

app/example/route.ts
export async function GET(request: Request) {}

تمتلك معالجات المسارات واجهة برمجة تطبيقات متماثلة (isomorphic API) لدعم كل من بيئات التشغيل Edge وNode.js بسلاسة، بما في ذلك دعم الاستجابات المتدفقة. نظرًا لأن معالجات المسارات تستخدم نفس تكوين قطعة المسار مثل الصفحات والتخطيطات، فإنها تدعم ميزات طال انتظارها مثل العرض الثابت للأغراض العامة و إعادة التحقق.

يمكن لملف route.ts تصدير دالة غير متزامنة مسماة بأفعال HTTP: GET, HEAD, OPTIONS, POST, PUT, DELETE, و PATCH. يمكن بعد ذلك تغليف هذه الدوال وتجريدها لإنشاء مساعدات / منطق قابل لإعادة الاستخدام لمنطق المسار المخصص الخاص بك.

يمكن استخدام وظائف الخادم الأخرى، مثل cookies و headers، داخل معالجات المسارات - إلى جانب أي واجهات برمجة تطبيقات ويب تم بناء هذه التجريدات عليها. هذا يسمح بمشاركة التعليمات البرمجية بين مكونات الخادم ومعالجات المسارات.

app/example/route.ts
import { cookies } from 'next/headers';
 
export async function GET(request: Request) {
  const cookieStore = cookies();
  const token = cookieStore.get('token');
 
  return new Response('مرحبًا، Next.js!', {
    status: 200,
    headers: { 'Set-Cookie': `token=${token}` },
  });
}

معالجات المسارات متاحة في الإصدار 13.2 لموجه التطبيق (app) باستخدام الملف الخاص route.ts. وهي غير متاحة في مجلد pages، حيث إنها بديل لواجهات برمجة تطبيقات المسارات.

تعلم المزيد عن معالجات المسارات أو شاهد مرجع واجهة برمجة التطبيقات. نود أن نشكر SvelteKit على العمل السابق والإلهام هنا.

MDX لمكونات الخادم

MDX هو مجموعة شاملة من Markdown تتيح لك كتابة JSX مباشرة في ملفات Markdown الخاصة بك. إنها طريقة قوية لإضافة تفاعل ديناميكي وتضمين مكونات React داخل محتواك.

مع الإصدار 13.2، يمكنك الآن استخدام MDX بالكامل مع مكونات خادم React (React Server Components) - مما يعني كمية أقل من JavaScript على جانب العميل لتحميل صفحات أسرع، مع الاحتفاظ بقدرات React القوية لواجهة المستخدم الديناميكية. يمكنك رش التفاعلية في محتوى MDX الخاص بك حسب الحاجة.

تم تحديث المكوّن الإضافي @next/mdx لدعم ملف خاص جديد، mdx-components.js|ts، يتم تعريفه في جذر تطبيقك لتوفير مكونات مخصصة:

your-project/mdx-components.js
// يسمح لك هذا الملف بتوفير مكونات React مخصصة
// لاستخدامها في ملفات MDX. يمكنك استيراد واستخدام أي
// مكون React تريده، بما في ذلك مكونات من
// مكتبات أخرى.
function H1({ children }) {
  // ...
}
 
function H2({ children }) {
  // ...
}
 
export function useMDXComponents(components) {
  return { h1: H1, h2: H2, ...components };
}

علاوة على ذلك، تعاونا مع حزم المجتمع لجلب محتوى MDX next-mdx-remote و contentlayer لإضافة دعم لمكونات خادم React.

تعلم المزيد حول كيفية إعداد MDX مع مكونات الخادم أو نشر مثالنا.

محلل MDX بلغة Rust

كجزء من تمكين MDX لمكونات الخادم، قمنا أيضًا بإعادة كتابة محلل MDX بلغة Rust لتحسين الأداء. هذا تحسن كبير عن المحلل القائم على JavaScript السابق، الذي شهد تباطؤًا ملحوظًا عند معالجة عدد كبير من ملفات MDX.

يمكنك اختيار استخدام محلل Rust في next.config.js. على سبيل المثال، مع @next/mdx:

next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
  experimental: {
    appDir: true,
    mdxRs: true,
  },
};
 
const withMDX = require('@next/mdx')();
module.exports = withMDX(nextConfig);

نود أن نشكر Titus Wormer الذي رعينا عمله في هذا المشروع. إذا كنت ترغب في استخدام هذا خارج Next.js، تحقق من الحزمة الجديدة mdxjs-rs.

روابط ذات أنواع ثابتة

يمكن لـ Next.js الآن كتابة الروابط في مجلد app بشكل ثابت لمنع الأخطاء المطبعية والأخطاء الأخرى عند استخدام next/link، مما يحسن سلامة النوع عند التنقل بين الصفحات.

import Link from 'next/link'
 
// ✅
<Link href="/about" />
// ✅
<Link href="/blog/nextjs" />
// ✅
<Link href={`/blog/${slug}`} />
 
// ❌ أخطاء TypeScript إذا لم يكن href مسارًا صالحًا
<Link href="/aboot" />

تتطلب هذه الميزة استخدام موجه التطبيق الجديد (App Router)، بالإضافة إلى TypeScript.

next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
  experimental: {
    appDir: true,
    typedRoutes: true,
  },
};
 
module.exports = nextConfig;

هذه الميزة متاحة الآن في النسخة التجريبية (beta). لا يزال rewrites و redirects غير مدعومين.

تعلم المزيد عن المسارات ذات الأنواع الثابتة.

لوحة أخطاء محسنة

للمساعدة في تحسين قابلية القراءة والقدرة على تصحيح الأخطاء، قمنا بعدد من التحسينات على لوحة أخطاء Next.js.

في الإصدار 13.2، تم فصل آثار مكدس Next.js وReact الآن، مما يسهل تحديد مصدر الخطأ. بالإضافة إلى ذلك، تعرض لوحة الأخطاء الآن الإصدار الحالي من Next.js، مما يساعدك على فهم ما إذا كان إصدارك محدثًا.

لوحة الأخطاء المحسنة في الإصدار 13.2 تظهر تقادم الإصدار.

لوحة الأخطاء المحسنة في الإصدار 13.2 تظهر تقادم الإصدار.

لقد قمنا أيضًا بتحسين إخراج الأخطاء لأخطاء ترطيب React، والتي أصبحت الآن أكثر قابلية للقراءة وأسهل في التصحيح.

تحسينات Turbopack

Turbopack، الذي أُعلن عنه في النسخة التجريبية مع Next.js 13، هو حزمة تدريجية مصممة لتسريع كل من التطوير المحلي، وكذلك عمليات البناء للإنتاج في المستقبل.

ركزنا على دعم ميزات Next.js الحالية في Turbopack وتحسين الاستقرار العام بينما نتجه نحو النسخة التجريبية. منذ آخر إصدار لدينا، أضفنا:

  • دعم لـ next/dynamic
  • دعم لـ rewrites, redirects, headers, و pageExtensions في next.config.js
  • دعم لصفحات 404 والأخطاء في pages
  • دعم لوحدات CSS composes: ... from ...
  • تحسين موثوقية التحديث السريع (Fast Refresh) واستعادة الأخطاء
  • تحسين معالجة أولوية CSS
  • تحسين التقييم في وقت الترجمة

لقد أصلحنا أيضًا العديد من الأخطاء وحسّنا الاستقرار أثناء اختبار Turbopack داخليًا مع بعض أكبر تطبيقات Next.js الداخلية لدينا ومع عملاء Vercel الأوائل.

تحويل ملفات مخصصة مع محمّلات Webpack

يُشحن Turbopack الآن مع دعم وتوافق لبعض محمّلات Webpack. هذا يعني أنه يمكنك استخدام العديد من المحمّلات من نظام Webpack البيئي لتحويل ملفات من أنواع مختلفة إلى JavaScript. المحمّلات مثل @mdx-js/loader, @svgr/webpack, و babel-loader مدعومة. تعلم المزيد حول تخصيص Turbopack.

على سبيل المثال، استخدم experimental.turbo.loaders لتكوين قائمة بالمحمّلات لكل امتداد ملف:

next.config.js
module.exports = {
  experimental: {
    turbo: {
      loaders: {
        '.md': [
          {
            // تنسيق الخيارات
            loader: '@mdx-js/loader',
            options: {
              format: 'md',
            },
          },
        ],
        '.svg': ['@svgr/webpack'],
      },
    },
  },
};

تحقق من مثال Turbopack باستخدام المحمّلات للحصول على مثال كامل.

أسماء مستعارة لحل المسارات على نمط Webpack

يمكن الآن تكوين Turbopack لتعديل حل الوحدات (module resolution) من خلال الأسماء المستعارة، على غرار resolve.alias في Webpack. قم بتكوين هذا من خلال experimental.turbo.resolveAlias:

next.config.js
module.exports = {
  experimental: {
    turbo: {
      resolveAlias: {
        underscore: 'lodash',
        mocha: { browser: 'mocha/browser-entry.js' },
      },
    },
  },
};

ذاكرة تخزين Next.js

يقدم Next.js 13.2 ذاكرة تخزين Next.js الجديدة (beta)، وهي تطور لـ ISR الذي يفتح:

  • ISR تدريجي على مستوى المكون
  • تحديثات أسرع دون طلبات شبكة
  • إعادة نشر أسرع لتغييرات التعليمات البرمجية للصفحات الثابتة

بالنسبة للصفحات الثابتة بالكامل، يعمل ISR بنفس الطريقة كما هو الحال اليوم. بالنسبة للصفحات التي تحتوي على جلب بيانات أكثر تفصيلاً، وخلطًا بين الثابت والديناميكي، تستخدم ذاكرة تخزين Next.js ذاكرة تخزين أكثر تفصيلاً وعابرة.

مع أساس مكونات خادم React وجلب البيانات المجاور في موجه تطبيق Next.js (app)، يمكنك الآن تغليف البيانات الثابتة أو الديناميكية جنبًا إلى جنب مع المكون المستهلك لها.

app/page.jsx
export default async function Page() {
  const [staticData, dynamicData, revalidatedData] = await Promise.all([
    // مخبأة حتى يتم إبطالها يدويًا
    fetch(`https://...`),
    // يتم جلبها في كل طلب
    fetch(`https://...`, { cache: 'no-store' }),
    // مخبأة بعمر 10 ثوانٍ
    fetch(`https://...`, { next: { revalidate: 10 } }),
  ]);
 
  return <div>...</div>;
}

أثناء التطوير محليًا مع موجه التطبيق، سترى الآن نفس سلوك التخزين المؤقت في next dev كما في الإنتاج مع next start. هذا يحسن سرعة التحديث السريع (Fast Refresh) عند تغيير أي مكون خادم أو كود جلب بيانات.

مع ذاكرة تخزين Next.js، يتحكم تطبيقك في الذاكرة المؤقتة - وليس واجهات برمجة التطبيقات الخارجية. هذا يختلف عن رؤوس cache-control، حيث يتحكم المصدر العلوي في مدة تخزين القيمة مؤقتًا.

ذاكرة التخزين المؤقت لـ Next.js مع واجهة برمجة تطبيقات التخزين المؤقت لـ Vercel

Next.js على Vercel تمنحك بنية تحتية محددة بإطار العمل. تقوم بكتابة كود التطبيق، مثل جلب البيانات على مستوى المكونات باستخدام fetch، ونقوم نحن ببناء بنية تحتية موزعة عالميًا لك دون جهد إضافي.

تجعل ذاكرة التخزين المؤقت الجديدة لـ Next.js تغيير الكود مستقلًا عن تغيير البيانات. هذا يمكن أن يسرع بشكل كبير إعادة نشر الصفحات الثابتة، حيث يمكن لإنشاء هذه الصفحات استخدام ذاكرة التخزين المؤقت الموجودة.

تم تصميم واجهة برمجة تطبيقات التخزين المؤقت الجديدة لـ Vercel للعمل مع أي إطار عمل، ولكن لها تكامل أصلي مع ذاكرة التخزين المؤقت لـ Next.js. تعلم المزيد حول كيف تطورت ISR إلى ذاكرة التخزين المؤقت لـ Next.js، وكذلك كيف تعمل ذاكرة التخزين المؤقت لـ Next.js عند النشر على Vercel.

ذاكرة التخزين المؤقت لـ Next.js عند الاستضافة الذاتية

عند الاستضافة الذاتية، يتم استخدام ذاكرة تخزين مؤقت من نوع LRU، والتي تكون افتراضيًا 50 ميجابايت. يتم كتابة جميع الإدخالات في ذاكرة التخزين المؤقت تلقائيًا على القرص افتراضيًا. يمكن مشاركة ذاكرة التخزين المؤقت لنظام الملفات بين العقد إذا كان لديها نفس مفتاح التخزين المؤقت، بشكل مشابه لكيفية عمل ISR اليوم.

بالنسبة للمطورين الذين يبحثون عن مزيد من التخصيص وتعديل جوهر ذاكرة التخزين المؤقت لـ Next.js، يمكنهم تعديل مفاتيح التخزين المؤقتة الأساسية وتغيير كيفية وأين يتم حفظ إدخالات التخزين المؤقت، بما في ذلك تعطيل الحفظ بالكامل.

تحسينات أخرى

  • الخطوط: بعد تبني مجتمعي مذهل، أصبح @next/font الآن مدمجًا في Next.js كـ next/font. هذا يعني أنك لم تعد بحاجة إلى تثبيت @next/font بشكل منفصل. تعلم المزيد.
  • الخطوط: تم تغيير خاصية font-display الافتراضية لـ next/font إلى font-display: swap بدلاً من optional بناءً على ملاحظات المجتمع.
  • الأداء: تم تحسين عملية البناء لاستخدام ذاكرة أقل، بحوالي 550 ميجابايت تم توفيرها في اختباراتنا (PR).
  • الأداء: تم تجنب تحميل تكوين المشروع عدة مرات، مما أدى إلى عمليات بناء أسرع بحوالي 400 مللي ثانية (في المتوسط) في اختباراتنا (PR).
  • الأداء: تم تحسين مكون الخطأ لتقليل 0.4 كيلوبايت من حمولة HTML دون تغيير التصميم (PR).
  • الأداء: تم تقليل حجم حزمة الحافة بحوالي 130 كيلوبايت، تقريبًا نصف الحجم، لمزيد من تقليل حجم التشغيل البارد عند النشر في بيئات الحافة مثل Vercel (PR).
  • الأمان: تمت إضافة تكوين images.contentDispositionType: "attachment" لفرض تنزيل الصور عند زيارة واجهة برمجة تطبيقات تحسين الصور مباشرة (PR).

المجتمع

Next.js هي نتيجة العمل المشترك لأكثر من 2500 مطور فردي، وشركاء صناعيين مثل Google و Meta، وفريقنا الأساسي في Vercel. مع أكثر من 3.9 مليون تنزيل أسبوعيًا من npm وأكثر من 100,000 نجمة على GitHub، تعد Next.js واحدة من أكثر الطرق شعبية لبناء الويب.

انضم إلى المجتمع على مناقشات GitHub، Reddit، و Discord.

تم إصدار هذا الإصدار بفضل:

و مساهمات: @timneutkens، @loettz، @okcoker، @clive-h-townsend، @shuding، @JanKaifer، @sepiropht، @hanneslund، @huozhi، @aralroca، @balazsorban44، @cristobaldominguez95، @vinaykulk621، @Brooooooklyn، @feedthejim، @samsisle، @MarDi66، @styfle، @therealrinku، @sebmarkbage، @cravend، @hu0p، @kdy1، @ijjk، @juzhiyuan، @IvanKiral، @LukeSchlangen، @wojtekolek، @samdenty، @Josehower، @bennettdams، @SCG82، @mike-plummer، @kwonoj، @David0z، @denchance، @joulev، @wbinnssmith، @alexkirsz، @UnknownMonk، @leerob، @sairajchouhan، @imranbarbhuiya، @jomeswang، @ductnn، @thomasballinger، @chibicode، @jridgewell، @sreetamdas، @Juneezee، @SukkaW، @wyattjoh، @michaeloliverx، @cattmote، @joefreeman، @valentincostam، @qrohlf، @ossan-engineer، @rishabhpoddar، @vasucp1207، @Schniz، @andrii-bodnar، @gergelyke، @abstractvector، @wherehows، @BrodaNoel، @taep96، @abe1272001، @0xadada، @nbouvrette، @teobler، @lubakravche، @molebox، و @hiddenest.