البداية · فصل ٢

registry.json — فهرس الـ Registry

$schema · name · homepage · items · include
🎯 الهدف: تكتب registry.json صح، سواء ملف واحد أو مقسوم بـ include، وتعرف قواعد المسارات والأسماء.

الفكرة

registry.json هو نقطة الدخول للـ registry. لازم يكون موجود في الـ root بتاع الـ endpoint، يعني المكان اللي الـ registry متقدم عليه.

الحقول

الحقلمعناه
$schemaرابط الـ schema عشان الـ editor يكمّل ويصحّح
nameاسم الـ registry، بيتستخدم في data attributes وmetadata
homepageموقع الـ registry، برضه للـ metadata
itemsقائمة الـ items، وكل واحد بيمشي على registry-item schema
includeقائمة ملفات registry.json تانية تتجمّع في الفهرس
  • الـ root لازم يكون فيه items أو include أو الاتنين مع بعض.
  • لو items مش موجودة، قيمتها الافتراضية array فاضية.

الطريقة الأولى: ملف واحد

أبسط حاجة: كل الـ items في items جوه ملف واحد.

registry.json
{  "$schema": "https://ui.shadcn.com/schema/registry.json",  "name": "nile",  "homepage": "https://nile.dev",  "items": [    {      "name": "money-input",      "type": "registry:ui",      "title": "Money Input",      "description": "Input بيكتب المبلغ بالجنيه ويحط الفواصل.",      "files": [        { "path": "components/ui/money-input.tsx", "type": "registry:ui" }      ]    },    {      "name": "checkout-card",      "type": "registry:block",      "title": "Checkout Card",      "description": "كارت دفع فيه money-input وزرار.",      "registryDependencies": ["button", "https://nile.dev/r/money-input.json"],      "files": [        { "path": "registry/default/checkout-card/checkout-card.tsx", "type": "registry:component" }      ]    }  ]}
  • في الطريقة دي، path نسبي لـ root المشروع.

الطريقة التانية: include للـ registries الكبيرة

لما الـ items تكتر، خلي كل فولدر ليه registry.json جنب ملفاته:

registry.jsoncomponents└── ui    ├── money-input.tsx    ├── otp-input.tsx    └── registry.jsonhooks├── registry.json├── use-copy.ts└── use-media-query.ts
registry.json
{  "$schema": "https://ui.shadcn.com/schema/registry.json",  "name": "nile",  "homepage": "https://nile.dev",  "include": ["components/ui/registry.json", "hooks/registry.json"]}
hooks/registry.json
{  "$schema": "https://ui.shadcn.com/schema/registry.json",  "items": [    {      "name": "use-copy",      "type": "registry:hook",      "files": [{ "path": "use-copy.ts", "type": "registry:hook" }]    }  ]}

قواعد include

  • المسار: كل عنصر في include لازم يكون مسار نسبي لملف registry.json بالاسم. اختصار الفولدر ("hooks" لوحده) مش مدعوم.
  • name وhomepage: مطلوبين في الـ root بس. الملفات الـ included تقدر تسيبهم.
  • مسار الملفات: path بيبقى نسبي لملف registry.json اللي معرّف الـ item. عشان كده كتبنا use-copy.ts مش hooks/use-copy.ts.
  • الأسماء: اسم كل item لازم يكون unique في الـ registry كله بعد ما الـ includes تتجمع.
  • بعد الـ build: shadcn build بيجمّع كل الـ includes ويطلّع registry.json واحد flat مفيهوش include، والمسارات بتتكتب نسبية للـ root.

نصايح التنظيم

  • مكان الملفات: حط ملفات الـ item تحت registry/[STYLE]/[NAME]، زي registry/default/checkout-card. الـ default ممكن يبقى أي اسم، المهم يكون تحت registry.
  • الـ imports جوه الـ registry: خليها دايمًا من @/registry، زي import { MoneyInput } from "@/registry/default/money-input/money-input".
  • الفولدرات جوه الـ item: الأحسن تقسّم الملفات على components وhooks وlib.
  • الـ blocks: لازم يبقى فيها name وdescription وtype وfiles.
  • name وdescription كويسين: بيساعدوا الـ LLMs تفهم الـ item بيعمل إيه.
  • كل الـ registry dependencies تتكتب في registryDependencies، وكل الـ npm packages في dependencies (والـ version بالشكل zod@^3.20.0).

خلّصت الفصل لما

🧠 اختبر نفسك
١) ملف hooks/registry.json فيه item ملفه hooks/use-copy.ts. تكتب path إيه؟
use-copy.ts، لأن المسار نسبي للـ registry.json اللي معرّف الـ item.
٢) ينفع أكتب include: ["hooks"]؟
لأ. لازم المسار الكامل لملف hooks/registry.json.
٣) ملف included معندوش name. مشكلة؟
لأ. name وhomepage مطلوبين في الـ root بس.
٤) item اسمه button في ملفين included مختلفين. ينفع؟
لأ. الأسماء لازم تبقى unique في الـ registry كله بعد التجميع.