شادcn/ui: دليل المبتدئين للبدء

Audrey Lopez

Audrey Lopez

14 يونيو 2025

شادcn/ui: دليل المبتدئين للبدء

بالنسبة لمطوري الويب، البحث عن مجموعة أدوات واجهة المستخدم المثالية هو مسعى مستمر. لسنوات، اعتمد مطورو React على مكتبات المكونات التقليدية مثل Material-UI (MUI) وAnt Design وChakra UI. تقدم هذه المكتبات ثروة من المكونات المعدة مسبقًا، واعدة بتسريع عملية التطوير. ومع ذلك، غالبًا ما تأتي مع مقايضة: نقص في التحكم، وتجاوزات في الأنماط تبدو كمعركة، وأحجام حزمة (bundle) متضخمة.

ادخل إلى عالم Shadcn UI، وهو نهج يغير النموذج وقد اجتاح مجتمع React. إنها ليست مكتبة مكونات بالطريقة التي اعتدت عليها؛ إنها شيء أفضل. إنها مجموعة من المكونات المصممة بشكل جميل، والتي يمكن الوصول إليها، وقابلة لإعادة الاستخدام بلا حدود، والتي لا تقوم بتثبيتها من npm كاعتمادية - بل تقوم بنسخها مباشرة إلى مشروعك.

سيكون هذا البرنامج التعليمي الشامل، الذي يبلغ طوله 4000 كلمة، دليلك النهائي، حيث يأخذك من مبتدئ تمامًا إلى ممارس واثق في Shadcn UI. سنستكشف فلسفته التأسيسية، ونستعرض إعدادًا تفصيليًا، ونبني واجهات مستخدم معقدة، ونتقن التخصيص المتقدم للسمات (theming) والتعامل مع النماذج (form handling)، ونناقش أفضل الممارسات للتطبيقات واسعة النطاق. استعد لإعادة التفكير فيما تتوقعه من مجموعة أدوات واجهة المستخدم.

💡
هل تريد أداة اختبار API رائعة تولد توثيق API جميل؟

هل تريد منصة متكاملة وشاملة لفريق المطورين لديك للعمل معًا بأقصى إنتاجية؟

Apidog يلبي جميع متطلباتك، ويحل محل Postman بسعر معقول أكثر بكثير!
button

فلسفة Shadcn UI - طريقة جديدة للبناء

قبل كتابة سطر واحد من التعليمات البرمجية، من الضروري فهم لماذا يوجد Shadcn UI وما هي المشاكل التي يحلها. فهم هذه الفلسفة الأساسية هو مفتاح إطلاق كامل إمكاناته.

ما ليس Shadcn UI

ما هو Shadcn UI

الميزة الأساسية لهذا النموذج هي دمج **السرعة والتحكم**. تحصل على السرعة الأولية لاستخدام المكونات المعدة مسبقًا دون التضحية بالمرونة وقابلية الصيانة على المدى الطويل التي تأتي من امتلاك التعليمات البرمجية الخاصة بك.


إعداد المسرح - إعداد المشروع والتثبيت

دعنا ننتقل من النظرية إلى التطبيق العملي. سنقوم بإعداد مشروع جديد من الصفر. لهذا الدليل، سنستخدم بشكل أساسي **Next.js**، حيث تتوافق مكونات الخادم الخاصة به والتوجيه المستند إلى الملفات بشكل مثالي مع روح Shadcn UI. سنغطي أيضًا إعداد Vite باختصار.

الخطوة 1: المتطلبات الأساسية للبيئة

تأكد من أن بيئة التطوير لديك جاهزة. ستحتاج إلى:

الخطوة 2: إنشاء تطبيق Next.js جديد

افتح الطرفية (terminal) ونفذ الأمر التالي لتهيئة مشروع Next.js جديد.Bash

npx create-next-app@latest my-pro-shadcn-app --typescript --tailwind --eslint

ينشئ هذا الأمر تطبيقًا جديدًا في مجلد باسم my-pro-shadcn-app. لقد قمنا بتضمين بعض العلامات المهمة:

سيطلب منك المثبت بعض الأسئلة. هذه هي الخيارات الموصى بها لإعداد Next.js 14+ حديث:

✔ Would you like to use `src/` directory? … No / **Yes**
✔ Would you like to use App Router? (recommended) … No / **Yes**
✔ Would you like to customize the default import alias? … **No** / Yes

يُعد استخدام App Router ممارسة قياسية، ويساعد مجلد src/ في تنظيم التعليمات البرمجية. بمجرد الانتهاء، انتقل إلى مشروعك الجديد:Bash

cd my-pro-shadcn-app

الخطوة 3: الأمر init - إضفاء الحياة على Shadcn UI

هذه هي الخطوة الأكثر أهمية. يوفر Shadcn UI أداة سطر أوامر (CLI) لتكوين مشروعك. قم بتشغيل الأمر التالي من الدليل الجذر لمشروعك:Bash

npx shadcn-ui@latest init

سيؤدي هذا إلى تشغيل استبيان تفاعلي لإعداد مشروعك. دعنا نفصل كل سؤال وأهميته:

بعد التأكيد، يقوم CLI بسحره:

  1. تثبيت الاعتماديات: يضيف الحزم الضرورية مثل tailwindcss-animate و class-variance-authority.
  2. إنشاء components.json: يخزن اختيارات التكوين الخاصة بك.
  3. تحديث tailwind.config.ts: يحقن مكون Shadcn UI الإضافي وتكوين السمات.
  4. تحديث globals.css: يضيف كتلة كبيرة من متغيرات CSS التي تحدد لوحة الألوان الكاملة، ونصف أقطار الحدود، والمزيد.
  5. إنشاء lib/utils.ts: يصدر هذا الملف دالة مساعدة cn، وهي أداة مساعدة ذكية لدمج فئات Tailwind CSS بشكل شرطي.

مشروعك الآن مُكوّن بالكامل.

(بديل: إعداد Vite)

إذا كنت تستخدم Vite مع React، فإن العملية مشابهة جدًا. بعد إعداد مشروع Vite + React + TS، ستقوم بتثبيت Tailwind CSS يدويًا ثم تشغيل npx shadcn-ui@latest init. أداة CLI ذكية بما يكفي لاكتشاف إعداد Vite وستطرح أسئلة مختلفة قليلاً حول مواقع الملفات (على سبيل المثال، index.css بدلاً من globals.css).


بناء واجهة مستخدم - من المكونات البسيطة إلى التخطيطات المعقدة

مع اكتمال الإعداد، دعنا نبدأ البناء. سير العمل الأساسي هو: **تحديد الحاجة، إضافة المكون، استخدامه.**

الخطوة 4: إضافة واستخدام مكوناتك الأولى

دعنا ننظف القالب الافتراضي لـ Next.js ونبني واجهة بسيطة.

1. إضافة زر:Bash

npx shadcn-ui@latest add button

لاحظ ما يحدث: يتم إنشاء ملف جديد، src/components/ui/button.tsx. هذا هو زرّك. أنت تملكه.

2. إضافة بطاقة (Card):Bash

npx shadcn-ui@latest add card

هذا الأمر أكثر إثارة للاهتمام. ينشئ src/components/ui/card.tsx. إذا فحصت هذا الملف، سترى أنه يصدر مكونات متعددة: Card، CardHeader، CardTitle، CardDescription، CardContent، و CardFooter. هذا نمط شائع للمكونات المركبة (compound components).

3. بناء واجهة المستخدم:

الآن، افتح src/app/page.tsx واستبدل محتواه بما يلي:TypeScript

import { Button } from "@/components/ui/button";
import {
  Card,
  CardContent,
  CardDescription,
  CardFooter,
  CardHeader,
  CardTitle,
} from "@/components/ui/card";
import { Input } from "@/components/ui/input"; // We'll add this next
import { Label } from "@/components/ui/label";   // And this

export default function Home() {
  return (
    <main className="flex min-h-screen items-center justify-center bg-background p-8">
      <Card className="w-full max-w-md">
        <CardHeader>
          <CardTitle className="text-2xl">Create Project</CardTitle>
          <CardDescription>
            Deploy your new project in one-click.
          </CardDescription>
        </CardHeader>
        <CardContent className="grid gap-4">
          <div className="grid gap-2">
            <Label htmlFor="name">Name</Label>
            <Input id="name" placeholder="Name of your project" />
          </div>
          <div className="grid gap-2">
            <Label htmlFor="framework">Framework</Label>
            {/* We'll replace this with a Select component later */}
            <Input id="framework" placeholder="e.g. Next.js" />
          </div>
        </CardContent>
        <CardFooter>
          <Button className="w-full">Deploy</Button>
        </CardFooter>
      </Card>
    </main>
  );
}

لن يعمل الكود الخاص بنا بعد لأننا نفتقد مكوني Input و Label. دعنا نضيفهما:Bash

npx shadcn-ui@latest add input
npx shadcn-ui@latest add label

الآن، قم بتشغيل خادم التطوير الخاص بك:Bash

npm run dev

انتقل إلى http://localhost:3000. سترى نموذجًا نظيفًا وذو مظهر احترافي داخل بطاقة. لاحظ كيف استخدمنا فئات الأدوات المساعدة (utility classes) مثل w-full و max-w-md و grid مباشرة في JSX للتحكم في التخطيط. هذه هي قوة الجمع بين Shadcn وTailwind CSS.

الخطوة 5: تقديم مكونات أكثر تطوراً

المدخلات الثابتة جيدة، لكن التطبيقات الحقيقية تحتاج إلى عناصر تفاعلية. دعنا نحسن نموذجنا.

1. إضافة مكون Select: يجب أن يكون حقل 'Framework' قائمة منسدلة. دعنا نضيف مكون Select. هذا المكون أكثر تعقيدًا ويعتمد على مكونات أخرى. Bash

npx shadcn-ui@latest add select

أداة CLI ذكية. سترى أن Select يتطلب مكون Popover ليعمل وستطلب إذنك لتثبيته هو واعتمادياته أيضًا. هذه ميزة رائعة تمنعك من الاضطرار إلى تتبع الاعتماديات يدويًا.

2. دمج مكون Select: استبدل حقل Input الخاص بـ 'Framework' في src/app/page.tsx بمكون Select الجديد. TypeScript

// Add these imports at the top
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";

// ... inside the CardContent
<div className="grid gap-2">
  <Label htmlFor="framework">Framework</Label>
  <Select>
    <SelectTrigger id="framework">
      <SelectValue placeholder="Select a framework" />
    </SelectTrigger>
    <SelectContent>
      <SelectItem value="nextjs">Next.js</SelectItem>
      <SelectItem value="sveltekit">SvelteKit</SelectItem>
      <SelectItem value="astro">Astro</SelectItem>
      <SelectItem value="nuxt">Nuxt.js</SelectItem>
    </SelectContent>
  </Select>
</div>

حدث صفحة المتصفح. لديك الآن قائمة منسدلة قابلة للتحديد وعملية بالكامل، مع رسوم متحركة وتنقل صحيح بلوحة المفاتيح، كل ذلك بفضل Radix UI الذي يعمل تحت الغطاء.

3. إضافة ملاحظات للمستخدم باستخدام Toast: ماذا يحدث عندما ينقر المستخدم على 'Deploy'؟ يجب أن نقدم له بعض الملاحظات. مكون Toast مثالي لذلك.

أولاً، أضفه:Bash

npx shadcn-ui@latest add toast

بعد ذلك، لاستخدام التنبيهات (toasts)، تحتاج إلى إضافة مكون <Toaster /> إلى تخطيطك الجذري (root layout) حتى يمكن عرضه في أي مكان في التطبيق. افتح src/app/layout.tsx وقم بتعديله:TypeScript

import { Toaster } from "@/components/ui/toaster" // Import the Toaster

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en">
      <body>
        {children}
        <Toaster /> {/* Add it here, just before closing body */}
      </body>
    </html>
  )
}

الآن، نحتاج إلى طريقة لتشغيل التنبيه (toast). سنستخدم hook useToast. دعنا نحدث src/app/page.tsx لجعله مكون عميل (client component) والتعامل مع نقرة الزر. TypeScript

'use client'; // <-- Add this at the very top of the file

// ... other imports
import { useToast } from "@/components/ui/use-toast";

export default function Home() {
  const { toast } = useToast(); // Get the toast function from the hook

  function handleDeploy() {
    toast({
      title: "Deployment Scheduled!",
      description: "Your project 'Name of your project' is being deployed.",
      duration: 5000,
    });
  }

  return (
    <main className="flex min-h-screen items-center justify-center bg-background p-8">
      <Card className="w-full max-w-md">
        {/* ... CardHeader and CardContent ... */}
        <CardFooter>
          <Button className="w-full" onClick={handleDeploy}> {/* Add onClick handler */}
            Deploy
          </Button>
        </CardFooter>
      </Card>
    </main>
  );
}

الآن، عند النقر على زر 'Deploy'، سيظهر إشعار أنيق في زاوية الشاشة.


بناء نموذج احترافي مع التحقق من الصحة (Validation)

تتطلب معظم التطبيقات الواقعية معالجة قوية للنماذج، بما في ذلك التحقق من صحة البيانات من جانب العميل. الطريقة الرسمية للتعامل مع هذا باستخدام Shadcn UI هي دمجه مع react-hook-form لإدارة الحالة و zod للتحقق من صحة المخطط (schema). دعنا نبنيه.

الخطوة 6: تثبيت اعتماديات النموذج

أولاً، دعنا نثبت المكتبات الضرورية:Bash

npm install react-hook-form zod @hookform/resolvers

الخطوة 7: إضافة مكون Form من Shadcn

يوفر Shadcn UI مكون Form خاصًا يعمل كغلاف لربط react-hook-form بسلاسة مع مكونات واجهة المستخدم الخاصة بك. Bash

npx shadcn-ui@latest add form

سيضيف هذا src/components/ui/form.tsx. يوفر هذا الملف مجموعة من المكونات الواعية بالسياق (Form، FormField، FormItem، FormLabel، FormControl، FormDescription، FormMessage) التي تقلل بشكل كبير من التعليمات البرمجية المتكررة (boilerplate).

الخطوة 8: إنشاء مخطط التحقق من الصحة (Validation Schema)

في ملف src/app/page.tsx الخاص بك، دعنا نحدد شكل وقواعد بيانات نموذجنا باستخدام zod. TypeScript

// Add these imports at the top
import { z } from "zod";
import { zodResolver } from "@hookform/resolvers/zod";
import { useForm } from "react-hook-form";
import {
  Form,
  FormControl,
  FormDescription,
  FormField,
  FormItem,
  FormLabel,
  FormMessage,
} from "@/components/ui/form";

الآن، دعنا ننشئ المخطط فوق مكون Home مباشرة:TypeScript

const formSchema = z.object({
  projectName: z.string().min(2, {
    message: "Project name must be at least 2 characters.",
  }).max(50, {
    message: "Project name must not exceed 50 characters.",
  }),
  framework: z.string({
    required_error: "Please select a framework to display.",
  }),
});

يحدد هذا المخطط حقلين: projectName يجب أن يكون سلسلة نصية بين 2 و 50 حرفًا، و framework هو سلسلة نصية مطلوبة.

الخطوة 9: ربط النموذج

الآن، دعنا نعيد هيكلة مكون Home الخاص بنا لاستخدام كل هذه الأدوات الجديدة. TypeScript

export default function Home() {
  const { toast } = useToast();

  // 1. Define your form.
  const form = useForm<z.infer<typeof formSchema>>({
    resolver: zodResolver(formSchema),
    defaultValues: {
      projectName: "",
    },
  });

  // 2. Define a submit handler.
  function onSubmit(values: z.infer<typeof formSchema>) {
    // Do something with the form values.
    // ✅ This will be type-safe and validated.
    console.log(values);
    toast({
      title: "You submitted the following values:",
      description: (
        <pre className="mt-2 w-[340px] rounded-md bg-slate-950 p-4">
          <code className="text-white">{JSON.stringify(values, null, 2)}</code>
        </pre>
      ),
    });
  }

  // 3. Build the JSX with Shadcn's Form components
  return (
    <main className="flex min-h-screen items-center justify-center bg-background p-8">
      <Card className="w-full max-w-md">
        <CardHeader>
          <CardTitle className="text-2xl">Create Project</CardTitle>
          <CardDescription>
            Deploy your new project in one-click.
          </CardDescription>
        </CardHeader>
        <CardContent>
          <Form {...form}>
            <form onSubmit={form.handleSubmit(onSubmit)} className="space-y-8">
              <FormField
                control={form.control}
                name="projectName"
                render={({ field }) => (
                  <FormItem>
                    <FormLabel>Name</FormLabel>
                    <FormControl>
                      <Input placeholder="Name of your project" {...field} />
                    </FormControl>
                    <FormDescription>
                      This is your public display name.
                    </FormDescription>
                    <FormMessage /> {/* Displays validation errors */}
                  </FormItem>
                )}
              />
              <FormField
                control={form.control}
                name="framework"
                render={({ field }) => (
                  <FormItem>
                    <FormLabel>Framework</FormLabel>
                    <Select onValueChange={field.onChange} defaultValue={field.value}>
                      <FormControl>
                        <SelectTrigger>
                          <SelectValue placeholder="Select a framework" />
                        </SelectTrigger>
                      </FormControl>
                      <SelectContent>
                        <SelectItem value="nextjs">Next.js</SelectItem>
                        <SelectItem value="sveltekit">SvelteKit</SelectItem>
                        <SelectItem value="astro">Astro</SelectItem>
                        <SelectItem value="nuxt">Nuxt.js</SelectItem>
                      </SelectContent>
                    </Select>
                    <FormDescription>
                      The framework you want to deploy.
                    </FormDescription>
                    <FormMessage />
                  </FormItem>
                )}
              />
              <Button type="submit" className="w-full">Deploy</Button>
            </form>
          </Form>
        </CardContent>
      </Card>
    </main>
  );
}

هذه قطعة كبيرة من التعليمات البرمجية، لكنها نمط قوي وقابل للتوسع بشكل لا يصدق. يتعامل مكون FormField مع جميع اتصالات الحالة، ويعرض FormMessage تلقائيًا خطأ التحقق الصحيح من مخطط zod الخاص بك عندما يتفاعل المستخدم مع الحقل. حاول إرسال النموذج باسم مشروع فارغ لترى التحقق من الصحة عمليًا.


إتقان السمات والتخصيص

تُطلق القوة الحقيقية لـ Shadcn UI عندما تبدأ في جعله خاصًا بك.

الخطوة 10: التخصيص المتقدم للسمات باستخدام متغيرات CSS

يتم تعريف السمة الكاملة الخاصة بك بواسطة متغيرات CSS في src/app/globals.css. افتح هذا الملف وابحث عن كتل :root و .dark. CSS

/* Example from globals.css */
:root {
  --background: 0 0% 100%;
  --foreground: 222.2 84% 4.9%;
  --primary: 222.2 47.4% 11.2%;
  --primary-foreground: 210 40% 98%;
  /* ... and many more */
  --radius: 0.5rem;
}

.dark {
  --background: 222.2 84% 4.9%;
  --foreground: 210 40% 98%;
  --primary: 210 40% 98%;
  --primary-foreground: 222.2 47.4% 11.2%;
  /* ... */
}

تطبيق الوضع الداكن:

تم تكوين Shadcn مسبقًا للوضع الداكن بفضل كتلة الفئة .dark واستراتيجية Tailwind darkMode: "class" في tailwind.config.ts. كل ما تحتاجه هو طريقة لتبديل فئة dark على عنصر <html>. مكتبة شائعة لهذا الغرض هي next-themes.

  1. قم بتثبيتها: npm install next-themes
  2. أنشئ مكون ThemeProvider (src/components/theme-provider.tsx): TypeScript
"use client"
import * as React from "react"
import { ThemeProvider as NextThemesProvider } from "next-themes"
import { type ThemeProviderProps } from "next-themes/dist/types"

export function ThemeProvider({ children, ...props }: ThemeProviderProps) {
  return <NextThemesProvider {...props}>{children}</NextThemesProvider>
}
  1. قم بتغليف RootLayout الخاص بك بهذا المزود (src/app/layout.tsx): TypeScript
import { ThemeProvider } from "@/components/theme-provider"

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en" suppressHydrationWarning>
      <body>
        <ThemeProvider
          attribute="class"
          defaultTheme="system"
          enableSystem
          disableTransitionOnChange
        >
          {children}
          <Toaster />
        </ThemeProvider>
      </body>
    </html>
  )
}
  1. أخيرًا، أنشئ زر تبديل (على سبيل المثال، src/components/mode-toggle.tsx): TypeScript
"use client"
import * as React from "react"
import { Moon, Sun } from "lucide-react"
import { useTheme } from "next-themes"
import { Button } from "@/components/ui/button"

export function ModeToggle() {
  const { theme, setTheme } = useTheme()

  return (
    <Button
      variant="outline"
      size="icon"
      onClick={() => setTheme(theme === "light" ? "dark" : "light")}
    >
      <Sun className="h-[1.2rem] w-[1.2rem] rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0" />
      <Moon className="absolute h-[1.2rem] w-[1.2rem] rotate-90 scale-0 transition-all dark:rotate-0 dark:scale-100" />
      <span className="sr-only">Toggle theme</span>
    </Button>
  )
}

يمكنك الآن وضع <ModeToggle /> هذا في أي مكان في تطبيقك للحصول على تبديل للوضع الداكن يراعي النظام وقابل للتجاوز من قبل المستخدم.

الخطوة 11: تخصيص التعليمات البرمجية المصدر للمكون

هذه هي القوة الخارقة المطلقة. لنفترض أنك تريد نوعًا جديدًا للنجاح (success variant) لزرّك بخلفية خضراء.

افتح src/components/ui/button.tsx. ابحث عن تعريف buttonVariants. يستخدم cva (Class Variance Authority). ببساطة أضف نوعًا جديدًا:TypeScript

const buttonVariants = cva(
  // ... base styles
  {
    variants: {
      variant: {
        default: "bg-primary text-primary-foreground hover:bg-primary/90",
        destructive: "bg-destructive text-destructive-foreground hover:bg-destructive/90",
        outline: "border border-input bg-background hover:bg-accent hover:text-accent-foreground",
        secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80",
        ghost: "hover:bg-accent hover:text-accent-foreground",
        link: "text-primary underline-offset-4 hover:underline",
        success: "bg-green-600 text-white hover:bg-green-600/90", // Our new variant
      },
      // ... size variants
    },
    defaultVariants: {
      variant: "default",
      size: "default",
    },
  }
)

هذا كل شيء. يمكنك الآن استخدامه في التعليمات البرمجية الخاصة بك: <Button variant="success">Success</Button>. لم تكن بحاجة لكتابة تجاوزات CSS معقدة. لقد قمت فقط بتحرير التعليمات البرمجية المصدر للمكون نفسه. سير العمل هذا بسيط، قابل للتنبؤ، وقوي بشكل لا يصدق.


الجزء 6: أفضل الممارسات والطريق إلى الأمام

مع نمو تطبيقك، إليك بعض أفضل الممارسات التي يجب وضعها في الاعتبار.

الخاتمة: أنت مؤلف المكتبة

لقد سافرت الآن من الفلسفة الأساسية لـ Shadcn UI إلى تطبيق أنماط متقدمة وعالمية واقعية. لقد رأيت أن ابتكاره الحقيقي ليس فقط في المكونات نفسها، بل في التحول النموذجي الذي يمثله. إنه ينقل المطورين من مجرد *مستهلكين* لمكتبة إلى *قائمين على التنسيق* و *مالكين* لمجموعة أدوات واجهة المستخدم الخاصة بهم.

من خلال منحك التعليمات البرمجية المصدر الخام، والبناء على الأسس القوية لـ Tailwind CSS و Radix UI، وتوفير تجربة CLI سلسة، يحقق Shadcn UI التوازن المثالي بين سرعة التطوير الأولية وقابلية الصيانة على المدى الطويل والحرية الإبداعية. لم تعد مقيدًا بنظام تصميم شخص آخر. المكونات في مشروعك هي ملكك - لتعديلها وتوسيعها وإتقانها.

مستقبل واجهة المستخدم لتطبيقك لم يعد في أيدي اعتمادية خارجية؛ إنه موجود هناك في مجلد components الخاص بك. بناء سعيد.

💡
هل تريد أداة اختبار API رائعة تولد توثيق API جميل؟

هل تريد منصة متكاملة وشاملة لفريق المطورين لديك للعمل معًا بأقصى إنتاجية؟

Apidog يلبي جميع متطلباتك، ويحل محل Postman بسعر معقول أكثر بكثير!
button

ممارسة تصميم API في Apidog

اكتشف طريقة أسهل لبناء واستخدام واجهات برمجة التطبيقات