الأربعاء، 25 مارس 2026

🔌 Next.js API Routes

📖 سلسلة تعلم React و Next.js | المقال 7

⚡ Next.js API Routes - بناء Backend

مع Next.js لا تحتاج Backend منفصل! أنشئ API داخل مشروعك!

🤔 ما هي API Routes؟

API Routes = نقاط نهاية (endpoints) داخل Next.js
تعمل كـ Backend بدون الحاجة لسيرفر منفصل!

📁 المكان:

src/app/api/
├── users/
│   └── route.ts      →  GET /api/users
├── posts/
│   └── route.ts      →  GET /api/posts
└── contact/
    └── route.ts      →  POST /api/contact

📝 إنشاء API بسيط

GET - جلب البيانات:

// src/app/api/users/route.ts

import { NextResponse } from 'next/server';

// بيانات وهمية
const users = [
  { id: 1, name: 'Ahmed', email: 'ahmed@example.com' },
  { id: 2, name: 'Sara', email: 'sara@example.com' },
];

// GET /api/users
export async function GET() {
  return NextResponse.json(users);
}

POST - إرسال بيانات:

// src/app/api/users/route.ts

import { NextResponse } from 'next/server';

// POST /api/users
export async function POST(request: Request) {
  const body = await request.json();
  
  const newUser = {
    id: Date.now(),
    name: body.name,
    email: body.email,
  };
  
  return NextResponse.json(newUser, { status: 201 });
}

📥 استخدام API في المكون

// src/app/users/page.tsx

'use client'; // مطلوب للـ useEffect

import { useState, useEffect } from 'react';

interface User {
  id: number;
  name: string;
  email: string;
}

export default function UsersPage() {
  const [users, setUsers] = useState<User[]>([]);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    // جلب البيانات من API
    fetch('/api/users')
      .then(res => res.json())
      .then(data => {
        setUsers(data);
        setLoading(false);
      });
  }, []);

  if (loading) return <div>جاري التحميل...</div>;

  return (
    <div className="p-8">
      <h1 className="text-2xl font-bold mb-6">المستخدمين</h1>
      <ul className="space-y-2">
        {users.map(user => (
          <li key={user.id} className="p-4 bg-gray-100 rounded">
            {user.name} - {user.email}
          </li>
        ))}
      </ul>
    </div>
  );
}

📤 إرسال بيانات للـ API

const addUser = async (name: string, email: string) => {
  const response = await fetch('/api/users', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({ name, email }),
  });
  
  const newUser = await response.json();
  console.log('تم الإضافة:', newUser);
};

🔧 Dynamic Routes في API

// src/app/api/users/[id]/route.ts

import { NextResponse } from 'next/server';

// GET /api/users/1
export async function GET(
  request: Request,
  { params }: { params: { id: string } }
) {
  const id = params.id;
  
  // البحث عن المستخدم
  const user = { id: parseInt(id), name: 'Ahmed' };
  
  if (!user) {
    return NextResponse.json(
      { error: 'User not found' },
      { status: 404 }
    );
  }
  
  return NextResponse.json(user);
}

📊 HTTP Methods

Method الاستخدام
GETجلب بيانات
POSTإنشاء جديد
PUTتحديث كامل
PATCHتحديث جزئي
DELETEحذف

✨ مميزات API Routes

  • ✅ لا تحتاج Backend منفصل
  • ✅ Serverless Functions (تشتغل عند الطلب)
  • ✅ آمن - الكود لا يظهر للعميل
  • ✅ سهل النشر على Vercel
  • ✅ يدعم TypeScript
💡 نصيحة: استخدم API Routes للـ authentication، database، وملفات حساسة!

📌 تسميات: Next.js API Backend

← المقال السابق | المقال التالي: TypeScript Basics →

سلسلة تعلم React و Next.js مع Ahmed Issa

🛣️ Next.js App Router

📖 سلسلة تعلم React و Next.js | المقال 6

🛤️ Next.js App Router - التوجيه

Next.js يجعل التوجيه سهلاً - كل ملف = صفحة!

📁 نظام الملفات = التوجيه

القاعدة: كل مجلد في src/app/ = مسار URL

مثال:

src/app/
├── page.tsx           →  /
├── about/
│   └── page.tsx       →  /about
├── blog/
│   ├── page.tsx       →  /blog
│   └── [id]/
│       └── page.tsx   →  /blog/:id
└── contact/
    └── page.tsx       →  /contact

📄 إنشاء صفحة جديدة

صفحة About:

// src/app/about/page.tsx

export default function AboutPage() {
  return (
    <div className="p-8">
      <h1 className="text-3xl font-bold mb-4">من نحن</h1>
      <p>هذه صفحة About...</p>
    </div>
  );
}

// ✅ الآن: http://localhost:3000/about

🔗 Dynamic Routes - مسارات ديناميكية

صفحة مقال بـ ID:

// src/app/blog/[id]/page.tsx

interface Props {
  params: { id: string };
}

export default function BlogPost({ params }: Props) {
  return (
    <div className="p-8">
      <h1>المقال رقم: {params.id}</h1>
    </div>
  );
}

// ✅ /blog/1  → params.id = "1"
// ✅ /blog/abc → params.id = "abc"

🎨 Layout - القالب المشترك

// src/app/layout.tsx

import Navbar from '@/components/Navbar';
import Footer from '@/components/Footer';

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="ar" dir="rtl">
      <body>
        <Navbar />
        
        <main>
          {children}
        </main>
        
        <Footer />
      </body>
    </html>
  );
}

🔗 Navigation - التنقل

استخدام Link:

import Link from 'next/link';

export default function Navbar() {
  return (
    <nav>
      <Link href="/">Home</Link>
      <Link href="/about">About</Link>
      <Link href="/blog/1">Blog</Link>
    </nav>
  );
}

// ✅ Link = تنقل سريع بدون إعادة تحميل الصفحة

برمجياً:

'use client';

import { useRouter } from 'next/navigation';

export default function LoginForm() {
  const router = useRouter();

  const handleLogin = async () => {
    // ... تسجيل الدخول
    
    // انتقل للصفحة الرئيسية
    router.push('/dashboard');
  };

  return <button onClick={handleLogin}>دخول</button>;
}

⚙️ Loading & Error

صفحة التحميل:

// src/app/dashboard/loading.tsx

export default function Loading() {
  return (
    <div className="flex justify-center p-8">
      <div className="text-xl">جاري التحميل... ⏳</div>
    </div>
  );
}

صفحة الخطأ:

// src/app/dashboard/error.tsx

'use client';

export default function Error({
  error,
  reset,
}: {
  error: Error;
  reset: () => void;
}) {
  return (
    <div className="p-8 text-center">
      <h2>❌ حدث خطأ!</h2>
      <button onClick={reset}>حاول مرة أخرى</button>
    </div>
  );
}

📊 ملخص

الملف الوظيفة
page.tsxصفحة
layout.tsxقالب مشترك
loading.tsxتحميل
error.tsxخطأ
[id]/page.tsxمسار ديناميكي

📌 تسميات: Next.js App Router تعلم برمجة

← المقال السابق | المقال التالي: API Routes →

سلسلة تعلم React و Next.js مع Ahmed Issa

📊 State و Events

📖 سلسلة تعلم React و Next.js | المقال 5

🔄 State & Events في React

State = الذاكرة. Events = التفاعل. تعلمهما وستبني تطبيقات تفاعلية!

📦 ما هو State؟

State = بيانات يتذكرها المكون ويمكن تغييرها
عندما يتغير State ← يعاد رسم المكون (re-render)

⚡ useState Hook

import { useState } from 'react';

export default function Counter() {
  //        ↓ القيمة    ↓ دالة التحديث     ↓ القيمة الابتدائية
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>العدد: {count}</p>
      <button onClick={() => setCount(count + 1)}>
        زيادة
      </button>
    </div>
  );
}

شرح:

الجزء الشرح
countالقيمة الحالية
setCountدالة لتحديث القيمة
useState(0)القيمة الابتدائية = 0

🖱️ Events - الأحداث

أهم Events:

Event الاستخدام مثال
onClickعند الضغطزر
onChangeعند التغييرinput
onSubmitعند الإرسالform
onFocusعند التركيزinput
onBlurعند الخروجinput

📝 مثال عملي: نموذج تسجيل

import { useState } from 'react';

export default function Form() {
  const [name, setName] = useState('');
  const [email, setEmail] = useState('');
  const [age, setAge] = useState(0);

  const handleSubmit = (e: React.FormEvent) => {
    e.preventDefault(); // منع إعادة تحميل الصفحة
    
    console.log({ name, email, age });
    alert(`مرحباً ${name}!`);
  };

  return (
    <form onSubmit={handleSubmit} className="p-8 space-y-4">
      
      {/* حقل الاسم */}
      <input
        type="text"
        value={name}
        onChange={(e) => setName(e.target.value)}
        placeholder="الاسم"
        className="w-full p-3 border rounded"
      />
      
      {/* حقل البريد */}
      <input
        type="email"
        value={email}
        onChange={(e) => setEmail(e.target.value)}
        placeholder="البريد الإلكتروني"
        className="w-full p-3 border rounded"
      />
      
      {/* حقل العمر */}
      <input
        type="number"
        value={age}
        onChange={(e) => setAge(parseInt(e.target.value))}
        placeholder="العمر"
        className="w-full p-3 border rounded"
      />
      
      {/* زر الإرسال */}
      <button 
        type="submit"
        className="bg-blue-500 text-white px-6 py-2 rounded"
      >
        إرسال
      </button>
      
    </form>
  );
}

⚠️ قواعد مهمة

❌ لا تفعل:
// تغيير State مباشرة
count = count + 1;  // ❌ خطأ!
✅ الصحيح:
// استخدام setFunction
setCount(count + 1);  // ✅ صحيح

🔄 تحديث State بناءً على القيمة السابقة

// ❌ قد يسبب مشاكل
setCount(count + 1);

// ✅ الأفضل - يستخدم القيمة السابقة مباشرة
setCount(prev => prev + 1);

📊 ملخص

المفهوم الشرح
useStateإنشاء State
setFunctionتحديث State
onChangeمتابعة تغييرات input
onSubmitإرسال نموذج

📌 تسميات: React State Events

← المقال السابق | المقال التالي: Forms & Validation →

سلسلة تعلم React و Next.js مع Ahmed Issa

🎨 Tailwind CSS للتنسيق

📖 سلسلة تعلم React و Next.js | المقال 4

🎨 Tailwind CSS في Next.js

Tailwind CSS يجعل التنسيق سهلاً وسريعاً - بدون كتابة CSS!

✅ Tailwind موجود تلقائياً في Next.js - لا تحتاج تثبيت!

📊 مقارنة: CSS عادي vs Tailwind

❌ بدون Tailwind
<div style={{
  minHeight: '100vh',
  display: 'flex',
  flexDirection: 'column',
  alignItems: 'center',
  justifyContent: 'center',
  padding: '2rem',
  backgroundColor: '#3B82F6'
}}>
✅ مع Tailwind
<div className="min-h-screen 
  flex flex-col 
  items-center 
  justify-center 
  p-8 
  bg-blue-500">

🎨 الألوان

خلفية بلون واحد:

bg-red-500
bg-orange-500
bg-yellow-500
bg-green-500
bg-blue-500
bg-purple-500

خلفية متدرجة (Gradient):

bg-gradient-to-r from-pink-500 to-yellow-500

bg-gradient-to-b from-blue-500 to-purple-600

// أفقي →
<div className="bg-gradient-to-r from-pink-500 to-yellow-500">

// عمودي ↓
<div className="bg-gradient-to-b from-blue-500 to-purple-600">

// قطري ↘
<div className="bg-gradient-to-br from-green-400 to-blue-600">

📐 الحجم

Class يعادل
p-4padding: 16px
px-4padding left/right: 16px
py-4padding top/bottom: 16px
m-4margin: 16px
text-xlنص كبير

📦 Flexbox

// Container
<div className="flex">              // display: flex
<div className="flex-col">          // flex-direction: column
<div className="flex-wrap">         // flex-wrap: wrap

// محاذاة أفقية
<div className="justify-center">   // center
<div className="justify-between">  // space-between
<div className="justify-around">   // space-around

// محاذاة عمودية
<div className="items-center">     // center
<div className="items-start">      // start
<div className="items-end">        // end

// المسافات
<div className="gap-4">            // gap: 16px

🎯 مثال عملي: Navbar

<nav className="bg-gray-900 text-white p-4">
  <div className="container mx-auto flex justify-between items-center">
    
    {/* Logo */}
    <div className="text-xl font-bold">
      MyApp
    </div>
    
    {/* Links */}
    <div className="flex gap-6">
      <a href="/" className="hover:text-blue-400 transition">
        Home
      </a>
      <a href="/about" className="hover:text-blue-400 transition">
        About
      </a>
    </div>
    
  </div>
</nav>

✨ Hover & Transitions

// زر مع hover
<button className="
  bg-blue-500 
  text-white 
  px-6 py-2 
  rounded-lg 
  hover:bg-blue-600 
  transition 
  duration-300
">
  اضغط هنا
</button>

📊 ملخص Classes المهمة

الفئة أمثلة
الألوانbg-red-500 text-white
الحجمp-4 m-4 text-xl
Flexboxflex justify-center items-center
Borderborder rounded-lg
Hoverhover:bg-blue-600 transition
💡 نصيحة: استخدم توثيق Tailwind للبحث عن أي class!

📌 تسميات: Tailwind CSS تعلم برمجة

← المقال السابق | المقال التالي: State & Events →

سلسلة تعلم React و Next.js مع Ahmed Issa

🧩 Components و JSX

📖 سلسلة تعلم React و Next.js | المقال 3

🧩 Components & JSX

Components هي اللبنات الأساسية في React. تعلمها وستفهم كل شيء!

🤔 ما هو Component؟

Component = دالة تُرجع HTML (JSX)

// src/app/page.tsx

export default function Home() {
  return (
    <div>
      <h1>مرحباً بالعالم! 👋</h1>
      <p>أول تطبيق React</p>
    </div>
  );
}

✨ ما هو JSX؟

JSX = JavaScript + XML
تستطيع كتابة HTML داخل JavaScript!

قواعد JSX:

1️⃣ استخدام className بدل class
<div className="container">  ✅
<div class="container">        ❌
2️⃣ إغلاق العناصر الفارغة
<img src="photo.jpg" />  ✅
<img src="photo.jpg">     ❌
3️⃣ عنصر جذر واحد
// ✅ صحيح
return (
  <div>
    <h1>العنوان</h1>
    <p>النص</p>
  </div>
);

// ❌ خطأ
return (
  <h1>العنوان</h1>
  <p>النص</p>
);

🧩 إنشاء Component مخصص

أنشئ ملف جديد: src/components/Navbar.tsx

// src/components/Navbar.tsx

export default function Navbar() {
  return (
    <nav className="bg-gray-900 text-white p-4">
      <div className="container mx-auto flex justify-between">
        
        {/* Logo */}
        <div className="text-xl font-bold">
          MyApp
        </div>
        
        {/* Links */}
        <div className="flex gap-6">
          <a href="/">Home</a>
          <a href="/about">About</a>
        </div>
        
      </div>
    </nav>
  );
}

📥 استخدام Component

// src/app/page.tsx

import Navbar from '@/components/Navbar';

export default function Home() {
  return (
    <>
      <Navbar />
      
      <div className="p-8">
        <h1>مرحباً! 👋</h1>
      </div>
    </>
  );
}

🎯 Props - تمرير البيانات

Props = خصائص تمررها للـ Component

// Component مع Props
function UserCard({ name, email }: { name: string; email: string }) {
  return (
    <div className="p-4 border rounded">
      <h3 className="font-bold">{name}</h3>
      <p className="text-gray-600">{email}</p>
    </div>
  );
}

// استخدام
<UserCard name="Ahmed" email="ahmed@example.com" />

📊 ملخص

المفهوم الشرح
Componentدالة تُرجع JSX
JSXHTML داخل JavaScript
Propsبيانات تُمرر للـ Component
classNameبدل class في JSX

📌 تسميات: React Components JSX

← المقال السابق | المقال التالي →

سلسلة تعلم React و Next.js مع Ahmed Issa

🚀 إنشاء مشروع Next.js جديد

📖 سلسلة تعلم React و Next.js | المقال 2

🚀 إنشاء مشروع Next.js جديد

في 5 دقائق فقط، ستكون جاهزاً لبناء أول تطبيق لك!

📋 المتطلبات: Node.js مثبت على جهازك

⚡ الأمر السحري

افتح PowerShell في المجلد الذي تريد إنشاء المشروع فيه:

# 1. أنشئ المشروع
npx create-next-app@latest my-app

# 2. ادخل المشروع
cd my-app

# 3. شغّل
npm run dev

# 4. افتح المتصفح
# http://localhost:3000

❓ الأسئلة أثناء التثبيت

سيطلب منك عدة أسئلة، هذه الإجابات الموصى بها:

السؤال الإجابة السبب
TypeScript? ✅ Yes كود آمن وأقل أخطاء
ESLint? ✅ Yes كود أنظف
Tailwind CSS? ✅ Yes تنسيق سريع
src/ directory? ✅ Yes تنظيم أفضل
App Router? ✅ Yes الأحدث والأفضل
Customize import alias? ❌ No الافتراضي كافي

📁 هيكل المشروع

my-app/
├── src/
│   ├── app/              # الصفحات
│   │   ├── page.tsx      # الصفحة الرئيسية (/)
│   │   ├── layout.tsx    # القالب العام
│   │   └── globals.css   # الأنماط
│   └── components/       # المكونات (أنشئها)
├── public/               # ملفات ثابتة
├── package.json          # المكتبات
└── next.config.ts        # إعدادات Next.js

🎯 الملفات المهمة

الملف الوظيفة
src/app/page.tsxالصفحة الرئيسية
src/app/layout.tsxقالب كل الصفحات
src/app/globals.cssCSS عام
src/components/مكوناتك القابلة لإعادة الاستخدام

⚡ أوامر مهمة

الأمر الوظيفة
npm run devتشغيل التطبيق (localhost:3000)
npm run buildبناء للإنتاج
npm run startتشغيل النسخة المبنية

🎉 تهانينا!

مشروعك جاهز! 🚀

افتح src/app/page.tsx وابدأ التعديل!

🚀 الخطوة التالية

في المقال القادم سنتعلم Components و JSX!

📌 تسميات: Next.js تعلم برمجة بداية

← المقال السابق | المقال التالي →

سلسلة تعلم React و Next.js مع Ahmed Issa

🤔 React أم Next.js؟ أيهما تختار؟

📖 سلسلة تعلم React و Next.js | المقال 1

🤔 React أم Next.js؟ أيهما تختار؟

إذا كنت تبدأ مشروع جديد، هذا السؤال مهم جداً. الإجابة القصيرة: اختر Next.js!

✅ الخيار الأسهل: اختر Next.js دائماً - إلا إذا كنت تصنع مكتبة فقط!

📊 مقارنة سريعة

الميزة Next.js React فقط
Routing ✅ مدمج تلقائياً ❌ تحتاج react-router
Server Side Rendering ✅ مدمج ❌ لا يوجد
SEO ✅ ممتاز ⚠️ ضعيف
API Routes ✅ مدمج ❌ تحتاج backend منفصل
Deployment ✅ Vercel مجاني ⚠️ Static hosts
Image Optimization ✅ تلقائي ❌ يدوي

🤔 ما الفرق؟

React: مكتبة لبناء واجهات المستخدم. تهتم بالـ UI فقط.
Next.js: إطار عمل (Framework) مبني على React. يضيف كل ما تحتاجه لمشروع كامل.

✅ متى أستخدم كل واحد؟

استخدم Next.js عندما:

  • تبني موقع أو تطبيق ويب كامل
  • تحتاج SEO جيد (مدونة، متجر، شركة)
  • تريد API بدون backend منفصل
  • تبني تطبيق إنتاج (Production)

استخدم React فقط عندما:

  • تصنع مكتبة (Library)
  • تتعلم أساسيات React
  • تطبيق بسيط جداً لا يحتاج routing

📈 الإحصائيات

99%

من المشاريع الجديدة تستخدم Next.js

🚀 الخطوة التالية

في المقال القادم سنتعلم كيفية إنشاء مشروع Next.js جديد من الصفر!

📌 تسميات: React Next.js تعلم برمجة

← المقال السابق | المقال التالي →

سلسلة تعلم React و Next.js مع Ahmed Issa