Next.js چیست؟ راهنمای جامع 2026 + پروژه عملی

?What is Next.js

04 خرداد 1405
what-is-nextjs-by-roxo

به‌روزرسانی ۲۰۲۶: Next.js 15 با بهبود عملکرد و پشتیبانی بهتر از React Server Components منتشر شده است. کلیه مثال‌های موجود این مقاله با آخرین نسخه سازگارند و برای پروژه‌های واقعی آماده‌ استفاده‌اند.

در این مقاله می‌خواهیم با فریم‌ورکی برای React به نام Next.js آشنا شویم. احتمالا خواندن این جمله برایتان عجیب باشد چرا که react خودش یک کتابخانه است بنابراین چطور می‌توانیم یک فریم‌ورک را برایش داشته باشیم!؟ در این مقاله به‌طور مفصل به این سوال پاسخ و دلایل استفاده از Next.js را توضیح می‌دهیم.

اگر به وب سایت Next.js بروید می‌بینید که جمله بزرگی در آن نوشته شده است:

The React Framework for Production

این جمله به معنی اینست که next یک فریم‌ورک react برای مرحله بهره‌برداری (production) است. می‌توان این جمله را به صورت Fullstack frarmework for React نیز نوشت؛ یعنی فریم‌ورکی که هم backend و هم frontend را برای کتابخانه React مدیریت می‌کند.

اگر از این جملات فنی دور شویم، می توانیم next.js را به زبان ساده تعریف کنیم: فریم‌ورکی که از react استفاده می‌کند و تمام برنامه شما (سمت سرور و سمت کلاینت) را برایتان می‌سازد. این فریم‌ورک قابلیت‌های بسیار بیشتری را نسبت به react به شما می‌دهد و در واقع react را توسعه می‌بخشد. توجه داشته باشید که در next.js هنوز هم کد react می‌نویسیم اما برای هر مسئله کوچکی نیاز به استفاده از کتابخانه‌های خارجی ندارید.

Next.js چیست؟ (به زبان خیلی ساده)

اگر در زمینه توسعه وب کار می‌کنید احتمالا نام Next.js را شنیده‌ یا در مورد آن کنجکاو شده‌اید. Next.js چیزی است که اغلب به عنوان «فریم‌ورک متا» شناخته می‌شود، یعنی فریمورکی که بر اساس یک یا چند فریمورک دیگر ساخته شده است – در این مورد، Next.js بر پایه React ایجاد شده است.

به‌طور ساده، Next.js یک فریمورک React برای توسعه برنامه‌های جاوااسکریپت تک‌صفحه‌ای (Single Page Application) است.

حالا چرا این مهم است؟ چون مزایای این فریم‌ورک، هم برای برنامه‌های کاربردی سمت کلاینت (مرورگر کاربر) و هم برای تیم توسعه (برنامه‌نویس‌ها) بسیار زیاد است. بگذارید صادق باشیم: سایت‌ها و برنامه‌هایی که سریع نیستند، انتظارات ما را برآورده نمی‌کنند. ما آن‌ها را دوست نداریم و معمولا از آن‌ها فرار می‌کنیم. یکی از مهم‌ترین مزایای Next.js، سرعت و عملکرد فوق‌العاده آن است.

اما فقط بحث سرعت نیست! Next.js یک فریم ورک جاوا اسکریپت است که به شما امکان می دهد دو نوع محصول خلق کنید:

  • وب سایت‌های ایستا (Static) که بسیار سریع و کاربرپسندند.
  • برنامه‌های کاربردی وب پویا (Dynamic) با استفاده از React

نکته جالب توجه اینست که Next.js به شما اجازه می‌دهد برنامه‌های ترکیبی بسازید. یعنی می‌توانید در یک پروژه، هم از صفحات رندر شده توسط سرور (Server-side rendering) استفاده کنید و هم از صفحات تولید شده به صورت ایستا (Static generation).

چرا Next.js محبوب است؟

Next.js به طور گسترده توسط بزرگ‌ترین و محبوب‌ترین شرکت‌ها در سراسر جهان مانند Netflix، Uber ،Starbucks یا Twitch استفاده می‌شود. اما چرا چنین شرکت‌های نامداری Next.js را انتخاب کرده‌اند؟ چون Next.js به‌عنوان یکی از سریع‌ترین فریم‌ورک‌های React مشهور شده است و خصوصا برای سایت‌های استاتیک خیلی مناسب است. جالب است بدانید که سایت‌های استاتیک اخیرا به یکی از جذاب‌ترین موضوعات در دنیای توسعه وب تبدیل شده‌اند.

به طور خلاصه دلایل محبوبیت فوق‌العاده Next.js عبارتند از:

  1. سرعت و کارایی فوق‌العاده: صفحات در میلی‌ثانیه بارگیری می‌شوند
  2. سئوی مطلوب: گوگل صفحات شما را کامل می‌بیند و ایندکس می‌کند
  3. توسعه سریع‌تر: امکانات آماده بدون نیاز به کتابخانه‌های جانبی باعث می‌شوند روند توسعه آن سریع‌تر باشد.
  4. فول‌استک با یک زبان: backend و frontend هر دو با جاوااسکریپت است.
  5. جامعه بزرگ و پشتیبانی Vercel: مستندات عالی و به‌روز دارد.

تفاوت Next.js و React

React یک کتابخانه برای ساخت رابط کاربری است، در حالی که Next.js یک فریم‌ورک کامل بر پایه React است. تفاوت کلیدی اینست که React فقط بخش UI را مدیریت می‌کند و برای کارهای دیگر (مثل روتینگ، سئو، یا ارتباط با سرور) باید از ابزارهای جانبی استفاده کنید ولی Next.js این امکانات را به صورت پیش‌فرض و یکپارچه در اختیارتان قرار می‌دهد.

سعی کرده‌ایم در یک جدول، مهم‌ترین تفاوت‌های Next.js و React را درج کنیم که در چند ثانیه تصمیم بگیرید که آیا اصلا Next.js به دردتان می‌خورد یا خیر؟

قابلیت React خالص Next.js
رندر کردن فقط Client-side SSR + SSG + ISR + Client
سئو (SEO) نیاز به تنظیمات اضافی عالی
روتینگ (Routing) کتابخانه جدا (React Router) فایل‌محور (built-in)
API routes نیاز به سرور جداگانه توکار
سرعت بارگذاری اولیه کندتر (spinner می‌بینید) خیلی سریع (میلی‌ثانیه)
یادگیری ساده متوسط (آسان بعد از React)
پیکربندی اولیه دستی (Webpack, Babel, ...) خودکار (zero-config)

بر اساس این جدول:

  • برای برنامه‌های داخلی، داشبوردهای ساده، پروژه‌های کوچک از React خالص استفاده کنید.
  • برای سایت‌های فروشگاهی، وبلاگ‌ها، پروژه‌هایی که سئو در آن‌ها اهمیت دارد از Next.js استفاده کنید.

۳ روش رندر در نکست جی اس: (SSR, SSG, ISR)

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

سه روش برای رندرینگ در Next.js وجود دارد که در واقع قلب تپنده آن هستند و انتخاب آن‌هاست که تعیین می‌کند یک سایت معمولی داشته باشید، یا یک سایت خیلی سریع. در این بخش این سه روش را بررسی می‌کنیم:

رندر در سمت سرور یا SSR

در Server-Side Rendering یا به اختصار SSR، صفحات در لحظه و به ازای هر درخواست کاربر روی سرور ساخته می‌شوند. یعنی هر بار که کاربر صفحه را باز می‌کند، داده از سرور واکشی می‌شود و صفحه از نو ساخته می‌شود.

// pages/profile.js
export async function getServerSideProps() {
  const res = await fetch('https://api.example.com/user')
  const user = await res.json()
  return { props: { user } }
}

مثال:
هنگامی که آدرس /about را در مرورگر باز کنیم، Next.js یک تابع بدون سرور را فراخوانی می‌کند. در نتیجه این فراخوانی، داده‌های مورد نیاز از backend واکشی می شوند و سپس صفحه About ساخته (رندر) می‌شود. به این تابع در اصطلاح لامبدا (Lambda) هم گفته می‌شود.

کاربردهای این قابلیت عبارتند از داشبورد کاربر، پنل ادمین، صفحات با اطلاعات لحظه‌ای (مثل قیمت ارز، وضعیت سفارش و غیره)

نکته: واکشی داده‌ها در متد getServerSideProps() انجام می‌شود. هر آنچه در این متد بنویسید، در سمت سرور اجرا می‌شود و کاربر به آن دسترسی ندارد.

پیش رندر یا SSG

پیش رندر که «رندر استاتیک» یا SSG (مخفف Static Site Generation) نیز نامیده می شود، روشی است که در آن صفحه در زمان ساختن (build) پروژه رندر می‌شود، نه هنگام درخواست کاربر. این فرآیند معمولا به‌عنوان بخشی از CI/CD انجام می‌شود. به عبارت دیگر صفحات یک‌بار در زمان build (قبل از اینکه سایت را روی سرور بگذارید) ساخته و به شکل فایل‌های HTML عادی ذخیره می‌شوند. بعد از آن، هر کاربری که وارد سایت شود، همین فایل آماده را دریافت می‌کند.

// pages/blog.js
export async function getStaticProps() {
  const res = await fetch('https://api.example.com/posts')
  const posts = await res.json()
  return { props: { posts } }
}

توانایی ترکیب صفحات SSR و SSG در یک پروژه، ویژگی منحصربه‌فرد Next.js بود و از آن زمان توسط سایر فریم‌ورک‌ها مانند Gatsby و Nuxt استفاده شده است.

کاربردهای این قابلیت عبارتند از: بلاگ، مستندات فنی، سایت‌های خبری و لندینگ پیج‌ها

ت

نکته: برای صفحات پویا (مثل blog/nextjs-tutorial) باید از متد getStaticPaths هم استفاده کنید تا مسیرها را به Next.js بشناسانید.

رندر معلق یا ISR

در Next.js، رندر معلق با نام «بازسازی استاتیک افزایشی» یا ISR (مخفف Incremental Static Regeneration) شناخته می‌شود که در ابتدا در نسخه 9.4 معرفی شد. این روش، شبیه SSG است با این تفاوت که صفحات می‌توانند در پس‌زمینه و بدون اینکه کاربر متوجه شود، به‌روز شوند. هدف ISR حذف زمان ساخت بسیار طولانی است که سایت‌های بزرگ اغلب با آن مواجه می‌شوند.

// pages/products/[id].js
export async function getStaticProps() {
  return {
    props: { product },
    revalidate: 60 // هر ۶۰ ثانیه یکبار در پس‌زمینه بازسازی می‌شود
  }
}

این قابلیت برای سایت‌های خیلی بزرگ که زمان build آنها ممکن است چندین دقیقه یا حتی ساعت طول بکشد. با ISR، صفحات پربازدید همیشه سریع بارگیری می‌شوند و صفحات کم‌بازدید در زمان مناسب ساخته می‌شوند.

کاربردهای این قابلیت عبارتند از: فروشگاه‌های بزرگ، کاتالوگ محصولات و سایت‌هایی که محتوای آن‌ها گاهی تغییر می‌کند (نه هر ثانیه) - همچنین می‌توانید از آن برای صفحاتی استفاده کنید که کاربران محتوا تولید می‌کنند (مثل نظرها، پست‌های انجمن).

مانند هر فریم‌ورک فرانت‌اند دیگر، Next.js نیز روش‌هایی برای رندر در سمت کلاینت دارد. اما SSR، SSG و ISR سه روش اصلی و قدرتمند آن محسوب می‌شوند.

در Next.js می‌توانید برای هر صفحه یکی از این روش‌ها را انتخاب کنید. حتی می‌توانید در یک پروژه، بعضی صفحات SSR، بعضی SSG و بقیه ISR باشند.

ویژگی‌های کلیدی Next.js

ویژگی های مهم Next.js

در این بخش می‌خواهیم به ویژگی‌ها و کاربردهای Next.js بپردازیم. این قسمت کمک می‌کند دقیقا درک کنید که بخش ابتدایی مقاله در مورد چه بود و بدانید Next دقیقا چه کاری را انجام می‌دهد.

۱. رندر در سمت سرور؛ مهم‌ترین ویژگی

همانطور که در قسمت قبلی توضیح دادیم Server-side Rendering به معنی رندر کردن صفحات (ساخت و نمایش آن‌ها) در سمت سرور است.

اگر با react کار کرده باشید می‌دانید که ما در react داده‌ها را از سرور گرفته و در سمت کلاینت (در مرورگر کاربر) از آن داده‌ها برای ساخت و نمایش صفحه (render کردن آن) استفاده می‌کنیم اما در SSR یعنی صفحات در سمت سرور ساخته می‌شوند و آماده به کاربر تحویل داده می‌شوند، درست مثل PHP قدیم. فرض کنید با React خالص یک وب‌سایت ساخته‌اید. اگر سورس کد صفحه را در مرورگر باز کنید، چیزی شبیه این می‌بینید:

<div id="root"></div>
<script src="bundle.js"></script>

می‌بینید که صفحه خالی است! چرا؟ زیرا در برنامه‌های تک‌صفحه‌ای یا SPA، صفحات واقعی وجود ندارند و همه‌چیز با جاوااسکریپت و به‌صورت پویا ساخته می‌شود. مشکلات این مسئله عبارتند از:

مشکل اول: منتظر ماندن کاربر
در ری‌اکت خالص سرور فایل‌های جاوااسکریپت را ارسال می‌کند، مرورگر آن‌ها را اجرا می‌نماید و تازه بعد از آن، داده از سرور واکشی شده و صفحه ساخته می‌شود. به همین خاطر است که در بسیاری از برنامه‌های SPA یک لودینگ یا اسپینر می‌بینید. این وقفه می‌تواند کاربر را فراری دهد.

مشکل دوم: سئو
خزنده‌های گوگل وقتی به سایت React خالص می‌رسند، ابتدا فقط یک صفحه خالی می‌بینند و چند لحظه طول می‌کشد تا محتوای اصلی صفحه را ببینند. چنین وقفه‌ای ممکن است به سئوی سایت شما ضربه بزند. حتی گاهی احتمال دارد که گوگل اصلا محتوای SPA را نبیند.

اینجاست که server-side rendering به ما کمک می‌کند. اگر صفحات ما در سمت سرور ساخته شده باشند و سپس ما آن صفحه آماده را به سمت کاربر ارسال کنیم دیگر از نظر سئو هیچ مشکلی نداریم. همچنین دیگر آن وقفه اولیه وجود ندارد و صفحات به صورت لحظه‌ای برای کاربر نمایش داده می‌شود.

در Next.js:

// pages/profile.js
export async function getServerSideProps() {
  const res = await fetch('https://api.example.com/user')
  const user = await res.json()
  return { props: { user } }
}

نکته: Next.js فقط صفحه اول را در سمت سرور می‌سازد و پس از آن، یک برنامه React عادی دارید و حرکت کاربر بین صفحات به صورت SPA خواهد بود. یعنی هم دارید از مزایای SSR (مانند سئو و سرعت اولیه) بهره‌مند می‌شوید، هم از تجربه کاربری روان React.
شاید بپرسید پس چه موقعی از React خالص استفاده می‌کنیم؟ پاسخ این است که React خالص برای برنامه‌های داخلی (مثل پنل ادمین) که سئو برایشان مهم نیست و توسط گوگل دیده نمی‌شوند، همچنان انتخابی عالی‌ است.

۲. File-based Routing (ناوبری فایل‌محور)

در React خالص برای مدیریت مسیرها باید از کتابخانه‌ای مثل react-router استفاده کنید و کلی کد اضافی بنویسید. اما در Next.js، ساختار پوشه‌ها و فایل‌ها، همان مسیرهای سایت شما هستند.

pages/
├── index.js       →  /
├── about.js       →  /about
├── blog/
│   ├── index.js   →  /blog
│   └── [slug].js  →  /blog/nextjs-tutorial

مزایا:

  1. برای تولید routeها هیچ نیازی به نوشتن کد نداریم بلکه Next.js خودش این کار را برایمان انجام می‌دهد.
  2. به دلیل نوشتن کد کمتر، خوانایی کدهایمان بالا رفته و از شلوغ شدن پروژه جلوگیری می‌کنیم.
  3. درک سیستم routing در این حالت بسیار ساده‌تر است و با نگاه انداختن به پوشه pages به‌راحتی می‌توانیم مسیرهای سایت خودمان را ببینیم.
  4. طبیعتا این سیستم routing تمام امکانات سیستم‌های مدرن ناوبری را دارد: مثلا به nested routes دسترسی دارید، به dynamic routes دسترسی دارید، به dynamic parameters دسترسی دارید و الی آخر.

// صفحه پویا برای بلاگ - pages/blog/[slug].js
import { useRouter } from 'next/router'

export default function BlogPost() {
  const router = useRouter()
  const { slug } = router.query  // slug همان نام فایل است
  return <h1>پست: {slug}</h1>
}

۳. Fullstack Capabilities (توانایی فول‌استک)

Next.js شما را به یک توسعه‌دهنده fullstack تبدیل می‌کند. یعنی بدون نیاز به سرور جداگانه، می‌توانید API بنویسید.

می‌دانیم که react برای سمت کلاینت (مرورگر کاربر) ساخته شده است اما سمت سرور چطور؟ Next.js جادوگر نیست که کدهای سمت سرور را برای شما بنویسد و چنین کاری در واقع اصلا امکانپذیر نیست. کاری که Next.js انجام می‌دهد ساده کردن ترکیب کد react با کد سمت سرور (منطق کاری سایت ما) است. اگر از Next.js استفاده کنید، ساخت یک API در سمت سرور برای کار با برنامه React بسیار آسان خواهد بود. بنابراین فرآیندهایی که به سرور و API نیاز دارند (مانند احراز هویت کاربران، دریافت داده، ذخیره‌سازی داده و غیره) به‌راحتی در دسترس شما خواهند بود.

// pages/api/hello.js - یک endpoint ساده
export default function handler(req, res) {
  res.status(200).json({ message: 'Hello World!' })
}

حالا آدرس /api/hello در دسترس است. احراز هویت، دریافت داده، ذخیره‌سازی در دیتابیس – همه در یک پروژه جاوااسکریپت.

شاید بپرسید مگر نمی‌توانیم با react عادی این کار را انجام دهیم؟ چرا، اما باید یک پروژه جداگانه برای backend بنویسید. در Next.js همه چیز یکپارچه و در کنار هم است.

۴. بهینه‌سازی خودکار (Automatic Optimization)

در Next.js خیلی از مشکلات عملکردی بدون نیاز به تنظیمات اضافی حل شده است. جدول زیر به برخی از بهینه‌سازی‌های خودکار Next.js اشاره می‌کند:

قابلیت توضیح
Code Splitting فقط کد موردنیاز هر صفحه بارگیری می‌شود (نه کل برنامه)
Image Optimization <Image> تصاویر را بهینه و با فرمت WebP ارائه می‌دهد
Font Optimization فونت‌ها بدون افت سرعت بارگیری می‌شوند
Fast Refresh تغییرات کد را بدون از دست دادن state صفحه اعمال می‌کند

// استفاده از Image به جای img معمولی
import Image from 'next/image'

export default function Home() {
  return (
    <Image 
      src="/hero.jpg" 
      width={800} 
      height={400} 
      alt="بنر اصلی"
    />
  )
}

مزایا و معایب Next.js

مثل هر ابزار دیگری در دنیای برنامه نویسی، Next.js نیز مزایا و معایب خودش را دارد ولی مزایای آن به‌مراتب بیشتر از معایب آن است:

جدول سریع برای مقایسه معایب و مزایای Next.js

مزایا معایب
سرعت بارگذاری عالی (میلی‌ثانیه) انعطاف‌ناپذیری در سیستم روتینگ
سئوی عالی محدودیت زبان سمت سرور (فقط Node.js)
توسعه سریع با ابزارهای آماده نداشتن state manager داخلی (نیاز به Redux یا Zustand)
پشتیبانی از TypeScript به صورت پیش‌فرض هزینه هاست برای SSR (نیاز به سرور Node)
جامعه بزرگ و مستندات عالی یادگیری اولیه (برای مبتدیان React)
یکپارچگی backend و frontend پلاگین‌های کمتر نسبت به React خالص

مزایای Next.js

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

رندر در سمت سرور: کامپوننت‌های React اول در سرور ساخته می‌شوند، بعد به مرورگر کاربر فرستاده می‌شوند. درنتیجه کاربر همان لحظه محتوای کامل را می‌بیند و نه خبری از صفحه سفید اولیه است، نه اسپینر آزاردهنده! نکته جالب اینکه شما کامپوننت‌های React را فقط یک بار می‌نویسید. Next.js خودش مسئول رندر دوباره آن‌ها در سمت کاربر است. یعنی زمان توسعه کمتر و خروجی بهتر.

تقسیم خودکار کد: Next.js به اندازه کافی کارآمد است و جاوااسکریپت و CSS را فقط برای هر صفحه که موردنیاز است، بارگیری می‌کند. یعنی چطور؟ یعنی کاربر وارد صفحه «درباره ما» می‌شود ولی کد صفحه «تماس با ما» را دانلود نمی‌کند. نتیجه: بارگذاری سریع‌تر، مصرف کمتر اینترنت کاربر، و رضایت بیشتر.

توسعه لذت‌بخش (Hot Module Replacement  یا HMR): HMR بیش‌تر برای توسعه‌دهندگان اهمیت دارد ولی نتیجه‌اش به نفع کاربران است. فرض کنید در حال نوشتن کد هستید. هر بار که تغییری می‌دهید، نیازی نیست صفحه را رفرش کنید. همان لحظه تغییر را در مرورگر می‌بینید، بدون اینکه حالت برنامه (مثل متن داخل فرم یا لاگین کاربر) از بین برود. نتیجه اینکه زمان توسعه و هزینه آن کمتر می‌شود.

به طور خلاصه، مزایای اصلی Next.js برای کسب و کارها عبارتند از:

  • بهبود فرآیند توسعه = توسعه‌ سریع‌تر + هزینه کمتر
  • عملکرد بهبودیافته = برنامه‌های سریع‌تر و ساده‌تر
  • سئوی بهتر = دیده شدن بیشتر در گوگل
  • تجربه کاربری روان‌تر = کاربر خوشحال‌تر = بازگشت دوباره

مزایای اصلی Next.js برای توسعه‌دهندگان عبارتند از:

  • صرفه‌جویی در زمان (خصوصا در پروژه‌های پیچیده)
  • عدم نیاز به پیکربندی اولیه: به شما امکان می‌دهد به جای منطق ساخت برنامه، روی منطق تجاری برنامه تمرکز کنید و برای کمک به شما، کامپایل و بسته‌بندی خودکار را فراهم می‌کند. به عبارت دیگر، Next از همان ابتدا برای production بهینه شده است.
  • تولید ایستاافزایشی: به شما این امکان را می‌دهد تا صفحات موجود را با رندر کردن دوباره آن‌ها در پس‌زمینه، به‌روزرسانی کنید. بنابراین محتوای استاتیک می‌تواند پویا شود.
  • ترکیبی از SSR و SSG در یک پروژه: صفحات در زمان ساخت یا زمان درخواست رندر می شوند.
  • پیشتیبانی از TypeScript: پیکربندی و کامپایل خودکار و بدون دردسر TypeScript.
  • بازخوانی سریع (Fast Refresh): تجربه ویرایش زنده و سریع.
  • پشتیبانی داخلی از CSS: امکان وارد کردن فایل‌های CSS از یک فایل جاوااسکریپت.

معایب استفاده از Next.js

تعداد مزایای Next بسیار زیاد است و به وضوح بیشتر از معایب آن است. بیایید برخی از نقاط ضعف Next.js را برشماریم:

عدم انعطاف پذیری سیستم routing: با اینکه سیستم routing مورد علاقه ماست اما قابل تغییر نیست. اگر شما دوست نداشته باشید از این سیستم استفاده کنید، هیچ راهی برای تغییر آن وجود ندارد و در هرحال مجبورید با آن کار کنید.

محدودیت زبان سمت سرور: فریم‌ورک Next.js تکنولوژی سمت سرور خود را Node انتخاب کرده است و تغییر آن ممکن نیست. مثلا اگر بخواهید به جای Node از زبان PHP استفاده کنید، ممکن نیست. حتی اگر بخواهید به جای Node از تکنولوژی بسیار مشابهی مانند Deno استفاده کنید، باز هم ممکن نیست.

نداشتن state manager داخلی: Next.js یک فریمورک کامل است، اما state manager ندارد. برای مدیریت وضعیت برنامه (مثل لاگین کاربر، سبد خرید، تم دارک/لایت) باید خودتان از Redux، Zustand یا Context API استفاده کنید.

هزینه مداوم: از آن جایی که Next.js صفحات داخلی زیادی را render نمی‌کند، قسمت frontend خود را باید ایجاد کنید، که هر از گاهی به تغییرات نیاز دارد. در نتیجه باید به یک توسعه‌دهنده پول پرداخت کنید.

پلاگین‌های کمتر: تعداد پلاگین‌های Next.js نسبت به React خالص کمتر است. ممکن است برای نیاز خاص خود پلاگین آماده پیدا نکنید.

منحنی یادگیری اولیه: اگر تازه با React آشنا شده‌اید، Next.js ممکن است در ابتدا سخت به نظر برسد. باید مفاهیم جدیدی مثل SSR، SSG، ISR و متدهای getStaticProps را یاد بگیرید.

با Next.js چه چیزی می‌توانید بسازید؟

با Next.js می توانید موارد زیر را بسازید:

دسته مثال
سایت‌های فروشگاهی فروشگاه آنلاین، عمده‌فروشی، مارکت‌پلیس
محصولات SaaS نرم‌افزارهای ابری، ابزارهای اشتراکی
داشبوردها پنل مدیریت، گزارش‌گیری، تحلیل داده
وب‌سایت‌های استاتیک مستندات، لندینگ پیج، وبلاگ
پورتال‌های سازمانی پنل کاربری، سامانه‌های داخلی
MVP نمونه اولیه برای جذب سرمایه
برنامه‌های تک صفحه‌ای (SPA) اپلیکیشن‌های تعاملی
رابط‌های کاربری پویا ابزارهای تحت وب با تعامل بالا
Jamstack سایت‌های فوق‌سریع با امنیت بالا

وب‌سایت‌های ساخته‌شده با Next.js

به لیست زیر نگاه کنید؛ این‌ها از بزرگ‌ترین برندهای دنیا هستند:

  • Nike - فروشگاه آنلاین
  • Twitch - پلتفرم استریم
  • Ferrari - سایت رسمی
  • Netflix - بخش تحقیق و توسعه
  • Uber - برخی صفحات
  • Starbucks - بخش سفارش آنلاین

یک پروژه کوچک با Next.js

برای آشنایی بهتر با این فریم‌ورک بیایید یک برنامه کوچک با آن بسازیم. نام این برنامه pokedex (دایره‌المعارف پوکمون) است.

این برنامه داده‌های خود را از  PokeAPI دریافت می‌کند و سپس آن‌ها را نمایش می‌دهد. صفحه اصلی این برنامه شامل لیست همه pokedexها با تصاویر است و اگر بر روی یکی از آن‌ها کلیک کنیم، صفحه جزئیات و اطلاعات مربوط به یک pokedex نمایش داده می‌شود.

تصویر کامل شده این برنامه را می‌توانید در زیر ببینید:

تصویر کامل پروژه
تصویر کامل پروژه

پیش از نوشتن پروژه مطمئن شوید node را در سیستم خود نصب کرده‌اید. برای نصب آن می‌توانید به سایت آن مراجعه کنید.

ابتدا یک پوشه خالی با نام pokedex ایجاد می‌کنیم. سپس آن را با vscode باز می‌کنیم. در vscode ترمینال را باز کرده و دستور زیر را برای ایجاد یک پروژه جدید Next.js می‌نویسیم:

نصب Next.js
نصب Next.js

نقطه پس از دستور npx create-next-app به معنی این است که پروژه را در همین پوشه ایجاد کن. پس از تمام شدن نصب پروژه، باید تصویر زیر را ببینیم:

ساختار پروژه
ساختار پروژه

برای دیدن پروژه باید دستور npm run dev را ترمینال بنویسیم و سپس Enter را بزنیم. پس از این کار می‌توانیم برنامه خود را در آدرس http://localhost:3000/ مشاهده کنیم:

قالب کلی Next.js
قالب کلی Next.js

تصویر بالا یک قالب کلی برای Next.js است. فایل اصلی این برنامه index.js است که در پوشه pages قرار دارد. این فایل به کمی تمیزکاری نیاز دارد.

این فایل را باز کنید و سپس کد زیر را در آن قرار دهید:

import Head from 'next/head'

export default function Home() {
  return (
    <div>
      <Head>
        <title>Create Next App</title>
        <link rel="icon" href="/favicon.ico" />
      </Head>

      <main>
        <h1 style={{color:"purple",textAlign:"center", direction: "rtl"}}>
        ساخت pokedex با Roxo
        </h1>
      </main>
    </div>
  )
}

پس از نوشتن کد بالا صفحه زیر را خواهیم دید: 

صفحه پس از تمیزکاری
صفحه پس از تمیزکاری

برای استایل‌دهی این پروژه از tailwindcss استفاده می‌کنیم. برای این کار دستور زیر را در ترمینال می‌نویسیم. (ابتدا باید ترمینال را متوقف کنیم سپس دستور را بنویسیم):

نصب tailwincss
نصب tailwincss

سپس برای پیکربندی tailwindcss دستور زیر را در ترمینال می‌نویسیم. اگر پیکربندی با موفقیت انجام شود باید پیام Created Tailwind CSS config file: tailwind.config.js را ببینید. مانند زیر:

پیکربندی tailwindcss
پیکربندی tailwindcss

همچنین پس از پیکربندی موفقیت‌آمیز باید فایل زیر به فایل‌های شما افزوده شده باشد:

فایل tailwind.config.js
فایل tailwind.config.js

فایل را باز کنید و کدهای زیر را در آن قرار دهید:

module.exports = {
  purge: ['./pages/**/*.{js,ts,jsx,tsx}', './components/**/*.{js,ts,jsx,tsx}'],
  theme: {
    extend: {},
  },
  variants: {  
    extend: {},
  },   
  plugins: [],
}

در ادامه کار یک فایل جدید در root خود به نام postcss.config.js ایجاد می‌کنیم و کد زیر را به آن اضافه می‌نماییم:

postcss.config.js
postcss.config.js

module.exports = {
    plugins: ['tailwindcss', 'postcss-preset-env'],
};


اکنون باید سراغ پوشه styles برویم. در این پوشه فایل Home.module.css را پاک می‌کنیم. سپس همه کدهای فایل globals.css را پاک کرده و کدهای زیر را در آن می‌نویسیم:

@tailwind base;

@tailwind components;

@tailwind utilities;

برای دیدن نتیجه استفاده از tailwindcss دوباره برنامه را با npm run dev اجرا می‌کنیم. پس از اجرا باید نوشته کوچک‌تر به‌نظر برسد. مانند زیر:

برای داشتن یک کامپوننت که اجزای دیگر را دربر گیرد، کامپوننت Layout.js را در یک پوشه جدید به نام components ایجاد می‌کنیم. کد زیر را در این کامپوننت می‌نویسیم:

import React from 'react'
import Head from 'next/head'

export default function Layout({title,children}) {
    return (
        <div className='bg-gray-300'>
            <Head>
                <title>{title}</title>
                <link rel="icon" href="/favicon.ico" />
            </Head>
            <main className='container mx-auto max-w-xl pt-8 min-h-screen'>
                {children}
            </main>
        </div>
       
    )
}

تگ main در بالا با tailwindcss استایل‌دهی شده است. برای آشنایی بیش‌تر با tailwindcss می‌توانید به نشانی سر بزنید. حال باید کامپوننت Layout.js را وارد index.js کنیم تا بتوانیم از آن استفاده کنیم. کد زیر را جایگزین کدهای پیشین index.js می‌کنیم:

import Head from 'next/head'
import Layout from "../components/Layout"

export default function Home() {
  return (
    <Layout title="Nextjs Pokedex">
        <h1 className="text-4xl mb-8 text-center">
            Nextjs Pokedex
        </h1>
    </Layout>
  )
}

پس از باز کردن صفحه باید تصویر زیر را ببینیم:

از pokeapi برای نمایش داده‌های خود استفاده می‌کنیم. با استفاده از تابع getStaticProps داده خود را از این api واکشی می‌کنیم. getStaticProps یک تابع همگام است که باید آن را در داخل کامپوننت page خود export کنیم که در این جا index.js است. در این تابع می‌توانیم هر کدی (بک‌اند) را که روی سرور بک‌اند اجرا می‌شود، بنویسیم.

یک مزیت دیگر این است که کدی که در داخل این تابع می‌نویسیم برای client قابل مشاهده نیست. اگر نیاز به ارتباط با دیتابیس داشته باشیم، این کار را در داخل این تابع انجام می‌دهیم و به این ترتیب پایگاه داده ما برای client قابل دستیابی نیست. تابع getStaticProps را در index.js تعریف می‌کنیم. کد آن در زیر آمده است:

export async function getStaticProps(context) {
  try {
      const res = await fetch('https://pokeapi.co/api/v2/pokemon?limit=150');
      const { results } = await res.json();
      const pokemon = results.map((pokemon, index) => {
          const paddedId = ('00' + (index + 1)).slice(-3);

          const image = `https://assets.pokemon.com/assets/cms2/img/pokedex/detail/${paddedId}.png`;
          return { ...pokemon, image };
      });
      return {
          props: { pokemon },
      };
  } catch (err) {
      console.error(err);
  }
}

در این تابع از trycatch برای نوشتن کد خود استفاده کرده‌ایم تا به این ترتیب خطاهای احتمالی را مدیریت کنیم. سپس با استفاده از fetch، داده‌های خود را از https://pokeapi.co/api/v2/pokemon?limit=150 واکشی می‌کنیم. از این api، صد و پنجاه pokemon وارد برنامه خود می‌کنیم. این داده‌های واکشی‌شده تصویر ندارند. برای اینکه برای هرکدام از آن‌ها یک تصویر مناسب نمایش دهیم، از https://assets.pokemon.com/assets/cms2/img/pokedex/full/001.png استفاده می‌کنیم.

اگر این url را باز کنیم، تصویر زیر را می‌بینیم:

تصویر pokemon
تصویر pokemon

در تصویر url ،001.png شماره اولین pokemon است. با تغییر این شماره می‌توان pokemon متفاوتی به دست آورد. در داده‌هایی که fetch به دست آورده است، map می‌کنیم و id هر pokemon را به دست آورده و در متغیر paddledId قرار می‌دهیم. برای تعریف تصویر از متغیر image استفاده می‌کنیم و از id موجود در paddledId برای به دست آوردن یک pokemon خاص استفاده می‌کنیم. paddledId را به جای شماره عکس می‌گذاریم.

این نکته را فراموش نکنید که حتما پس از شماره عکس، پسوند .png را قرار بدهید.

سپس یک شی جدید ایجاد می‌کنیم. این شی شامل pokemon و تصویر مناسب آن است. این را با return برمی‌گردانیم.

const pokemon = results.map((pokemon, index) => {
    const paddedId = ('00' + (index + 1)).slice(-3);

    const image = `https://assets.pokemon.com/assets/cms2/img/pokedex/detail/${paddedId}.png`;
    return { ...pokemon, image };
});

پس از آن باید pokemon را برگردانیم تا در فایل‌های دیگر بتوانیم از آن استفاده کنیم:

return {
    props: { pokemon },
};

برای نمایش pokemonها در بالای همین فایل (index.js) یعنی در کامپوننت Home تغییرات زیر را اعمال می‌کنیم:

export default function Home({ pokemon }) {
    return (
        <Layout title="NextJS Pokedex">
            <h1 className="text-4xl mb-8 text-center ">The Nextjs Pokedex</h1>
            <ul>
                {pokemon.map((pokeman, index) => (
                    <li key={index}>
                        <Link href={`/pokemon?id=${index + 1}`}>
                            <a className="border p-4 border-grey my-2 hover:shadow-md capitalize flex items-center text-lg bg-gray-200 rounded-md">
                                <img
                                    src={pokeman.image}
                                    alt={pokeman.name}
                                    className="w-20 h-20 mr-3"
                                />
                                <span className="mr-2 font-bold">
                                    {index + 1}.
                                </span>
                                {pokeman.name}
                            </a>
                        </Link>
                    </li>
                ))}
            </ul>
        </Layout>
    );
}

حالا اگر صفحه را باز کنیم باید تصویر زیر را ببینیم:

تصویر برنامه
تصویر برنامه

اگر روی هر pokemon کلیک کنیم، تصویر و جزئیات او نمایش داده نمی‌شود و با تصویر زیر روبهرو می‌شویم:

404

برای رفع این مشکل یک صفحه جدید به نام pokemon در پوشه pages ایجاد می‌کنیم و کد زیر را در آن قرار می‌دهیم:

import React from 'react';
import Layout from '../components/Layout';
import Link from 'next/Link';
export default function pokemon({ pokeman }) {
    return (
        <Layout title={pokeman.name}>
            <h1 className="text-4xl mb-2 text-center capitalize">
                {pokeman.id}. {pokeman.name}
            </h1>
            <img className="mx-auto" src={pokeman.image} alt={pokeman.name} />
            <p>
                <span className="font-bold mr-2">Weight:</span> {pokeman.weight}
            </p>
            <p>
                <span className="font-bold mr-2">Height:</span>
                {pokeman.height}
            </p>
            <h2 className="text-2xl mt-6 mb-2">Types</h2>
            {pokeman.types.map((type, index) => (
                <p key="index">{type.type.name}</p>
            ))}
            <p className="mt-10 text-center">
                <Link href="/">
                    <a className="text-2xl underline">Home</a>
                </Link>
            </p>
        </Layout>
    );
}

export async function getServerSideProps({ query }) {
    const id = query.id;
    try {
        const res = await fetch(`https://pokeapi.co/api/v2/pokemon/${id}`);
        const pokeman = await res.json();
        const paddedId = ('00' + id).slice(-3);
        pokeman.image = `https://assets.pokemon.com/assets/cms2/img/pokedex/detail/${paddedId}.png`;
        return {
            props: { pokeman },
        };
    } catch (err) {
        console.error(err);
    }
}

قسمت ابتدایی این کد برای استایل‌دهی صفحه است. این فایل برای نمایش تصویر و سایر جزییات pokemon به‌کار می‌رود. در این‌جا از تابع getServerSideProps استفاده می‌کنیم.

getServerSideProps به ما اجازه می‌دهد صفحه‌ای را که داده‌های آن باید در زمان درخواست واکشی شوند، از پیش رندر کنیم. در این تابع، داده‌ها دوباره از api واکشی می‌شوند و به‌جای اینکه همه آن‌ها نمایش داده شوند، یک pokemon نشان داده می‌شود. برای نمایش یک pokemon، از id آن استفاده می‌شود. این id از پارامتر query می‌آید. این id با pokemon ترکیب می‌شود و سپس شی نهایی برگردانده می‌شود.

پس از نوشتن کد بالا، اگر صفحه را دوباره نگاه کنیم، باید پس از کلیک کردن هر pokemon، تصویر و جزئیات مربوط به آن را ببینیم. مانند زیر:

صفحه pokemon
صفحه pokemon

تبریک! شما یک پروژه Next.js کامل با SSG، روتینگ پویا و استایل‌دهی مدرن ساختید. کد کامل این برنامه را می توانید از این نشانی دانلود کنید.

جمع‌بندی: آیا ارزشش را دارد که Next.js را یاد بگیرم؟

قطعاً بله. اگر با React کار می‌کنید، یادگیری Next.js شما را از یک توسعه‌دهنده frontend به یک توسعه‌دهنده fullstack تبدیل می‌کند.

دولوپرهای React که می‌خواهند سایتی ایجاد کنند که سئو در آن مهم است، فریلنسرهایی که لازم است برای مشتریان خود سایت‌هایی سریع ایجاد کنند، تیم‌هایی که فروشگاه اینترنتی راه انداخته‌اند یا استارتاپ SAAS دارند و هرکسی که از پیکربندی Webpack/Babel به ستوه آمده است باید Next.js را بیاموزد.

اما افرادی که فقط ابزارهای داخلی ایجاد می‌کنند یا فرم‌های ساده‌ای می‌سازند که سئو در آن‌ها مهم نیست و نیز کسانی که پروژه‌هایی دارند که که سرور Node در دسترس ندارند نیازی به یادگیری Next.js ندارند.

توصیه می‌کنیم مقاله زیر را که درباره آموزش کامل کار با Next.js است، از دست ندهید:

در یک مقاله جداگانه هم به بررسی قابلیت های جدید Next.js پرداخته‌ایم.

سوالات متداول (FAQ)

سوال: آیا برای یادگیری Next.js الزاما باید React هم بلد باشم؟

بله، Next.js یک فریمورک روی React است. بدون آشنایی با React (کامپوننت‌ها، props، state، hooks) نمی‌توانید از Next.js استفاده کنید.

سوال: Next.js برای چه پروژه‌هایی مناسب نیست؟

برنامه‌های خیلی ساده تک صفحه‌ای (مثل یک فرم نظرسنجی) نیازی به Next.js ندارند. برای چنین برنامه‌هایی React خالص یا حتی HTML ساده هم کافیست. همچنین چنانچه هاست شما از Node.js پشتیبانی نمی‌کند (هاست‌های ارزان اشتراکی)، نمی‌توانید از SSR استفاده کنید (اما SSG کار می‌کند).

سوال: آیا Next.js به درد فروشگاه اینترنتی هم می‌خورَد؟

بله، معرکه است! Nike، Netflix و بسیاری از فروشگاه‌های بزرگ دارند از Next.js استفاده می‌کنند. ترکیب ISR و SSR برای محصولات، تجربه کاربری عالی و سئوی قوی فراهم می‌کند. 

سوال: Next.js نسخه ۱۵ با نسخه ۱۴ چه فرقی دارد؟

نسخه ۱۵ (۲۰۲۴) بهبودهای بزرگی داشته است: پشتیبانی کامل از React 19، بهبود عملکرد Turbopack (تا ۵ برابر سریع‌تر)، API جدید برای caching، و ابزارهای بهینه‌سازی خودکار دارد. مثال‌های این مقاله با نسخه ۱۵+ کار می‌کند. برای جزئیات بیشتر به مستندات رسمی مراجعه کنید.

سوال: آیا می‌توانم Next.js را با PHP یا Python استفاده کنم؟

Next.js فقط با Node.js در سمت سرور کار می‌کند. اما می‌توانید API خود را با PHP/Python بنویسید و Next.js از آن داده بگیرد. فقط سرور اصلی باید حتما Node.js باشد.


منابع: وب‌سایت‌های pagepro و tailwindcss و dev.to و nextjs و youtube

نویسنده شوید
دیدگاه‌های شما (4 دیدگاه)

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.

فرزاد
24 خرداد 1403
سلام و درود با سپاس از توضیحات جامعی که دادید. برای شروع next.js بسیار مناسب بود.

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.

سینا
28 فروردین 1403
ممنون. من این مقاله رو دانشگاه ارائه دادم و مقاله مورد تشویق قرار گرفت و منو با نمره خوبی پاس خواهد کرد. :)

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.

سهیل
04 بهمن 1401
با عرض سلام، بسیار توضیح قابل درک و مفیدی بود، درود بر شما

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.

محسن
23 شهریور 1400
خیلی کامل و خوب بود

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.

روکسو
20 دی 1400
ممنون از همراهی شما

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.