دوره های پرنیان

آموزش فریم ورک NEXT درREACT

آموزش فریم ورک NEXT درREACT

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

Next.js یک فریم‌ورک React است که برای ایجاد وب‌سایت‌ها و برنامه‌های وب سریع و مقیاس‌پذیر طراحی شده است. این یک چارچوب کامل است که شامل همه چیزهایی است که برای توسعه وب‌سایت‌ها و برنامه‌های وب با React نیاز دارید.

برای آشنایی با این مطلب تا انتهای مقاله آموزش فریم ورک NEXT در REACT با ما همراه باشید.

چارچوب React برای وب

اگر کسی از شما پرسید که نکست جی اس چیست؟ در پاسخ به او بگویید تمام ابزار ها و راه هایی که وبسایت شما را سریعتر میکند. بله ، همانطور که خواندید، خود ری اکت که یک فریم ورک در جاوا اسکریپت میباشد، دارای یک فریم ورک قوی و کامل به نام نکست جی اس است که میتواند هر دو سمت فرانت اند و بک اند را کاور کند!

این فریم ورک ، ری اکت را توسعه میدهد و قابلیت های بیشتری در اختیار شما میگذارد. بطور مثال سرعت و عملکرد سایت شما را بطور زیادی افزایش میدهد و از ویژگی های اصلی آن به حساب می آید.

پلتفرم vercel از بنیانگذاران Next.js است که آن را به چارچوبی تبدیل می کند که می توانید به راحتی آن را گسترش دهید.

اما دقیقاً منظور ما از این حرف ها چیست؟ بیایید کمی وقت بگذاریم و توضیح دهیم که React و Next.js چه هستند و چگونه می توانند کمک کنند.

کمی در رابطه با NEXT.JS عمیق شویم:

هنگام ساخت برنامه های مدرن باید چند نکته را در نظر بگیرید. مانند:

  • رابط کاربری – نحوه تعامل کاربران با برنامه شما – User Interface
  • مسیریابی – چگونه کاربران بین بخش های مختلف برنامه شما حرکت می کنند – Routing 
  • واکشی داده – محل زندگی داده های شما و نحوه دریافت آن – Data Fetching
  • رندر – چه زمانی و در کجا محتوای ایستا یا پویا را ارائه می کنید – Rendering 
  • یکپارچه‌سازی – از چه سرویس‌های شخص ثالثی استفاده می‌کنید (CMS، احراز هویت، و..) – Integrations 
  • زیرساخت – جایی که کد برنامه خود را مستقر، ذخیره و اجرا می کنید – Infrastructure 
  • عملکرد – چگونه برنامه خود را برای کاربران نهایی بهینه کنید – Performance 
  • مقیاس پذیری – چگونه برنامه شما با رشد تیم، داده ها و ترافیک شما سازگار می شود – Scalability 
  • تجربه توسعه دهنده – تجربه تیم شما در ساخت و نگهداری برنامه شما – Developer Experience

  • رندر سمت سرور (SSR): Next.js به شما امکان می دهد صفحات را در سمت سرور رندر کنید، که منجر به بهبود عملکرد SEO (بهینه سازی موتور جستجو) و تجربه کاربری اولیه (initial user experience) می شود.
  • تولید سایت استاتیک (SSG): Next.js همچنین به شما امکان می دهد صفحات وب استاتیک از محتوای پویا ایجاد کنید، که برای وب سایت هایی با محتوای نسبتاً ثابت ایده آل است.
  • ** مسیریابی:** Next.js یک سیستم مسیریابی داخلی را برای مدیریت URL ها و نمایش صفحات مرتبط ارائه می دهد.
  • بستن کد خودکار (code-splitting): Next.js به طور خودکار کد برنامه شما را به قسمت های کوچکتر تقسیم می کند، که زمان بارگذاری صفحه را بهبود می بخشد.
  • بهینه سازی تصویر: Next.js به طور خودکار تصاویر را برای اندازه صفحه و دستگاه کاربر بهینه می کند.
  • API Routes: Next.js به شما امکان می دهد API routes ایجاد کنید که به عنوان نقاط انتهایی برای درخواست های back-end عمل می کنند.

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

  • بهبود عملکرد: Next.js می تواند به بهبود عملکرد وب سایت های شما از طریق ویژگی هایی مانند رندر سمت سرور و تولید سایت استاتیک کمک کند.
  • بهبود سئو (SEO): Next.js با رندر سمت سرور، به خزنده های موتورهای جستجو امکان می دهد محتوای کامل صفحات شما را ببینند که می تواند به رتبه بندی بهتر در نتایج جستجو کمک کند.
  • تجربه توسعه دهنده بهتر: Next.js با ارائه ویژگی های اضافی و ساده سازی کارهای تکراری، تجربه توسعه دهنده را بهبود می بخشد.
  • مناسب برای انواع برنامه های کاربردی: Next.js برای طیف وسیعی از برنامه های کاربردی وب، از وب سایت های ساده گرفته تا برنامه های تک صفحه ای (SPA) پیچیده، مناسب است.

برای هر قسمت از برنامه خود، باید تصمیم بگیرید که آیا خودتان راه حلی ایجاد می کنید یا از ابزارهای دیگری مانند فریم ورک ها و چارچوب ها استفاده می کنید.

آموزش کتابخانه NEXT در REACT

اما نکست جی اس…

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

آموزش کتابخانه NEXT در REACT

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

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

ویژگی های مهم NEXT

۱. Server-side Rendering (صفحه سازی در سمت سرور)

SSR (Render-on-the-Server) از SSR استفاده می کند تا صفحات وب را در سمت سرور رندر کند. این باعث می شود که صفحات وب سریعتر بارگذاری شوند و در موتورهای جستجو بهتر رتبه بندی شوند.

Server-side Rendering به معنی رندر کردن صفحات (ساخت و نمایش آن ها) در سمت server است. اگر با react کار کرده باشید می دانید که ما در react داده ها را از سرور گرفته و در سمت client (مرورگر کاربر) از آن داده ها برای ساخت و نمایش صفحه استفاده می کنیم.
در این حالت صفحه را در سمت کلاینت ساخته و نمایش داده ایم اما server-side rendering مانند زمانی است که از زبان بک اند برای تولید صفحات HTML استفاده می کنید. یعنی صفحات شما در سمت سرور ساخته شده و سپس به صورت آماده به سمت کاربر ارسال می شوند.

بنابراین کاربر نیازی به انجام پردازش ندارد. به این ساختار به اختصار SSR میگویند.

به همین خاطر سایت های CSR که در سمت کلاینت رندر میشوند میتوانند سرعت کمتری نسبت به سایت های SSR داشته باشند(به دلیل اینکه در مرورگر کاربر تازه سایت ساخته میشود) و همچنین در سئو مشکلات جدی خواهند داشت، زیرا متن ها و کد های سایت از قبل ساخته نشده و موتور های جستجو به آنها دسترسی ندارند!

نکته : یکی از سوالاتی که معمولا زیاد هم در سوالات استخدامی ری اکت پرسیده میشود این است که از نکست برای سئو استفاده میشود؟ باید پاسخ دهید که یکی از موارد آن، سئو است و کسی که فقط قصد سئو دارد ، ده ها راه حل دیگر برای این قضیه موجود است و نباید به سراغ نکست بیاید!

پیشنهاد میکنیم لیست سوالات استخدامی REACT را مشاهده فرمایید.

پیشنهاد سرآشپز سایت 😂

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

ویژگی دوم و بسیار محبوب فریم ورک نکست ، ناوبری فایل محور یا File-based Routing است. در فریم ورک react به صورت پیش فرض هیچ router ای وجود ندارد که مسیر حرکت کاربر و تغییر URL مرورگر را تحت نظر بگیرد.

بجای آن از پکیج هایی مانند react-router استفاده می کنیم. کار چنین پکیج هایی این است که با تغییر URL در مرورگر کاربر، جلوی رفتار پیش فرض مرورگر (ارسال درخواست HTTP) گرفته شود و سپس نمایش محتوای متفاوت در همان صفحه است.

بنابراین به نوعی کاربر را گول می زنیم تا تصور کند برنامه ما صفحات مختلفی را دارد. در ضمن در کدزنی هم سختی ها و مشکلاتی دارد!

برای حل این مشکلات Next.js این مسئله را با معرفی سیستم ناوبری یا routing خاص خودش حل می کند!  در واقع در پروژه های Next.js یک پوشه به نام pages را داریم که عینا باید با همین نام باشد.

حالا درون این پوشه، پوشه ها و فایل های دیگری را خواهید داشت و ساختار این پوشه ها و فایل ها دقیقا سیستم routing وب سایت شما خواهد بود!

چنین سیستمی برای ساخت مسیر دهی چندین مزیت مهم دارد:

  • اولا برای تولید route ها هیچ نیازی به نوشتن کد نداریم بلکه Next.js خودش این کار را برایمان انجام می دهد
  • دوما به دلیل نوشتن کد کمتر، خوانایی کدهایمان بالا رفته و از شلوغ شدن پروژه جلوگیری می کنیم
  • سوما درک سیستم routing در این حالت بسیار ساده تر است چرا که با نگاه انداختن به پوشه pages به راحتی می توانیم مسیر های سایتمان را مشاهده کنیم

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

کوتاه بگوییم این که که قرار نیست نکست بصورت خودکار کدهای سمت بک اند شما را نوشته و آن را مدیریت کند ، بلکه قرار است سیستم API نویسی شما و همچنین اتصال کد های سمت فرانت و بک را تسهیل کرده و آن را برای برنامه نویس آسانتر کند.

ما می توانیم بدون Next.js یک پروژه react داشته باشیم و API را جداگانه بنویسیم. در هر دو حالت نیز باید API را خودمان بنویسیم! اما در پروژه های Next.js علاوه بر مزیت های قبلی این مزیت را نیز داریم که کد سمت سرور (مثلا Node.js) و کد سمت کلاینت‌ (React) در یک پروژه و یکجا قرار دارند بنابراین مدیریت آن بسیار ساده تر خواهد بود.

نکته : شاید از معدود معایب نکست جی اس این باشد که ایشان زبان سمت بک اند خود را نود جی اس انتخاب کرده است و تغییر آن به زبان دیگر مانند ASP , py و… امکان پذیر نیست!

4. از Static Site Generation (SSG) استفاده می کند تا صفحات وب را به صورت استاتیک تولید کند. این باعث می شود که صفحات وب سریعتر بارگذاری شوند و در صورت قطعی سرور نیز در دسترس باشند.

علاوه بر این ویژگی ها، Next.js همچنین از ویژگی های دیگری مانند:

  • SEO: Next.js بهینه شده است تا صفحات وب شما در موتورهای جستجو بهتر رتبه بندی شوند.
  • Performance: Next.js برای عملکرد بهینه شده است.
  • Scalability: Next.js برای مقیاس پذیری طراحی شده است.

Next.js یک انتخاب عالی برای توسعه وب‌سایت‌ها و برنامه‌های وب است که سریع، مقیاس‌پذیر و SEO-friendly هستند.

مقدمه بس است! بزن بریم تا شروع به کار کنیم:

آموزش نصب NEXT.JS

فکر میکنم نیازی نیست که به شما بگوییم آخرین ورژن نود را بروی سیستم خود نصب داشته باشید 😊

توصیه می کنیم با استفاده از create-next-app یک برنامه Next.js جدید ایجاد کنید، که همه چیز را به طور خودکار برای شما تنظیم می کند. برای ایجاد یک پروژه، اجرا کنید:(حتما ف*ل*ت*ر*ش*ک*ن را روشن بفرمایید😢)

npx create-next-app@latest

هنگام نصب، اعلان های زیر را مشاهده خواهید کرد:

آموزش نصب NEXT.JS

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

آموزش نصب NEXT.JS

حال میتوانید کامند npm run dev را زده و در پورت 3000 دمو پروژه خود را ببینید.

پیشنهاد میکنیم سری هم به صفحه آموزش نصب ری اکت با VIT بیندازید!

پیشنهاد ویژه سرآشپز سایت 😊

بعد از نصب، پوشه ها را باز کنید و نگاهی به آن ها بیندازید. فعلا فقط سرو کار ما با پوشه SRC میباشد و در وهله بعدی پوشه .next

چون در هنگام نصب، گزینه tailwind را زدیم، همانطور که در آدرس src/app/page.js مشاهده میکنید، پروژه ما با تیلویند سازگار است و تقریبا نیاز به تنظیمات و نصب دیگری ندارید!

ساختار پوشه بندی NEXT

اولین پوشه که مورد بررسی قرار میدهیم public است که هم اکنون فقط چند فایل نظیر next.svg و vercel.svg را در دل خود دارد. این پوشه برای محتویات استاتیک ما میباشد و هر فایلی در پوشه public قرار گیرد، در مرورگر نمایش داده خواهد شد.

(از نسخه های قبل از 13 نکست) یکی از مهمترین پوشه های نکست ، pages میباشد که شامل سیستم روتینگ درونی نکست هست و بسیار محبوب! در ورژن های قدیمی نکست پوشه pages در همان نزدیکی و روش به شکل زیر…

چرا که در این پوشه شما هر فایل و کامپوننتی ایجاد کنید بعنوان یکی از صفحات سایت شما به حساب خواهد آمد.

امتحان کنید و فایل زیر را بسازید:

const teacher = () => { return ( <div> <h1>parsa ghorbanian is best teacher :</h1> </div> ); }; export default Teacher;

حال طبیعتا باید به مسیر http://localhost:3000/Teacher رفته و صفحه خود را ببینید.

اما در آخرین ورژن های نکست و در حال تایپ این مقاله، پوشه pages در src وجود ندارد. پس قدم های زیر را دنبال کنید:

Creating Routes یا ساختن مسیر

هر پوشه نشان دهنده یک بخش مسیر است که به یک بخش URL نگاشت می شود. برای ایجاد یک مسیر تودرتو، می توانید پوشه ها را در داخل یکدیگر قرار دهید.

Creating Routes یا ساختن مسیر

پسوندهای فایل .js، jsx. یا tsx. را می توان برای صفحات استفاده کرد. در پوشه app یک دایرکتوری به نام dashboard ساخته و در آن یک فایل به نام page.js ایجاد کرده و کد زیر را در آن بنویسید:

export default function Page() { return <h1>Hello NextJs, i am Parsa ghorbanian!</h1>; }

حال اگر آدرس http://localhost:3000/dashboard را بزنید صفحه جدید خود را مشاهده خواهید کرد. نکست روی کلمه page حساس است و مانند کلمه index در لینوکس و یا default در ویندوز، آن را بعنوان صفحه پیشفرض انتخاب میکند. پس یک راه حل زود بازده این است که برای هر صفحه خود یک دایرکتوری ایجاد کرده و در آن با ساخت صفحه page محتویات را درج نماییم.

فایل layout.js در نکست چیست؟

اما معمولا یک فایل layout.jsx هم داریم که محتویات داخل آن میتواند در همه صفحات تکرار شود. این فایل عموما برای چند منظور استفاده میشود:

ارسال دیتا های هر صفحه مانند تگ title, description و …

ساخت قسمت های ثابت هر صفحه مانند header, footer, sidebar و…

نکته بسیار مهم اینجاست که بدانید در فایل alyout باید هرجایی که میخواهید محتوایات سایت شما قرار گیرد، همانجا از پراپ children استفاده کنید.

در نظر داشته باشید هر فایل میتواند layout اختصاصی خودش را داشته باشد. metaData های هر صفحه جدید و جایگزین قبلی های میشود، اما اگر هدر و فوتر را تغییر دهید، آن هدر و فوتری که از layout اصلی آمده است در جای خود میماند و تغییرات شما از layout دومی هم به آن اضافه میشود.

مثال زیر را در نظر گرفته که هم فایل page را دارید و هم فایل layout را:

http://localhost:3000///// page صفحه اصلی//// import Image from 'next/image' export default function Home() { return ( <main> <p> Get started by &nbsp; <code className="font-mono font-bold">parnian school</code> </p> </main> ) } layout صفحه اصلی//// import './globals.css' export const metadata = { title: 'Create Next App', description: 'Generated by create next app', } export default function DashboardLayout({ children, // will be a page or nested layout }) { return ( <section> {/* Include shared UI here e.g. a header or sidebar */} <nav> <ul> <li>menu</li> <li>menu</li> </ul> </nav> {children} <footer> <p>lorem ipsum...</p> </footer> </section> ) }

و فرض کنید صفحه ای ساختیم با آدرس http://localhost:3000/parsa با محتویات:

محتویات صفحه page//// export default function Page() { return <h1>Hello NextJs, i am Parsa ghorbanian!</h1>; } محتویات صفحه layout//// export const metadata = { title: 'parsa page', description: 'test' } export default function DashboardLayout({ children, // will be a page or nested layout }) { return ( <section> {children} </section> ) }

فایل Templates در نکست چیست؟

در Next.js ، فایل Templates به عنوان یک راه برای سازماندهی و مدیریت کدهای HTML در پروژه شما استفاده می شود. فایل های Template می توانند برای ایجاد صفحات جدید، یا برای تغییر ظاهر و عملکرد صفحات موجود استفاده شوند.

فرض کنید شما یک پروژه Next.js دارید که دارای دو صفحه اصلی و صفحه تماس است. در نسخه های قبلی Next.js، شما باید تمام کد HTML برای هر صفحه را در یک فایل واحد قرار می دادید. این می تواند منجر به کدهای طولانی و پیچیده شود.

با استفاده از فایل های Template، می توانید کد HTML برای هر صفحه را در یک فایل جداگانه قرار دهید. این باعث می شود کد شما سازمان یافته تر و نگهداری آن آسان تر شود.

در اینجا یک نمونه از نحوه استفاده از فایل های Template برای ایجاد یک صفحه جدید آورده شده است:

محتویات page.js///////// import React from "react"; const About = () => { return ( <main></main> ); }; export default About; محتویات template.js///// import React from "react"; const AboutTemplate = ({title, content}) => { return ( <div> <h1>{title}</h1> <p>{content}</p> </div> ); }; AboutTemplate.defaultProps = { title: "پارسا قربانیان", content: "بهترین استاد جهان :)", }; export default AboutTemplate;

در این مثال، ما از فایل Template برای سازماندهی کد HTML برای صفحه about استفاده کردیم. این باعث می شود کد ما سازمان یافته تر و نگهداری آن آسان تر شود.

در نظر داشته باشید خروجی به صورت زیر میباشد:

<Layout> {/* Note that the template is given a unique key. */} <Template key={routeParam}>{children}</Template> </Layout>

آدرس دهی داینامیک در نکست جی اس

در Next.js، می‌توانید از آدرس‌های داینامیک برای ایجاد صفحاتی استفاده کنید که با محتوای متغیر سازگار هستند. این کار با استفاده از سینتکس [slug] در مسیر صفحه امکان‌پذیر است. به ساده ترین شکل ممکن توضیح میدهم. با دقت بخوانید:

برای اینکار ابتدا یک فایل با آدرس زیر بسازید:

app/blog/[slug]/page.js

سپس داخل page.js محتویات زیر را بریزید:

export default function Page({ params }) { return <div>My Post: {params.slug}</div> }

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

app/blog/[slug]/page.js/blog/a{ slug: 'a' }

یا زیر:

app/blog/[slug]/page.js/blog/parsa{ slug: 'parsa' }

هر چه جای slug بنویسیم، در بالای url صفحه قرار میگیرد.

اما مهم ترین قسمت در آدرس دهی داینامیک:

ساختن داینامیک صفحات در dynamic Routing نکست

در نظر داشته باشید، در قسمت میخواهیم به شما یاد بدهیم که چگونه به تعداد api خود، لینک در منو درست کرده و وقتی روی هر کدام از آن لینک ها کلیک شد، بصورت اتومات صفحه ای برای آن ساخته شده و محتویات همان آی دی یا slug در آن صفحه قرار گیرد.

برای این منظور ابتدا ساختار پوشه ای زیر را بسازید:

ساختن داینامیک صفحات در dynamic Routing نکست

یعنی در app ، یک پوشه blog بسازید با page.jsx خودش و داخل آن یه پوشه [slug] با page.jsx خودش.

ابتدا در page.jsx که برای پوشه blog هست کد زیر را وارد کنید:

import Link from "next/link" async function getData() { const res = await fetch('https://jsonplaceholder.typicode.com/posts/') if (!res.ok) { throw new Error('Failed to fetch data') } return res.json() } export default async function Page({ params, searchParams }) { const data = await getData() return ( <nav> <h1>main menu</h1> <ul> {data.map((val) => { console.log(val.id); let x = "blog/"+val.id return( <li><Link href={x} as={x}>{val.title}</Link></li> ) })} </ul> </nav> ) }

همانطور که در کد بالا میبینید، یک fetch به api مورد نظر زده شده و به تعداد فایل های موجود در آن، منو همراه لینک ساخته شده است(لازم به ذکر است در نکست از کامپوننت Link به جای a استفاده میکنیم که کمی پایین تر توضیح داده شده)

حال روی هر لینک که کلیک شود رشته “blog/”+val.id که حکم همان slug را دارد قرار دادیم.

حال کد زیر را در page.jsx پوشه slug بنویسید:

async function getData(x) { const res = await fetch('https://jsonplaceholder.typicode.com/posts/'+x) if (!res.ok) { throw new Error('Failed to fetch data') } return res.json() } export default async function Page({ params, searchParams }) { const data = await getData(params.slug) console.log(data); return ( <main> <h2>hello , wlc to page: {params.slug} !</h2> <h3>{data.title}</h3> <h4>{data.body}</h4> </main> ) }

همانطور که در کد بالا میبینید، href که در صفحه قبلی ارسال کردیم را در این صفحه با params.slug میگیریم و مجدد fetch میزنیم و همان مقدار آی دی مورد نظر خود را استخراج کرده و در صفحه چاپ میکنیم.

لینک دهی بین صفحات در نکست

<Link> یک کامپوننت React است که عنصر <a> HTML را برای ارائه پیش واکشی و ناوبری سمت client بین مسیرها گسترش می دهد. این راه اصلی برای پیمایش بین مسیرها در Next.js است. طبق کد زیر:

تا به اینجای کار ما دو فایل dashboard و parsa ساختیم و درون هر کدام یک فایل page.js و میخواهیم بین هر کدام لینک برقرار کنیم:

Creating Routes یا ساختن مسیر

dashboard/page.js

import Link from `next/link`; export default function Main() { return ( <> <h1>dashboard is here!</h1> <Link href="/parsa">parsa</Link>; </> ); }

parsa/page.js

import Link from `next/link`; export default function Main() { return ( <> <h1>parsa ghorbanian</h1> <Link href="/dashboard">Dashboard</Link>; </> ); }

همانطور که میبینید بین صفحات لینک برقرار شد!

اگر هم به دنبال لینک دهی داینامیک هستید میتواند از کد زیر کمک بگیرید:

import Link from `next/link`; export default function PostList({ posts }) { return ( <ul> {posts.map((post) => ( <li key={post.id}> <Link href={`/blog/${post.slug}`}>{post.title}</Link> </li> ))} </ul> ); }

usePathname در نکست به چه معناست؟

کاربرد بسیار ساده ای دارد. به این معنا که معمولا در className و داخل دستور شرطی نوشته میشود. اگر pathname با href مطابقت داشته باشد، کلاس مورد نظر به المان داده میشود و در غیر این صورت خیر. کد زیر را با دقت ببینید:

'use client' import { usePathname } from 'next/navigation' import Link from 'next/link' export default function Links() { const pathname = usePathname() return ( <nav> <ul> <li> <Link className={`link ${pathname === '/sw' ? 'active' : ''}`} href="/"> Home </Link> </li> <li> <Link className={`link ${pathname === '/about' ? 'active' : ''}`} href="/about" > About </Link> </li> </ul> </nav> ) }

در مثال فوق، لینک اول به دلیل عدم تطابق href و pathName کلاس اکتیو داده نشده و در لینک دوم به دلیل تطابق، داده شده است.

هوک userRouter در نکست به چه معناست؟

هوک userRouter به شما اجازه می دهد تا مسیرهای درون کامپوننت های کلاینت را به صورت برنامه نویسی تغییر دهید. برای استفاده از useRouter، آن را از next/navigation وارد کنید و هوک داخل کامپوننت کلاینت خود را فراخوانی کنید:

'use client' import { useRouter } from 'next/navigation' export default function Page() { const router = useRouter(); return ( <button type="button" onClick={() => router.push('./dashboard')}> Dashboard </button> ) }

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

<Link href="/dashboard#settings">Settings</Link> // Output <a href="/dashboard#settings">Settings</a>

سایر ویژگی های لینک را اینجا بخوانید.

Styling در نکست

  • CSS گلوبال : استفاده ساده و آشنا برای کسانی که با CSS خارجی کار می کنند، اما می تواند منجر به مشکل در مدیریت بسته های بزرگتر CSS و مدیریت سبک ها با رشد برنامه شود.
  • ماژول‌های CSS : برای جلوگیری از تداخل نام‌گذاری و بهبود قابلیت نگهداری، کلاس‌های CSS با محدوده محلی ایجاد کنید.
  • Tailwind CSS : یک فریم ورک CSS اولین ابزار است که امکان طراحی های سفارشی سریع را با ترکیب کلاس های ابزار فراهم می کند. (در هنگام نصب، گزینه yes install tailwind را زده تا اتومات نصب و فعال شود)
  • Sass : یک پیش پردازنده محبوب CSS که CSS را با ویژگی هایی مانند متغیرها، قوانین تودرتو و میکسین گسترش می دهد.
  • CSS-in-JS: CSS را مستقیماً در مؤلفه‌های جاوا اسکریپت خود جاسازی کنید و یک ظاهر طراحی پویا و محدوده را فعال کنید.

ماژول‌های CSS :

پوشه بعدی styles میباشد که در آپدیت های جدید داخل پوشه SRC قرار دارد. نکست برای استایل ها ساختار جالبی دارد. فایل globals.css شامل استایل های سراسری برنامه است و طبیعتا روی تمام صفحات پیاده سازی خواهد شد. اما میتوان استایل را برای یک ماژول یا کامپوننت خاص هم نوشت!

به این منظور فایل کافیست از ساختار زیر برای نامگذاری فایل استفاده نمایید و نام کامپوننت react خودتان را بنویسید:

moduleName.module.css
sample:
Header.module.css

شبیه کد زیر :

import styles from ‘../styles/Header.module.css’
export default function Header() {

در این صفحات فقط اجازه درج استایل هایی را دارید که سراسری نیستند و در انتهای نامشان module.css دارند.

نصب sass در نکست

Next.js با استفاده از هر دو پسوند .scss و .sass از Sass پشتیبانی داخلی دارد. می‌توانید از Sass در سطح مؤلفه از طریق ماژول‌های CSS و پسوند .module.scssor .module.sass استفاده کنید.

برای نصب sass در نکست کامند زیر را بزنید:

npm install –save-dev sass

اگر می خواهید کامپایلر Sass را پیکربندی کنید، از sassOptions در next.config.js استفاده کنید.

const path = require(`path`); module.exports = { sassOptions: { includePaths: [path.join(__dirname, `styles`)], }, };

فایل بسازید در app/variables.module.scss

$primary-color: #64ff00; :export { primaryColor: $primary-color; }

و استفاده کنید در app/page.js

import variables from `./variables.module.scss`; export default function Page() { return <h1 style={{ color: variables.primaryColor }}>Hello, Next.js!</h1>; }

نصب tailwind در نکست

فکر کنم برای کسی که اینجای مقاله هست، نیاز به توضیح و تعریف از tailwin نداریم. همانطور که میدانید در هنگام نصب، سوال میشود و میتوانید تیک تیلویند را بزنید تا اتومات نصب شود. اما در اینجا نصب دستی ان را هم آموزش میدهیم.

بسته‌های Tailwind CSS را نصب کنید و دستور init را اجرا کنید تا فایل‌های tailwind.config.js و postcss.config.js تولید شود، پس کامند های زیر را به ترتیب بزنید:

npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p

کد زیر را در فایل tailwind.config.js وارد کنید: (لطفا کاری به postcss.config.js نداشته باش دوست من 🙂

/** @type {import('tailwindcss').Config} */ module.exports = { content: [ './app/**/*.{js,ts,jsx,tsx,mdx}', // Note the addition of the `app` directory. './pages/**/*.{js,ts,jsx,tsx,mdx}', './components/**/*.{js,ts,jsx,tsx,mdx}', // Or if using `src` directory: './src/**/*.{js,ts,jsx,tsx,mdx}', ], theme: { extend: {}, }, plugins: [], }

این فایل app/globals.css را بسازید و محتویات زیر را قرار دهید:

@tailwind base; @tailwind components; @tailwind utilities;

سپس این فایل app/layout.js را بسازید و در layOut اصلی global.css را وارد کنید:

import './globals.css' export const metadata = { title: 'Create Next App', description: 'Generated by create next app', } export default function RootLayout({ children }) { return ( <html lang="en"> <body data-rsssl=1>{children}<script>class RocketElementorAnimation{constructor(){this.deviceMode=document.createElement("span"),this.deviceMode.id="elementor-device-mode",this.deviceMode.setAttribute("class","elementor-screen-only"),document.body.appendChild(this.deviceMode)}_detectAnimations(){let t=getComputedStyle(this.deviceMode,":after").content.replace(/"/g,"");this.animationSettingKeys=this._listAnimationSettingsKeys(t),document.querySelectorAll(".elementor-invisible[data-settings]").forEach(t=>{const e=t.getBoundingClientRect();if(e.bottom>=0&&e.top<=window.innerHeight)try{this._animateElement(t)}catch(t){}})}_animateElement(t){const e=JSON.parse(t.dataset.settings),i=e._animation_delay||e.animation_delay||0,n=e[this.animationSettingKeys.find(t=>e[t])];if("none"===n)return void t.classList.remove("elementor-invisible");t.classList.remove(n),this.currentAnimation&&t.classList.remove(this.currentAnimation),this.currentAnimation=n;let s=setTimeout(()=>{t.classList.remove("elementor-invisible"),t.classList.add("animated",n),this._removeAnimationSettings(t,e)},i);window.addEventListener("rocket-startLoading",function(){clearTimeout(s)})}_listAnimationSettingsKeys(t="mobile"){const e=[""];switch(t){case"mobile":e.unshift("_mobile");case"tablet":e.unshift("_tablet");case"desktop":e.unshift("_desktop")}const i=[];return["animation","_animation"].forEach(t=>{e.forEach(e=>{i.push(t+e)})}),i}_removeAnimationSettings(t,e){this._listAnimationSettingsKeys().forEach(t=>delete e[t]),t.dataset.settings=JSON.stringify(e)}static run(){const t=new RocketElementorAnimation;requestAnimationFrame(t._detectAnimations.bind(t))}}document.addEventListener("DOMContentLoaded",RocketElementorAnimation.run);</script></body> </html> ) }

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

export default function Page() { return <h1 className="text-3xl font-bold underline">Hello, Next.js!</h1> }

آیا میدانید مدرسه طراحی سایت پرنیان، کلاس های فرانت اند با تضمین استخدام برگزار میکند؟

اطلاعات بیشتر، کلیک کنید

use client چیست؟

شاید یکی از مهمترین مسائل در نکست همین use client باشد. امتحان کنید و در یکی از فایل های page خود، از کد های قبلی ری اکت که بلد بودید استفاده کنید. هوک بزنید، استیت بسازید و یا پراپ ، مقادیری را جابجا کنید. خواهید دید که در اکثر موارد به ارور میخورید. اینجاست که یوز کلاینت به دادمان میرسد!

Client Components شما را قادر می سازد تا تعامل سمت کلاینت را به برنامه خود اضافه کنید. در Next.js از قبل روی سرور رندر شده و روی کلاینت هیدراته می شوند.

useClient قراردادی برای اعلام مرز بین گراف ماژول مؤلفه سرور و کلاینت است. پس اگر در کد خود ایونت هایی دارید و یا از هوک ها برای تعامل کاربر میخواهید استفاده کنید و یا… حتما اول کد خود از use client استفاده کنید. کد زیر را یکبار با یوز و بار دیگر بدون یوز اجرا کنید:

`use client` import { useState } from `react` export default function Main(){ const [temp, setTemp] = useState(`parsa`) return( <div className=`row`> <h1>{temp}</h1> <button onClick={()=>setTemp(`arsam`)}>click to change</button> </div> ) }

Data Fetching در نکست

تقریبا برنامه حرفه ای و جدید امروزی نیست که در آن از واکشی دیتا استفاده نشود. نکست راهکارهای جدید و حرفه ای برای واکشی داده ارایه کرده است. اما امروز در ساختار جدید پشتیبانی نمیشود! درورژن های گذشته از getServerSidePropsgetStaticProps getInitialProps متدها برای دیتا فچینگ استفاده میشد که هم اکنون در زمان ویرایش مقاله دیگر ساپورت نمیشود.

React و Next.js راه جدیدی را برای واکشی و مدیریت داده ها در برنامه شما معرفی کردند. سیستم جدید واکشی داده ها در دایرکتوری برنامه کار می کند و بر روی fetch() Web API ساخته شده است. fetch() یک وب API است که برای واکشی منابع راه دور استفاده می شود که یک promise را برمی گرداند.

async and await in Server Components

با React RFC پیشنهادی، می‌توانید از async استفاده کنید و منتظر واکشی داده‌ها در کامپوننت‌های سرور باشید.

به‌طور پیش‌فرض، تمام درخواست‌های fetch() به صورت خودکار ذخیره و حذف می‌شوند. به این معنی که اگر یک درخواست را دو بار انجام دهید، درخواست دوم از نتیجه درخواست اول مجددا استفاده می کند.

async function getData() { const res = await fetch('https://jsonplaceholder.typicode.com/todos/') if (!res.ok) { throw new Error('Failed to fetch data') } return res.json() } export default async function Page() { const data = await getData() return ( <ul> {data && data.map((val, i) => { return ( <li>{val.title}</li> ) })} </ul> ) }

Revalidating Data در نکست چیست؟

برای اعتبارسنجی مجدد داده های کش شده در یک بازه زمانی معین، می توانید از گزینه next.revalidate در fetch() برای تنظیم طول عمر کش یک منبع (در ثانیه) استفاده کنید.

اعتبار سنجی مجدد فرآیند پاکسازی حافظه پنهان داده و واکشی مجدد آخرین داده ها است. این زمانی مفید است که داده های شما تغییر می کند و می خواهید مطمئن شوید که آخرین اطلاعات را نشان می دهید.

fetch(‘https://…’, { next: { revalidate: 10 } });

یا برای کنترل کش از کد زیر:

fetch(‘https://…’, { cache: ‘no-store’ });

export default async function Page() { // revalidate this data every 10 seconds at most const res = await fetch(`https://jsonplaceholder.typicode.com/todos/1`, { next: { revalidate: 10 } }); const data = await res.json(); console.log(`data:`+data); }

Optimization در نکست

مجموعه عملیات ها و ویژگی هایی که باعث میشود برنامه ما بصورت کلی عملکرد بهتری داشته باشد و در ضمن برای مبحث core web vitals هم جزو عوامل موثر بحساب میآید.

Image Optimization

برای این کار کافیست از کامپوننت Image استفاده کنید. کد بسیار سادست. ابتدا خود کامپوننت image را فراخوانی کرده و سپس آدرس تصویر مورد نظر را درون آن قرار دهید:

import Image from `next/image`; import profilePic from `./me.png`; export default function Page() { return ( <> <Image src={profilePic} alt=`Picture of the author` // width={500} automatically provided // height={500} automatically provided // blurDataURL=`data:..." automatically provided // placeholder="blur" // Optional blur-up while loading /> <Image src=`https://s3.amazonaws.com/my-bucket/profile.png` alt="Picture of the author" width={500} height={500} /> </> ); }

آدرس تصویر هم میتواند داخلی و داینامیک و خارجی و استاتیک باشد. مطابق نمونه بالا.

اما تمامی حالت های آدرس دهی تصاویر را همراه توضیحات در کد زیر مشاهده فرمایید:

import Image from 'next/image'; import Pic from './img/r.jpg'; export default function Page() { return ( <> {/* در این مدل مستقیما فایل را در پوشه پابلیک آپلود کرده و بدون نیاز به ایمپورت کردن، آدرس دهی میکنیم. */} <Image src='vercel.svg' alt="Picture of the author" width={500} height={500} /> {/* در این مدل، در پوشه اپ، یک پوشه تصاویر ساخته، عکس را در آن ریخته و بعد از ایمپورت، قرار میدهیم. */} <Image src={Pic} alt="Picture of the author" width={500} height={500} /> {/* این مدل بی نیاز از همه مدل های بالا و ادرس دهی خارجی فقط باید در nextConfig فراخوانی شود. */} <Image src='https://trainingsitedesign.ir/wp-content/uploads/2023/04/5578123-ai-1.png' alt="Picture of the author" width={500} height={500} /> <Image src='https://www.thelist.com/img/gallery/leonardo-dicaprio-was-named-after-another-famous-leo/intro-1646484008.jpg' alt="Picture of the authorsrdgf" width={500} height={500} /> </> ); }

و این هم کد nextConfig برای آدرس دهی خارجی:

/** @type {import('next').NextConfig} */ const nextConfig = { images:{ domains: ['trainingsitedesign.ir','www.thelist.com'], } }; export default nextConfig;

Font Optimization

next/font به طور خودکار فونت های شما (از جمله فونت های سفارشی) را بهینه می کند و درخواست های شبکه خارجی را برای حفظ حریم خصوصی و عملکرد بهتر حذف می کند.

بطور مثال برای استفاده از فونت های گوگل کد زیر را ببینید:

import { Inter } from `next/font/google`; // If loading a variable font, you don`t need to specify the font weight const inter = Inter({ subsets: [`latin`], display: `swap`, }); export default function RootLayout({ children }) { return ( <html lang=`en` className={inter.className}> <body data-rsssl=1>{children}</body> </html> ); }

یا کد زیر:

import { Roboto } from `next/font/google`; const roboto = Roboto({ weight: `400`, subsets: [`latin`], display: `swap`, }); export default function RootLayout({ children }) { return ( <html lang=`en` className={roboto.className}> <body data-rsssl=1>{children}</body> </html> ); }

اما برای استفاده از فونت های local در app/layout.js باید آدرس فایل فونت را فراخوانی کنید:

import localFont from `next/font/local`; // Font files can be colocated inside of `app` const myFont = localFont({ src: `./my-font.woff2`, display: `swap`, }); export default function RootLayout({ children }) { return ( <html lang=`en` className={myFont.className}> <body data-rsssl=1>{children}</body> </html> ); }

Script Optimization

برای بارگیری یک اسکریپت شخص ثالث برای چندین مسیر، next/script را وارد کنید و اسکریپت را مستقیماً در layout خود قرار دهید:

import Script from `next/script`; export default function DashboardLayout({ children }) { return ( <> <section>{children}</section> <Script src=`https://example.com/script.js` /> </> ); }

سایر ویژگی های script را اینجا بخوانید.

Metadata

Next.js دارای یک API فراداده است که می تواند برای تعریف متاهای برنامه شما (به عنوان مثال متا و تگ های پیوند در عنصر سر HTML شما) برای بهبود سئو و قابلیت اشتراک گذاری وب استفاده شود.

برای تعریف Metadata ایستا، یک شی Metadata را از یک فایل layout.js یا static page.js اکسپورت کنید. در layout.js/page.js بنویسید:

export const metadata = { title: `parsa`, description: `parnian edu`, }; export default function Page() {}

Static Assets

Next.js می‌تواند فایل‌های استاتیک، مانند تصاویر، را در پوشه‌ای به نام public در دایرکتوری ROOT ارائه کند. فایل‌های داخل عمومی می‌توانند با کد شما با شروع از URL پایه (/) ارجاع داده شوند. به عنوان مثال، اگر me.png را در داخل public اضافه کنید، کد زیر به تصویر دسترسی پیدا می کند:

import Image from `next/image`; function Avatar() { return <Image src=`/me.png` alt=`me` width=`64` height=`64` />; } export default Avatar;

Lazy Loading

همان لود تنبل است. در Next.js با کاهش مقدار جاوا اسکریپت مورد نیاز برای ارائه یک مسیر، به بهبود عملکرد بارگیری اولیه یک برنامه کمک می کند.این به شما امکان می‌دهد بارگیری مؤلفه‌های client و فریم ورک های import شده را به تعویق بیندازید و فقط در صورت نیاز آن‌ها را در فایل client قرار دهید. برای بهره مندی از این ویژگی از next/dynamic استفاده میکنیم.

در دایرکتوری‌های برنامه‌ها و صفحات به همین صورت عمل می‌کند تا امکان مهاجرت تدریجی فایل ها را فراهم کند.

مثال کد زیر را در app/page.js بنویسید:

<pre> `use client`; import { useState } from `react`; import dynamic from `next/dynamic`; // Client Components: const ComponentA = dynamic(() => import(`../components/A`)); const ComponentB = dynamic(() => import(`../components/B`)); const ComponentC = dynamic(() => import(`../components/C`), { ssr: false }); export default function ClientComponentExample() { const [showMore, setShowMore] = useState(false); return ( <div> {/* Load immediately, but in a separate client bundle */} <ComponentA /> {/* Load on demand, only when/if the condition is met */} {showMore && <ComponentB />} <button onClick={() => setShowMore(!showMore)}>Toggle</button> {/* Load only on the client side */} <ComponentC /> </div> ); } </pre>

هنگام استفاده از React.lazy() و Suspense، Client Component ها به طور پیش فرض (SSR) از قبل رندر می شوند. اگر می‌خواهید پیش‌رندر را برای یک مؤلفه مشتری غیرفعال کنید، می‌توانید از گزینه ssr که روی false تنظیم شده است استفاده کنید:

const ComponentC = dynamic(() => import(`../components/C`), { ssr: false });

یا در مثالی دیگر برای اضافی کردن یک کامپوننت لودینگ اختصاصی کد زیر را در app/page.js بزنید:

import dynamic from `next/dynamic`; const WithCustomLoading = dynamic( () => import(`../components/WithCustomLoading`), { loading: () => <p>Loading...</p>, }, ); export default function Page() { return ( <div> {/* The loading component will be rendered while <WithCustomLoading/> is loading */} <WithCustomLoading /> </div> ); }

متد ها و فانکشن های مهم در نکست

در اینجای کار قصد داریم چند نمونه از مهمترین متد ها و فانکشن های نکست را به شما آموزش دهیم.

cookies().set(name, value, options)

روشی که نام، مقدار و گزینه های کوکی را می گیرد و کوکی درخواست خروجی را تنظیم می کند.

import { cookies } from `next/headers`; async function create(data) { `use server`; cookies().set(`name`, `parsa`); // or cookies().set(`name`, `arsam`, { secure: true }); // or cookies().set({ name: `name`, value: `lee`, httpOnly: true, path: `/`, }); }

draftMode یا حالت پیش نویس

عملکرد draftMode به شما امکان می دهد حالت پیش نویس را در داخل یک مؤلفه سرور تشخیص دهید. در app/page.js بنویسید:

import { draftMode } from `next/headers`; export default function Page() { const { isEnabled } = draftMode(); return ( <main> <h1>My Blog Post</h1> <p>Draft Mode is currently {isEnabled ? `Enabled` : `Disabled`}</p> </main> ); }

fetch در نکست

می‌توانید با async ارتباط بگیرید و مستقیماً در مؤلفه‌های سرور منتظر بمانید. ساختار کلی:

fetch(`https://...`, { cache: 'force-cache' | 'no-store' });
  • کد زیر:
export default async function Page() { // This request should be cached until manually invalidated. // Similar to `getStaticProps`. // `force-cache` is the default and can be omitted. const staticData = await fetch(`https://...`, { cache: `force-cache` }); // This request should be refetched on every request. // Similar to `getServerSideProps`. const dynamicData = await fetch(`https://...`, { cache: `no-store` }); // This request should be cached with a lifetime of 10 seconds. // Similar to `getStaticProps` with the `revalidate` option. const revalidatedData = await fetch(`https://...`, { next: { revalidate: 10 }, }); return <div>...</div>; }

redirect در نکست

تابع تغییر مسیر به شما امکان می دهد کاربر را به URL دیگری هدایت کنید. اگر نیاز به تغییر مسیر به 404 دارید، می توانید از تابع notFound استفاده کنید. فراخوانی تابع redirect() یک خطای NEXT_REDIRECT ایجاد می کند و رندر قسمت مسیری را که در آن پرتاب شده است خاتمه می دهد. redirect() را می توان با URL نسبی یا مطلق فراخوانی کرد.

import { redirect } from next/navigation; async function fetchTeam(id) { const res = await fetch(https://...); if (!res.ok) return return res.json(); } export default async function Profile({ params }) { const team = await fetchTeam(params.id); if (!team) redirect(login) } }

next/head در نکست

بسیار شبیه به next/link، next/head یک مؤلفه ارائه شده توسط Next.js است که به شما امکان می دهد به راحتی متا تگ ها و سایر عناصر head را به صفحات خود اضافه کنید.

import Head from 'next/head' export default function Home() { return ( <div> <Head> <title>My Homepage</title> <meta name="description" content="Welcome to my homepage!" /> </Head> <p>Welcome to my homepage!</p> </div> ) }

Static Exports در نکست

بعضی وقتها نیاز دارید یک سری اطلاعات را در یک فایل جداگانه نگهداری کرده و در زمان مورد نیاز با فراخوانی آن فایل، از آنها استفاده کنید. شبیه یک فایل config که با دسترسی گرفتن به آن، اطلاعات داخل آن را فراخوانی کرده و از آن استفاده کنید.

در مثال زیر میخواهیم اطلاعات api خود را از فایل دیگری فراخوانی کنیم. خوب ابتدا یک فایل next.config.js ساخته و اطلاعات خود را در آن میریزیم:

const nextConfig = { data : { token : '653d26dbf52310ee6a99ee3e', endPoint : 'users' } } module.exports = nextConfig

و سپس با فراخوانی آن در فایل page.jsx از آنها استفاده میکنیم:

'use client' import { useState } from "react"; import nextConfig from './next.config' import { useEffect } from "react"; export default function MyFetch(){ const [data , setData] = useState([]) useEffect(()=>{ async function para (){ const x = await fetch(`https://${nextConfig.data.token}.mockapi.io/api/divar/${nextConfig.data.endPoint}`) const y = x.json() setData(y) } para() }, []) return( <> <h1>myFetch.jsx page</h1> <ul> {data.map((val)=>{ return <li key={val.id}>{val.fullName}</li> })} </ul> </> ) }

Deploying در نکست

در انتهای مقاله در نظر داریم شیوه خروجی گرفتن از یک اپلیکیشن نکست را مورد بررسی قرار دهیم.

next build یک نسخه بهینه از برنامه شما تولید می کند. این خروجی استاندارد شامل:

  • فایل های HTML برای صفحاتی که از getStaticProps یا Automatic Static Optimization استفاده می کنند
  • فایل‌های CSS برای سبک‌های سراسری یا برای سبک‌های دارای دامنه جداگانه
  • جاوا اسکریپت برای پیش رندر کردن محتوای پویا از سرور Next.js
  • جاوا اسکریپت برای تعامل در سمت مشتری از طریق React

برای تست گرفتن از پروژه خود میتوانید از سرویس هایی نظیر vercel که سایت نکست تاکید زیادی بروی آن دارد استفاده کنید. اما تمرکز ما بروی هاست شخصی (سرور نود جی اس) میباشد.

Next.js را می توان در هر ارائه دهنده میزبانی که از Node.js پشتیبانی می کند مستقر کرد.

ابتدا مطمئن شوید که package.json شما دارای اسکریپت های “build” و “start” است:

{ `scripts`: { `dev`: `next dev`, `build`: `next build`, `start`: `next start` } }

سپس، npm run build را اجرا کنید تا اپلیکیشن شما ساخته شود. در نهایت npm run start را اجرا کنید تا سرور Node.js راه اندازی شود. این سرور از تمامی ویژگی های Next.js پشتیبانی می کند.

در نظر داشته باشید این پایان راه نیست و فقط یه مقدمه بود به زبان ساده برای درک کلیت و مفهوم فریمن ورک نکست زیبا ♥ حتما وارد داکیومنت اصلی سایت شده و تمرین های و مثال های بیشتری را انجام دهید و سوالات خود را در قسمت نظرات بیان بفرمایید.

امیدواریم از این مقاله نهایت استفاده را برده باشید و آن را با دوستانتان به اشتراک بگذارید. تیم تولید محتوای مدرسه اینترنتی پرنیان این مقاله را تهیه کرده است.

8 نظر

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

کلاس طراحی سایت