التصدير الثابت (Static Exports)

يتيح Next.js البدء كموقع ثابت أو تطبيق صفحة واحدة (SPA)، ثم الترقية لاحقًا بشكل اختياري لاستخدام ميزات تتطلب خادمًا.

عند تشغيل next build، يقوم Next.js بإنشاء ملف HTML لكل مسار. من خلال تقسيم تطبيق SPA صارم إلى ملفات HTML فردية، يمكن لـ Next.js تجنب تحميل كود JavaScript غير الضروري على جانب العميل، مما يقلل حجم الحزمة ويُمكن من تحميل الصفحات بشكل أسرع.

بما أن Next.js يدعم هذا التصدير الثابت، فيمكن نشره واستضافته على أي خادم ويب يمكنه تقديم أصول ثابتة من نوع HTML/CSS/JS.

معلومة مفيدة: نوصي باستخدام موجه التطبيق (App Router) لدعم محسن للتصدير الثابت.

التهيئة

لتمكين التصدير الثابت، قم بتغيير وضع الإخراج داخل next.config.js:

next.config.js
/**
 * @type {import('next').NextConfig}
 */
const nextConfig = {
  output: 'export',

  // اختياري: تغيير الروابط `/me` -> `/me/` وإنشاء `/me.html` -> `/me/index.html`
  // trailingSlash: true,

  // اختياري: منع التحويل التلقائي `/me` -> `/me/`، والحفاظ على `href` كما هو
  // skipTrailingSlashRedirect: true,

  // اختياري: تغيير دليل الإخراج `out` -> `dist`
  // distDir: 'dist',
}

module.exports = nextConfig

بعد تشغيل next build، سينشئ Next.js مجلد out الذي يحتوي على أصول HTML/CSS/JS لتطبيقك.

يمكنك استخدام getStaticProps و getStaticPaths لإنشاء ملف HTML لكل صفحة في دليل pages الخاص بك (أو أكثر لـ المسارات الديناميكية).

الميزات المدعومة

يتم دعم معظم ميزات Next.js الأساسية اللازمة لبناء موقع ثابت، بما في ذلك:

تحسين الصور

يمكن استخدام تحسين الصور عبر next/image مع التصدير الثابت عن طريق تعريف محمل صور مخصص في next.config.js. على سبيل المثال، يمكنك تحسين الصور باستخدام خدمة مثل Cloudinary:

next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
  output: 'export',
  images: {
    loader: 'custom',
    loaderFile: './my-loader.ts',
  },
}

module.exports = nextConfig

سيحدد هذا المحمل المخصص كيفية جلب الصور من مصدر بعيد. على سبيل المثال، سيقوم المحمل التالي ببناء عنوان URL لـ Cloudinary:

export default function cloudinaryLoader({
  src,
  width,
  quality,
}: {
  src: string
  width: number
  quality?: number
}) {
  const params = ['f_auto', 'c_limit', `w_${width}`, `q_${quality || 'auto'}`]
  return `https://res.cloudinary.com/demo/image/upload/${params.join(
    ','
  )}${src}`
}
export default function cloudinaryLoader({ src, width, quality }) {
  const params = ['f_auto', 'c_limit', `w_${width}`, `q_${quality || 'auto'}`]
  return `https://res.cloudinary.com/demo/image/upload/${params.join(
    ','
  )}${src}`
}

يمكنك بعد ذلك استخدام next/image في تطبيقك، مع تحديد مسارات نسبية للصورة في Cloudinary:

import Image from 'next/image'

export default function Page() {
  return <Image alt="turtles" src="/turtles.jpg" width={300} height={300} />
}
import Image from 'next/image'

export default function Page() {
  return <Image alt="turtles" src="/turtles.jpg" width={300} height={300} />
}

الميزات غير المدعومة

الميزات التي تتطلب خادم Node.js، أو المنطق الديناميكي الذي لا يمكن حسابه أثناء عملية البناء، غير مدعومة:

النشر

مع التصدير الثابت، يمكن نشر Next.js واستضافته على أي خادم ويب يمكنه تقديم أصول ثابتة من نوع HTML/CSS/JS.

عند تشغيل next build، ينشئ Next.js التصدير الثابت في مجلد out. على سبيل المثال، لنفترض أن لديك المسارات التالية:

  • /
  • /blog/[id]

بعد تشغيل next build، سينشئ Next.js الملفات التالية:

  • /out/index.html
  • /out/404.html
  • /out/blog/post-1.html
  • /out/blog/post-2.html

إذا كنت تستخدم مضيفًا ثابتًا مثل Nginx، فيمكنك تكوين إعادة كتابة من الطلبات الواردة إلى الملفات الصحيحة:

nginx.conf
server {
  listen 80;
  server_name acme.com;

  root /var/www/out;

  location / {
      try_files $uri $uri.html $uri/ =404;
  }

  # هذا ضروري عندما `trailingSlash: false`.
  # يمكنك حذف هذا عندما `trailingSlash: true`.
  location /blog/ {
      rewrite ^/blog/(.*)$ /blog/$1.html break;
  }

  error_page 404 /404.html;
  location = /404.html {
      internal;
  }
}

سجل الإصدارات

الإصدارالتغييرات
v14.0.0تمت إزالة next export لصالح "output": "export"
v13.4.0أضاف موجه التطبيق (App Router) دعمًا محسنًا للتصدير الثابت، بما في ذلك استخدام مكونات خادم React ومعالجات المسار.
v13.3.0أصبح next export قديمًا واستُبدل بـ "output": "export"