انتقل إلى المحتوى

البدء

يشرح هذا الدليل إعداد موقع توثيق باستخدام Onedocs بدءًا من مجلد فارغ. إذا كان لديك مشروع Next.js بالفعل، فتجاوز الملفات الموجودة لديك وقارن البقية.

المتطلبات الأساسية

  • Node.js 20.9 أو أحدث (يتطلب Next.js 16)
  • Next.js 16 مع App Router، وReact 19.2 أو أحدث
  • Tailwind CSS v4 (يستورد إعداد Onedocs المسبق CSS tailwindcss)

لا يدعم Fumadocs UI 16 سوى Next.js 16 وReact 19.2، لذا لن تعمل إصدارات Next.js أو React الأقدم، رغم أن بيانات الحزمة الوصفية لـonedocs ما تزال تدرجها (#5).

التثبيت

لا يضمّن Onedocs Next.js أو Fumadocs. فهما اعتمادان نظيران، لذا ثبّتهما إلى جانبه:

سطر الأوامر
npm install onedocs fumadocs-core fumadocs-mdx fumadocs-ui lucide-react@0.562 next react react-dom
npm install -D tailwindcss @tailwindcss/postcss typescript @types/react @types/react-dom @types/node

أبقِ تثبيت lucide-react@0.562. يعلن onedocs 0.1.27 أن lucide-react ^0.562.0 اعتماد نظير، ومن دون التثبيت المحدد، يثبّت npm إصدار lucide-react 1.x ويتوقف مع خطأ ERESOLVE (#1).

تعمل الحزم نفسها مع pnpm أو yarn أو bun.

أضف نصوص Next.js البرمجية إلى package.json:

JSON
{
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start"
  }
}

بنية المشروع

إليك ما ستحصل عليه في النهاية:

الكود
your-project/
├── content/
│   └── docs/
│       ├── index.mdx
│       └── meta.json
├── public/
│   └── fonts/
│       └── InterVariable.woff2
├── src/
│   ├── app/
│   │   ├── layout.tsx
│   │   ├── page.tsx
│   │   ├── globals.css
│   │   └── docs/
│   │       ├── layout.tsx
│   │       └── [[...slug]]/
│   │           └── page.tsx
│   └── lib/
│       └── source.ts
├── onedocs.config.ts
├── source.config.ts
├── next.config.mjs
├── postcss.config.mjs
├── tsconfig.json
└── package.json

لننشئ كل ملف.

ملفات الإعداد

onedocs.config.ts

ملف الإعداد الرئيسي. لا يلزم سوى title؛ راجع الإعداد للاطلاع على البقية.

TypeScript
import { defineConfig } from "onedocs/config";

export default defineConfig({
  title: "My Docs",
  description: "Documentation for my project",
  nav: {
    github: "username/repo",
  },
});

source.config.ts

يخبر Fumadocs MDX بمكان المحتوى. وهذا هو الموضع الوحيد الذي يُحدَّد فيه مجلد المحتوى:

TypeScript
import { defineDocs } from "fumadocs-mdx/config";

export const docs = defineDocs({
  dir: "content/docs",
});

next.config.mjs

يتيح معالجة MDX:

JavaScript
import { createMDX } from "fumadocs-mdx/next";

const withMDX = createMDX();

/** @type {import('next').NextConfig} */
const config = {};

export default withMDX(config);

ينشئ Fumadocs MDX مجلد .source/ من source.config.ts عند بدء Next.js. أضف .source إلى .gitignore.

postcss.config.mjs

يشغّل Tailwind CSS v4، الذي بُني عليه الإعداد المسبق لـOnedocs CSS:

JavaScript
export default {
  plugins: {
    "@tailwindcss/postcss": {},
  },
};

tsconfig.json

تستورد الأمثلة أدناه من @/، لذا اربطه بـsrc/:

JSON
{
  "compilerOptions": {
    "paths": {
      "@/*": ["./src/*"]
    }
  }
}

يضيف Next.js خيارات المترجم المتبقية التي يحتاج إليها هذا الملف عند تشغيل next dev أو next build لأول مرة.

إعداد المصدر

src/lib/source.ts

يحمّل محتوى التوثيق:

TypeScript
import { loader } from "fumadocs-core/source";
import { docs } from "../../.source/server";

export const source = loader({
  baseUrl: "/docs",
  source: docs.toFumadocsSource(),
});

ملفات التطبيق

src/app/layout.tsx

التخطيط الجذري:

TSX
import type { Metadata } from "next";
import { RootProvider } from "fumadocs-ui/provider/next";
import { FontHead } from "onedocs";
import "./globals.css";

export const metadata: Metadata = {
  title: "My Docs",
  description: "Documentation for my project",
};

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en" suppressHydrationWarning>
      <head>
        <FontHead />
      </head>
      <body className="antialiased">
        <RootProvider>{children}</RootProvider>
      </body>
    </html>
  );
}

يوفّر RootProvider من Fumadocs UI مربع البحث والسمتين الفاتحة والداكنة. تهيّئ FontHead خط Inter Variable مسبقًا من /fonts/InterVariable.woff2 وتعيّنه خطًا للصفحة. لا يتضمن Onedocs ملف الخط: نزّل InterVariable.woff2 من إصدارات Inter وضعه في public/fonts/. من دونه، سيستخدم النص خط sans-serif الافتراضي للنظام.

لإنشاء بيانات التعريف هذه من إعدادك بدلًا من ذلك، راجع createMetadata في مرجع API.

src/app/globals.css

استورد الإعداد المسبق CSS:

CSS
@import "onedocs/css/preset.css";

@source "./**/*.tsx";
@source "../../content/**/*.mdx";

يحمّل الإعداد المسبق Tailwind CSS وأنماط UI الخاصة بـFumadocs وأنماط تخطيط Onedocs. تكون المسارات @source نسبية إلى globals.css، لذا يشير هذان السطران إلى src/app/ وإلى مجلد content/ في جذر المشروع.

src/app/page.tsx

الصفحة الرئيسية. يعرض HomePage العنوان الرئيسي والميزات والتذييل من إعدادك:

TSX
import { HomePage } from "onedocs";
import config from "../../onedocs.config";

export default function Home() {
  return <HomePage config={config} packageName="my-package" />;
}

يضيف packageName أوامر تثبيت npm وyarn وpnpm وbun إلى العنوان الرئيسي. احذفه إذا لم يكن مشروعك حزمة.

src/app/docs/layout.tsx

تخطيط التوثيق مع الشريط الجانبي:

TSX
import { DocsLayout } from "onedocs";
import type { ReactNode } from "react";
import { source } from "@/lib/source";
import config from "../../../onedocs.config";

export default function Layout({ children }: { children: ReactNode }) {
  return (
    <DocsLayout config={config} pageTree={source.pageTree}>
      {children}
    </DocsLayout>
  );
}

src/app/docs/[[...slug]]/page.tsx

صفحات التوثيق الفردية:

TSX
import { source } from "@/lib/source";
import { DocsPage, mdxComponents } from "onedocs";
import { notFound } from "next/navigation";

export default async function Page(props: {
  params: Promise<{ slug?: string[] }>;
}) {
  const params = await props.params;
  const page = source.getPage(params.slug);
  if (!page) notFound();

  const MDX = page.data.body;

  return (
    <DocsPage toc={page.data.toc}>
      <MDX components={mdxComponents} />
    </DocsPage>
  );
}

export async function generateStaticParams() {
  return source.generateParams();
}

export async function generateMetadata(props: {
  params: Promise<{ slug?: string[] }>;
}) {
  const params = await props.params;
  const page = source.getPage(params.slug);
  if (!page) notFound();

  return {
    title: page.data.title,
    description: page.data.description,
  };
}

المحتوى

content/docs/index.mdx

تحتاج كل صفحة إلى title في بيانات الواجهة الأمامية الوصفية. أما description فاختياري:

Mdx
---
title: Introduction
description: What this project does.
---

Welcome to the docs. Components such as `<Callout>` work without imports; see [Components](/docs/components).

content/docs/meta.json

يحدّد ترتيب الشريط الجانبي:

JSON
{
  "pages": ["index"]
}

أضف صفحة بإنشاء ملف .mdx آخر وإدراج اسمه في pages.

التشغيل

ابدأ خادم التطوير:

سطر الأوامر
npm run dev

الصفحة الرئيسية على http://localhost:3000 وصفحات التوثيق على http://localhost:3000/docs.

أنشئ نسخة الإنتاج:

سطر الأوامر
npm run build

بعد ذلك، أضف البحث وخريطة الموقع وllms.txt في SEO والبحث.