الفرق بين المراجعتين لصفحة: «Next.js/environment variables»
لا ملخص تعديل |
جميل-بيلوني (نقاش | مساهمات) ط مراجعة |
||
سطر 1: | سطر 1: | ||
<noinclude>{{DISPLAYTITLE:متغيرات البيئة في Next.js}}</noinclude | <noinclude>{{DISPLAYTITLE:متغيرات البيئة Environment Variables في Next.js}}</noinclude>تدعم Next.js متغيرات البيئة التي تسمح لك بما يلي: | ||
* استخدام <code>env.local.</code> لتحميل متغيرات البيئة. | * استخدام <code>env.local.</code> لتحميل متغيرات البيئة. | ||
* كشف متغيرات البيئة للمتصفح بإضافة البادئة <code>_NEXT_PUBLIC</code>. | * كشف متغيرات البيئة للمتصفح بإضافة البادئة <code>_NEXT_PUBLIC</code>. | ||
== تحميل متغيرات البيئة | == تحميل متغيرات البيئة == | ||
تدعم Next.js تحميل متغيرات البيئة من الملف <code>env.local.</code> إلى <code>process.env</code>. إليك مثالًا:<syntaxhighlight lang="bash"> | تدعم Next.js تحميل متغيرات البيئة من الملف <code>env.local.</code> إلى <code>process.env</code>. إليك مثالًا:<syntaxhighlight lang="bash"> | ||
DB_HOST=localhost | DB_HOST=localhost | ||
DB_USER=myuser | DB_USER=myuser | ||
DB_PASS=mypassword | DB_PASS=mypassword | ||
</syntaxhighlight>تُحمِّل الشيفرة السابقة <code>process.env.DB_HOST</code> و <code>process.env.DB_USER</code> و <code>process.env.DB_PASS</code> إلى بيئة عمل Node.js تلقائيًا مما يسمح لك باستخدام [[Next.js/data fetching|طرق Next.js في إحضار البيانات]] واستخدام [[Next.js/api routes| | </syntaxhighlight>تُحمِّل الشيفرة السابقة <code>process.env.DB_HOST</code> و <code>process.env.DB_USER</code> و <code>process.env.DB_PASS</code> إلى بيئة عمل Node.js تلقائيًا مما يسمح لك باستخدام [[Next.js/data fetching|طرق Next.js في إحضار البيانات]] واستخدام [[Next.js/api routes|واجهة التوجيه]]. | ||
إليك مثالًا باستخدام <code>getStaticProps</code>:<syntaxhighlight lang="javascript"> | إليك مثالًا باستخدام <code>getStaticProps</code>:<syntaxhighlight lang="javascript"> | ||
سطر 22: | سطر 21: | ||
// ... | // ... | ||
} | } | ||
</syntaxhighlight>'''ملاحظة''': لتُبقي الأمور الحساسة الموجودة فقط على الخادم محمية، تُستبدل | </syntaxhighlight>'''ملاحظة''': لتُبقي الأمور الحساسة الموجودة فقط على الخادم محمية، تُستبدل متغيرات البيئة بالقيمة الصحيحة أثناء بناء التطبيق. يعني ذلك أن الكائن <code>process.env</code> ليس كائنًا معياريًا في JavaScript، ولن تكون قادرًا على تفكيك الكائن. لا بد من الإشارة إلى متغيرات البيئة كالتالي:<syntaxhighlight lang="javascript"> | ||
process.env.PUBLISHABLE_KEY; | process.env.PUBLISHABLE_KEY; | ||
// أو | // أو | ||
const { PUBLISHABLE_KEY } = process.env; | const { PUBLISHABLE_KEY } = process.env; | ||
</syntaxhighlight>'''ملاحظة''': تُوسِّع Next.js تلقائيًا المتغيّر <code>VAR$</code> ضمن | </syntaxhighlight>'''ملاحظة''': تُوسِّع Next.js تلقائيًا المتغيّر <code>VAR$</code> ضمن ملف متغيرات البيئة ويساعدك ذلك في الإشارة إلى أمور محمية أخرى: <syntaxhighlight lang="bash"> | ||
# .env | # .env | ||
HOSTNAME=localhost | HOSTNAME=localhost | ||
PORT=8080 | PORT=8080 | ||
HOST=http://$HOSTNAME:$PORT | HOST=http://$HOSTNAME:$PORT | ||
</syntaxhighlight>'''ملاحظة''': إن أردت استخدام متغير يحتوي على المحرف <code>$</code> ضمن قيمته الفعلية، لا بد من تجاوز المحرف كالتالي <code>$\</code>. إليك مثالًا:<syntaxhighlight lang="bash"> | </syntaxhighlight>'''ملاحظة''': إن أردت استخدام متغير يحتوي على المحرف <code>$</code> ضمن قيمته الفعلية، لا بد من تجاوز أو تهريب المحرف كالتالي <code>$\</code>. إليك مثالًا:<syntaxhighlight lang="bash"> | ||
# .env | # .env | ||
A=abc | A=abc | ||
سطر 42: | سطر 41: | ||
</syntaxhighlight>'''ملاحظة''': إن كنت تستخدم المجلّد <code>src/</code> فلا بد من تنبيهك أن Next.js تحمّل الملفات من المجلد الأب فقط وليس من المجلد <code>src/</code>. | </syntaxhighlight>'''ملاحظة''': إن كنت تستخدم المجلّد <code>src/</code> فلا بد من تنبيهك أن Next.js تحمّل الملفات من المجلد الأب فقط وليس من المجلد <code>src/</code>. | ||
== كشف متغيرات البيئة للمتصفح | == كشف متغيرات البيئة للمتصفح == | ||
تُعد متغيرات البيئة متغيرات في بيئة Node.js وبالتالي لن تكون متاحة في بيئة المتصفح. ولكي تكشف متغيرات البيئة للمتصفح، لا بد من إضافة البادئة <code>_NEXT_PUBLIC</code> إلى المتغير. إليك مثالًا:<syntaxhighlight lang="bash"> | |||
NEXT_PUBLIC_ANALYTICS_ID=abcdefghijk | NEXT_PUBLIC_ANALYTICS_ID=abcdefghijk | ||
</syntaxhighlight>يحمّل ذلك <code>process.env.NEXT_PUBLIC_ANALYTICS_ID</code> إلى بيئة عمل Node.js تلقائيًا مما يسمح باستخدامها في أي مكان من الشيفرة. ستُوضَّب هذه القيمة ضمن شيفرة JavaScript التي تُرسل إلى المتصفح نظرًا لوجود البادئة <code>_NEXT_PUBLIC</code>. تجري عملية التوضيب أثناء بناء التطبيق وبالتالي لابد أن تُضبط قيم جميع متغيرات البيئة التي تمتلك تلك البادئة قبل بناء المشروع.<syntaxhighlight lang="javascript"> | </syntaxhighlight>يحمّل ذلك <code>process.env.NEXT_PUBLIC_ANALYTICS_ID</code> إلى بيئة عمل Node.js تلقائيًا مما يسمح باستخدامها في أي مكان من الشيفرة. ستُوضَّب هذه القيمة ضمن شيفرة JavaScript التي تُرسل إلى المتصفح نظرًا لوجود البادئة <code>_NEXT_PUBLIC</code>. تجري عملية التوضيب أثناء بناء التطبيق وبالتالي لابد أن تُضبط قيم جميع متغيرات البيئة التي تمتلك تلك البادئة قبل بناء المشروع.<syntaxhighlight lang="javascript"> | ||
سطر 58: | سطر 57: | ||
export default HomePage | export default HomePage | ||
</syntaxhighlight>انتبه إلى أن الاستدعاء الديناميكي مع متغيرات البيئة آنذاك لن يعمل مثل:<syntaxhighlight lang="javascript"> | |||
// لن تعمل | |||
const varName = 'NEXT_PUBLIC_ANALYTICS_ID' | |||
setupAnalyticsService(process.env[varName]) | |||
// لن تعمل | |||
const env = process.env | |||
setupAnalyticsService(env.NEXT_PUBLIC_ANALYTICS_ID) | |||
</syntaxhighlight> | </syntaxhighlight> | ||
== متغيرات البيئة | == متغيرات البيئة الافتراضية == | ||
لا نحتاج عادة إلى أكثر من الملف <code>env.local.</code> | لا نحتاج عادة إلى أكثر من الملف <code>env.local.</code> لكنك قد تحتاج أحيانًا إلى إضافة بعض القيم الافتراضية لمرحلة التطوير <code>next dev</code> أو مرحلة الإنتاج <code>next start</code>. تتيح لك Next.js ضبط القيم الافتراضية في ملف <code>env.</code> لكلتا المرحلتين ضمن ملفين مستقلين، الأول <code>env.development.</code> لمرحلة التطوير والثاني <code>env.production.</code> لمرحلة الإنتاج. وتذكر أن <code>env.local.</code> يلغي القيم التي تضبطها في أي ملف آخر. | ||
'''ملاحظة''': لا بد من وضع الملفات <code>env.</code> و <code>env.development.</code> و <code>env.production.</code> في مستودعك لأنها تعرّف قيمًا افتراضية. كما ينبغي وضع الملفات <code>env | '''ملاحظة''': لا بد من وضع الملفات <code>env.</code> و <code>env.development.</code> و <code>env.production.</code> في مستودعك لأنها تعرّف قيمًا افتراضية. كما ينبغي وضع الملفات <code>env*.local.</code> في ملف التجاهل <code>gitignore.</code> لأننا ننوي أصلًا تجاهلها. وتذكر أن <code>env.local.</code> هو المكان الذي تُخزّن فيه المعلومات والمفاتيح السرية التي لا يجب أن يطلع عليها أحد. | ||
== تهيئة متغيرات البيئة لتعمل على منصة Vercel | == تهيئة متغيرات البيئة لتعمل على منصة Vercel == | ||
يمكن تهيئة متغيرات البيئة من خلال [https://vercel.com/docs/environment-variables إعدادات المشروع] عند نشر تطبيق Next.js على [https://vercel.com/ Vercel]. | يمكن تهيئة متغيرات البيئة من خلال [https://vercel.com/docs/environment-variables إعدادات المشروع] عند نشر تطبيق Next.js على [https://vercel.com/ Vercel]. تُهيأ جميع متغيرات البيئة في هذا المكان حتى تلك المستخدمة في مرحلة التطوير والتي يمكن [https://vercel.com/docs/environment-variables#development-environment-variables تنزيلها على حاسوبك] بعد ذلك. | ||
إن هيَّأت متغيرات بيئة لمرحلة التطوير، يمكنك سحبها إلى داخل الملف <code>env.local.</code> لاستخدامها على حاسوبك من خلال الأمر التالي:<syntaxhighlight lang="bash"> | إن هيَّأت متغيرات بيئة لمرحلة التطوير، يمكنك سحبها إلى داخل الملف <code>env.local.</code> لاستخدامها على حاسوبك من خلال الأمر التالي:<syntaxhighlight lang="bash"> | ||
vercel env pull .env.local | vercel env pull .env.local | ||
</syntaxhighlight> | </syntaxhighlight> | ||
== اختبار متحولات البيئة في Next.js == | == اختبار متحولات البيئة في Next.js == | ||
بالإضافة إلى | بالإضافة إلى بيئتي التطوير والإنتاج التي يمكن إضافة متغيرات لهما، ستجد خيارًا ثالثًا هو بيئة الاختبار، إذ يمكن وضع القيم الافتراضية لغايات الاختبار فقط بنفس الطريقة التي تضبط فيها تلك القيم في المرحلتين السابقتين، اي بإنشاء ملف <code>env.test.</code> لمرحلة الاختبار (على الرغم من أن استخدامه ليس شائعًا كمثيليه السابقين). | ||
يُستخدم الملف | يُستخدم هذا الملف عندما تُجري الاختبارات بأدوات مثل "jest" أو "cypress" وتريد ضبط متغيرات بيئة لأغراض الاختبار فقط. تُحمَّل القيم الافتراضية تلقائيًا إن جرى ضبط <code>NODE_ENV</code> بيئة العمل على <code>test</code> وبالتالي لا حاجة لأن تفعل ذلك بنفسك بل ستفعلها أداة الاختبار بالنيابة عنك. | ||
هنالك فرق ضئيل بين مرحلة الاختبار <code>test</code> ومرحلتي التطوير <code>development</code> والإنتاج <code>production</code> لابد أن تتذكره دائمًا: لن يُحمّل الملف <code>env.local.</code> لأن | هنالك فرق ضئيل بين مرحلة الاختبار <code>test</code> ومرحلتي التطوير <code>development</code> والإنتاج <code>production</code> لابد أن تتذكره دائمًا: لن يُحمّل الملف <code>env.local.</code> لأن بيئة الاختبار تحاكي بيئة الانتاج التي يفترض أنها ستكون متاحة للجميع. لهذا السبب، تستخدم الاختبارات جميعها نفس القيم الافتراضية وتتجاهل قيم الملف <code>env.local.</code> (والمخصص لتجاوز مجموعة القيم الافتراضية). | ||
'''ملاحظة''': لا بد من وضع الملف <code>env.test.</code> في مستودعك وليس الملف <code>env.test.local.</code> لأننا ننوي تجاهل الملفات<code>env | '''ملاحظة''': لا بد من وضع الملف <code>env.test.</code> في مستودعك وليس الملف <code>env.test.local.</code> لأننا ننوي تجاهل الملفات<code>env*.local.</code> في <code>gitignore.</code>. | ||
تأكد عندما تُجري اختبارات وحدة unit tests أن تُحمِّل متغيرات البيئة بالطريقة التقليدية من خلال الدالة <code>loadEnvConfig</code> الموجودة في الحزمة <code>@next/env</code>.<syntaxhighlight lang="javascript"> | تأكد عندما تُجري اختبارات وحدة unit tests أن تُحمِّل متغيرات البيئة بالطريقة التقليدية من خلال الدالة <code>loadEnvConfig</code> الموجودة في الحزمة <code>@next/env</code>.<syntaxhighlight lang="javascript"> | ||
// العام وبشكل مشابه لملف Jest يمكن استخدام هذه الشيفرة في ملف إعداد | // العام وبشكل مشابه لملف Jest يمكن استخدام هذه الشيفرة في ملف إعداد | ||
// إعداد الاختبار الخاص بك | // إعداد الاختبار الخاص بك | ||
سطر 93: | سطر 99: | ||
== ترتيب تحميل متغيرات البيئة في Next.js == | == ترتيب تحميل متغيرات البيئة في Next.js == | ||
وفقًا للبيئة التي تختارها (كما ضُبطت في <code>NODE_ENV</code>)، تُحمَّل متغيرات البيئة | وفقًا للبيئة التي تختارها (كما ضُبطت في <code>NODE_ENV</code>)، تُحمَّل متغيرات البيئة الأعلى إلى الأسفل بالترتيب التالي المذكور وانتبه إلى عملية تحميل المتغير تتوقف متى ما عثر على قيمته أولًا وتهمل الملفات الأخرى اللاحقة. | ||
#<code>process.env</code> | |||
#<code>env.$(NODE_ENV).local.</code> | |||
#<code>env.local.</code> | |||
#<code>env.$(NODE_ENV).</code> | |||
#<code>env.</code> | |||
أي إن ضُبطت <code>NODE_ENV</code> إلى <code>development</code> وعرفت متغير بيئة في الملف <code>env.development.local.</code> والملف <code>env.</code> فالقيمة التي ستستعمل هي المعرفة في الملف الأول وتهمل تلك المعرفة في الملف <code>env.</code>. | |||
'''ملاحظة''': القيم المسموحة من أجل <code>NODE_ENV</code> هي: <code>production</code> أو <code>development</code> أو <code>test</code>. | |||
== أمثلة == | |||
* [https://github.com/vercel/next.js/tree/canary/examples/environment-variables Environment Variables] | |||
== المصادر == | == المصادر == | ||
* الصفحة [https://nextjs.org/docs/basic-features/environment-variables Environment Variables] من توثيق Next.js الرسمي | * الصفحة [https://nextjs.org/docs/basic-features/environment-variables Environment Variables] من توثيق Next.js الرسمي. |
مراجعة 19:21، 8 نوفمبر 2022
تدعم Next.js متغيرات البيئة التي تسمح لك بما يلي:
- استخدام
env.local.
لتحميل متغيرات البيئة. - كشف متغيرات البيئة للمتصفح بإضافة البادئة
_NEXT_PUBLIC
.
تحميل متغيرات البيئة
تدعم Next.js تحميل متغيرات البيئة من الملف env.local.
إلى process.env
. إليك مثالًا:
DB_HOST=localhost
DB_USER=myuser
DB_PASS=mypassword
تُحمِّل الشيفرة السابقة process.env.DB_HOST
و process.env.DB_USER
و process.env.DB_PASS
إلى بيئة عمل Node.js تلقائيًا مما يسمح لك باستخدام طرق Next.js في إحضار البيانات واستخدام واجهة التوجيه.
إليك مثالًا باستخدام getStaticProps
:
// pages/index.js
export async function getStaticProps() {
const db = await myDB.connect({
host: process.env.DB_HOST,
username: process.env.DB_USER,
password: process.env.DB_PASS,
})
// ...
}
ملاحظة: لتُبقي الأمور الحساسة الموجودة فقط على الخادم محمية، تُستبدل متغيرات البيئة بالقيمة الصحيحة أثناء بناء التطبيق. يعني ذلك أن الكائن process.env
ليس كائنًا معياريًا في JavaScript، ولن تكون قادرًا على تفكيك الكائن. لا بد من الإشارة إلى متغيرات البيئة كالتالي:
process.env.PUBLISHABLE_KEY;
// أو
const { PUBLISHABLE_KEY } = process.env;
ملاحظة: تُوسِّع Next.js تلقائيًا المتغيّر VAR$
ضمن ملف متغيرات البيئة ويساعدك ذلك في الإشارة إلى أمور محمية أخرى:
# .env
HOSTNAME=localhost
PORT=8080
HOST=http://$HOSTNAME:$PORT
ملاحظة: إن أردت استخدام متغير يحتوي على المحرف $
ضمن قيمته الفعلية، لا بد من تجاوز أو تهريب المحرف كالتالي $\
. إليك مثالًا:
# .env
A=abc
# "preabc" ستصبح قيمة المتغير
WRONG=pre$A
# "pre$A" ستصبح قيمة المتغيّر
CORRECT=pre\$A
ملاحظة: إن كنت تستخدم المجلّد src/
فلا بد من تنبيهك أن Next.js تحمّل الملفات من المجلد الأب فقط وليس من المجلد src/
.
كشف متغيرات البيئة للمتصفح
تُعد متغيرات البيئة متغيرات في بيئة Node.js وبالتالي لن تكون متاحة في بيئة المتصفح. ولكي تكشف متغيرات البيئة للمتصفح، لا بد من إضافة البادئة _NEXT_PUBLIC
إلى المتغير. إليك مثالًا:
NEXT_PUBLIC_ANALYTICS_ID=abcdefghijk
يحمّل ذلك process.env.NEXT_PUBLIC_ANALYTICS_ID
إلى بيئة عمل Node.js تلقائيًا مما يسمح باستخدامها في أي مكان من الشيفرة. ستُوضَّب هذه القيمة ضمن شيفرة JavaScript التي تُرسل إلى المتصفح نظرًا لوجود البادئة _NEXT_PUBLIC
. تجري عملية التوضيب أثناء بناء التطبيق وبالتالي لابد أن تُضبط قيم جميع متغيرات البيئة التي تمتلك تلك البادئة قبل بناء المشروع.
// pages/index.js
import setupAnalyticsService from '../lib/my-analytics-service'
//NEXT_PUBLIC_ نظرًا لوجود البادئة NEXT_PUBLIC_ANALYTICS_ID يمكن استخدام
setupAnalyticsService(process.env.NEXT_PUBLIC_ANALYTICS_ID)
function HomePage() {
return <h1>Hello World</h1>
}
export default HomePage
انتبه إلى أن الاستدعاء الديناميكي مع متغيرات البيئة آنذاك لن يعمل مثل:
// لن تعمل
const varName = 'NEXT_PUBLIC_ANALYTICS_ID'
setupAnalyticsService(process.env[varName])
// لن تعمل
const env = process.env
setupAnalyticsService(env.NEXT_PUBLIC_ANALYTICS_ID)
متغيرات البيئة الافتراضية
لا نحتاج عادة إلى أكثر من الملف env.local.
لكنك قد تحتاج أحيانًا إلى إضافة بعض القيم الافتراضية لمرحلة التطوير next dev
أو مرحلة الإنتاج next start
. تتيح لك Next.js ضبط القيم الافتراضية في ملف env.
لكلتا المرحلتين ضمن ملفين مستقلين، الأول env.development.
لمرحلة التطوير والثاني env.production.
لمرحلة الإنتاج. وتذكر أن env.local.
يلغي القيم التي تضبطها في أي ملف آخر.
ملاحظة: لا بد من وضع الملفات env.
و env.development.
و env.production.
في مستودعك لأنها تعرّف قيمًا افتراضية. كما ينبغي وضع الملفات env*.local.
في ملف التجاهل gitignore.
لأننا ننوي أصلًا تجاهلها. وتذكر أن env.local.
هو المكان الذي تُخزّن فيه المعلومات والمفاتيح السرية التي لا يجب أن يطلع عليها أحد.
تهيئة متغيرات البيئة لتعمل على منصة Vercel
يمكن تهيئة متغيرات البيئة من خلال إعدادات المشروع عند نشر تطبيق Next.js على Vercel. تُهيأ جميع متغيرات البيئة في هذا المكان حتى تلك المستخدمة في مرحلة التطوير والتي يمكن تنزيلها على حاسوبك بعد ذلك.
إن هيَّأت متغيرات بيئة لمرحلة التطوير، يمكنك سحبها إلى داخل الملف env.local.
لاستخدامها على حاسوبك من خلال الأمر التالي:
vercel env pull .env.local
اختبار متحولات البيئة في Next.js
بالإضافة إلى بيئتي التطوير والإنتاج التي يمكن إضافة متغيرات لهما، ستجد خيارًا ثالثًا هو بيئة الاختبار، إذ يمكن وضع القيم الافتراضية لغايات الاختبار فقط بنفس الطريقة التي تضبط فيها تلك القيم في المرحلتين السابقتين، اي بإنشاء ملف env.test.
لمرحلة الاختبار (على الرغم من أن استخدامه ليس شائعًا كمثيليه السابقين).
يُستخدم هذا الملف عندما تُجري الاختبارات بأدوات مثل "jest" أو "cypress" وتريد ضبط متغيرات بيئة لأغراض الاختبار فقط. تُحمَّل القيم الافتراضية تلقائيًا إن جرى ضبط NODE_ENV
بيئة العمل على test
وبالتالي لا حاجة لأن تفعل ذلك بنفسك بل ستفعلها أداة الاختبار بالنيابة عنك.
هنالك فرق ضئيل بين مرحلة الاختبار test
ومرحلتي التطوير development
والإنتاج production
لابد أن تتذكره دائمًا: لن يُحمّل الملف env.local.
لأن بيئة الاختبار تحاكي بيئة الانتاج التي يفترض أنها ستكون متاحة للجميع. لهذا السبب، تستخدم الاختبارات جميعها نفس القيم الافتراضية وتتجاهل قيم الملف env.local.
(والمخصص لتجاوز مجموعة القيم الافتراضية).
ملاحظة: لا بد من وضع الملف env.test.
في مستودعك وليس الملف env.test.local.
لأننا ننوي تجاهل الملفاتenv*.local.
في gitignore.
.
تأكد عندما تُجري اختبارات وحدة unit tests أن تُحمِّل متغيرات البيئة بالطريقة التقليدية من خلال الدالة loadEnvConfig
الموجودة في الحزمة @next/env
.
// العام وبشكل مشابه لملف Jest يمكن استخدام هذه الشيفرة في ملف إعداد
// إعداد الاختبار الخاص بك
import { loadEnvConfig } from '@next/env'
export default async () => {
const projectDir = process.cwd()
loadEnvConfig(projectDir)
}
ترتيب تحميل متغيرات البيئة في Next.js
وفقًا للبيئة التي تختارها (كما ضُبطت في NODE_ENV
)، تُحمَّل متغيرات البيئة الأعلى إلى الأسفل بالترتيب التالي المذكور وانتبه إلى عملية تحميل المتغير تتوقف متى ما عثر على قيمته أولًا وتهمل الملفات الأخرى اللاحقة.
process.env
env.$(NODE_ENV).local.
env.local.
env.$(NODE_ENV).
env.
أي إن ضُبطت NODE_ENV
إلى development
وعرفت متغير بيئة في الملف env.development.local.
والملف env.
فالقيمة التي ستستعمل هي المعرفة في الملف الأول وتهمل تلك المعرفة في الملف env.
.
ملاحظة: القيم المسموحة من أجل NODE_ENV
هي: production
أو development
أو test
.
أمثلة
المصادر
- الصفحة Environment Variables من توثيق Next.js الرسمي.