OpenTelemetry Learning
Bắt đầu

Quy ước repository

Cách tổ chức, viết, liên kết và kiểm tra tài liệu trong repository OpenTelemetry Learning.

Phạm vi của trang này

Đây là quy ước của repository hiện tại, không phải một template chung cho mọi dự án OpenTelemetry. Repository này là website docs-only dùng Next.js, Fumadocs và static export. Hãy ưu tiên cây thư mục, script và cấu hình đang có thay vì tự tạo thư mục examples/, configs/ hoặc một app demo chưa tồn tại.

Mục lục

Tổng quan repository

otel-learn là website tài liệu tiếng Việt về OpenTelemetry. Đây là repository docs-only: source chính là các trang MDX trong content/docs/, còn src/ chứa ứng dụng Next.js và lớp tích hợp Fumadocs để đọc các trang đó.

Next.js được cấu hình với output: 'export'. Nghĩa là quá trình build tạo các tệp HTML tĩnh thay vì yêu cầu Next.js server runtime khi deploy. dist/ là thư mục output được đặt tên riêng trong next.config.mjs. Route docs ở root nên website mở trực tiếp vào docs, không có landing page riêng.

Một trang MDX đi qua pipeline sau:

content/docs/*.mdx


  fumadocs-mdx  ──►  .source/ (generated source)


  src/lib/source.ts + Next.js


  /<category>/<slug>/  ──►  dist/ (static export sau build)

source.config.ts khai báo collection ở content/docs, dùng pageSchema cho frontmatter và metaSchema cho navigation metadata. Cấu hình này cũng bật remarkMdxMermaid, tức plugin chuyển fenced block mermaid thành component Mermaid trong pipeline MDX.

Cây thư mục thực tế

Các thư mục và file source chính hiện có:

README.md
package.json
source.config.ts
meta.json
index.mdx
meta.json
environment.mdx
first-trace.mdx
learning-path.mdx
local-stack.mdx
next-steps.mdx
repository-conventions.mdx
next.config.mjs
.gitignore

Trong cây trên, các category được liệt kê theo content/docs/meta.json. Mỗi category hiện có một meta.json riêng. Các trang chi tiết khác nằm trong cùng các folder đó; không nên suy ra một thư mục con chỉ vì một chủ đề có thể cần nó trong tương lai.

Nội dung docs và navigation

Trang MDX

Mỗi file .mdx dưới content/docs/ là một trang tài liệu. index.mdx đại diện cho trang đầu của category. Ví dụ:

  • content/docs/getting-started/index.mdx tạo route /getting-started/.
  • content/docs/getting-started/environment.mdx tạo route /getting-started/environment/.
  • content/docs/fundamentals/index.mdx tạo route /fundamentals/.

src/lib/source.ts gọi docs.toFumadocsSource() rồi đưa collection cho Fumadocs loader. src/app/[[...slug]]/page.tsx lấy page theo slug, render frontmatter và body MDX. Vì vậy, nội dung trang nên nằm trong content/docs/; không copy nội dung docs vào component React.

Tệp meta.json

content/docs/meta.json quyết định thứ tự các category trong navigation. Ví dụ, slug getting-started trỏ tới folder content/docs/getting-started/. content/docs/getting-started/meta.json quyết định thứ tự các trang trong nhóm Bắt đầu:

{
  "title": "Bắt đầu",
  "pages": [
    "index",
    "learning-path",
    "environment",
    "first-trace",
    "local-stack",
    "repository-conventions",
    "next-steps"
  ]
}

Giá trị trong pages là slug hoặc tên file bỏ phần mở rộng .mdx. Không thêm .mdx vào giá trị này. Khi đổi thứ tự, hãy nhớ rằng thứ tự đó cũng là thứ tự người học nhìn thấy trong sidebar.

Khi thêm trang vào một category, cập nhật meta.json của category đó. Nếu trang không cần xuất hiện trong sidebar, trước tiên phải xác nhận đó là chủ ý; đừng tạo một file meta.json mới ở nơi không có category tương ứng.

Quy ước đặt tên và routing

  • Dùng chữ thường cho tên folder và file.
  • Dùng kebab-case cho slug nhiều từ, ví dụ first-trace.mdxrepository-conventions.mdx.
  • Giữ tên index.mdx cho trang đầu category.
  • Giữ đúng tên meta.json, source.config.ts và các file cấu hình đã có.
  • Không đổi tên file chỉ để dịch slug. Slug ổn định giúp link và bookmark của người đọc không bị hỏng.

next.config.mjs bật trailingSlash: true, nên route public luôn có dấu / ở cuối. Mapping quan trọng là:

content/docs/<category>/<page>.mdx

               └── /<category>/<page>/

content/docs/<category>/index.mdx

               └── /<category>/

Route của một trang không phải là đường dẫn tuyệt đối trên filesystem. Trong nội dung, dùng route public như /getting-started/environment/; khi sửa source, dùng path file như content/docs/getting-started/environment.mdx.

Frontmatter, mục lục và liên kết

Frontmatter

Mỗi trang phải có YAML frontmatter ở đầu file. pageSchema trong source.config.ts dùng frontmatter đó để tạo metadata của Fumadocs.

---
title: "Tên trang"
description: "Một câu mô tả ngắn cho kết quả tìm kiếm và phần đầu trang."
---

title được render thành H1 bởi layout docs. Vì vậy, không thêm # Tên trang ở body. Sau frontmatter, có thể đặt một <Callout> giới thiệu phạm vi hoặc đối tượng đọc trước phần ## Mục lục.

description nên nói rõ người đọc sẽ làm được gì hoặc hiểu điều gì sau khi đọc. Đừng đặt một đoạn dài hoặc nhiều ý không liên quan vào trường này.

Mục lục thủ công

Mỗi trang cần một mục ## Mục lục viết tay. Đặt nó sau frontmatter và phần callout mở đầu, trước section nội dung đầu tiên. Mục lục phải liệt kê mọi heading ##### thật sự có trong trang, với ### thụt vào dưới ##:

## Mục lục

- [Tổng quan](#tổng-quan)
- [Cài đặt](#cài-đặt)
  - [Kiểm tra](#kiểm-tra)

Fumadocs tạo anchor bằng cách viết thường, thay khoảng trắng bằng dấu gạch ngang và bỏ dấu câu; chữ tiếng Việt có dấu được giữ lại. Sau khi đổi heading, phải đổi anchor tương ứng trong mục lục. Không dùng H1 trong body và không đưa các heading không tồn tại vào mục lục.

Liên kết nội bộ

Liên kết đến trang docs bằng route public tuyệt đối và luôn có trailing slash:

Đọc thêm [Nền tảng](/fundamentals/) trước khi instrument ứng dụng.

<Cards>
  <Card
    title="Chuẩn bị môi trường"
    href="/getting-started/environment/"
    description="Kiểm tra toolchain trước khi thực hành."
  />
</Cards>

Kiểm tra route bằng cách đối chiếu file trong content/docs/. Ví dụ, /fundamentals/telemetry-pipeline/ chỉ hợp lệ khi content/docs/fundamentals/telemetry-pipeline.mdx tồn tại. Không link tới placeholder, file hoặc folder chưa có trong repository. Link ngoài dùng URL đầy đủ và chỉ nên thêm khi nguồn đó thực sự cần thiết.

Components và code blocks

Components Fumadocs

Dùng component khi nó làm rõ cấu trúc, không dùng component chỉ để trang trí. Các component mặc định như Callout, CardsCard đã được cung cấp qua src/components/mdx.tsx, nên các trang hiện tại không import chúng.

Với component không mặc định, dùng đúng import ở đầu file. Ví dụ trang có cây thư mục dùng:

import { File, Folder, Files } from 'fumadocs-ui/components/files';

Các quy ước đang dùng:

  • <Callout type="info|warn|error|idea" title="..."> cho ghi chú, cảnh báo, lỗi hoặc mẹo. Nêu hành động cụ thể sau cảnh báo.
  • <Steps><Step> cho quy trình theo thứ tự. Mỗi <Step> thường chứa một heading ### và một hành động có thể làm được.
  • <Cards><Card> để nối sang các bài liên quan ở cuối trang. href phải là route có trailing slash.
  • <Files>, <Folder><File> cho cây thư mục đã kiểm chứng.
  • Fenced block mermaid được remarkMdxMermaid xử lý và component Mermaid trong src/components/mdx.tsx render ở phía client. Giữ diagram ở dạng text để dễ review và version control.

Code blocks

Chọn language tag phù hợp để Shiki tô màu và để người đọc biết shell hoặc ngôn ngữ đang dùng:

  • bash cho lệnh terminal trên Linux/macOS.
  • powershell khi cú pháp Windows khác đáng kể.
  • ts, tsx, js, json cho source hoặc dữ liệu cấu hình thực sự có trong repository.
  • yaml cho cấu hình khi bài học đã cung cấp file YAML tương ứng.
  • text cho output, cây thư mục hoặc giá trị không có ngôn ngữ.

Ví dụ lệnh phải copy được và không chứa prompt $. Chú thích nguyên nhân hoặc kết quả ở ngoài code block. Một block nên phục vụ một mục đích; tách lệnh cài, lệnh chạy và lệnh kiểm tra thay vì gom một đoạn shell dài khó đọc.

Không trình bày một file cấu hình tưởng tượng như thể nó đã tồn tại. Nếu chỉ minh họa cú pháp, nói rõ đó là ví dụ tối giản và chỉ dùng tên binding, port hoặc path đã được giải thích trong bài.

Quy trình thêm hoặc sửa trang

Sửa một trang có sẵn

Đọc context trước khi sửa

Mở meta.json của category, trang liền kề và các route mà trang đang link tới. Giữ title, độ sâu heading, thuật ngữ tiếng Việt và mức chi tiết nhất quán với nhóm. Nếu trang là placeholder, thay nội dung placeholder thay vì tạo một file trùng chủ đề.

Sửa nội dung MDX

Giữ frontmatter ở đầu file, không thêm H1 body, cập nhật mục lục thủ công sau khi chốt heading. Khi dùng component, kiểm tra import và prop theo component đang được đăng ký trong src/components/mdx.tsx.

Đối chiếu từng link nội bộ với file MDX hoặc index.mdx tương ứng. Chạy ví dụ ở mức có thể kiểm chứng. Nếu ví dụ phụ thuộc một Collector, backend, runtime hoặc file Compose chưa có trong repository, nói rõ dependency đó thay vì viết như thể nó đã được commit.

Thêm một trang mới

  1. Chọn category đã tồn tại trong content/docs/. Dùng tên file chữ thường, kebab-case, có phần mở rộng .mdx.
  2. Tạo frontmatter titledescription. Viết phần nội dung không có H1, rồi thêm ## Mục lục với anchor của mọi #####.
  3. Thêm slug bỏ .mdx vào đúng mảng pages trong meta.json của category. Đặt slug ở vị trí phản ánh thứ tự học.
  4. Dùng route public có trailing slash khi link tới trang mới. Ví dụ, new-page.mdx trong getting-started có route /getting-started/new-page/.
  5. Không tạo thư mục examples/, configs/ hay runtime project chỉ để chứa một đoạn minh họa nếu repository chưa có quyết định tổ chức cho chúng.

Chạy các kiểm tra

Các script này có trong package.json hiện tại:

npm run lint
npm run types:check
npm run build
npm run preview

Ý nghĩa của từng lệnh:

LệnhMục đích
npm run lintChạy ESLint cho source code.
npm run types:checkChạy fumadocs-mdx, Next typegen và TypeScript không phát sinh output.
npm run buildBuild Next.js static export vào dist/.
npm run startPhục vụ dist/ bằng serve; cần build trước, giống npm run preview.
npm run previewPhục vụ dist/ bằng serve; cần build trước.

Trong quá trình phát triển, npm run dev giúp xem nội dung nhanh. Trước khi mở pull request, chạy các kiểm tra phù hợp và ghi nhận lỗi nếu một kiểm tra không thể chạy trong môi trường hiện tại. Không sửa generated file để làm cho kiểm tra tạm thời qua.

Tệp được sinh tự động

Các path sau không phải nơi viết source tài liệu:

PathNguồn sinhQuy tắc
.source/fumadocs-mdx, được gọi bởi postinstalltypes:checkKhông sửa hoặc commit thủ công.
dist/next build, theo distDir trong next.config.mjsChỉ là static build output; không sửa để thay đổi docs.
.next/Next.js trong development/buildCache và output nội bộ; không sửa.

.gitignore của repository đã bỏ qua .source, dist/.next/. Nếu source collection lỗi, sửa MDX, meta.json, source.config.ts hoặc component nguồn tương ứng rồi chạy lại lệnh sinh. Những file sinh tự động có thể thay đổi sau mỗi lần cài hoặc build nên không dùng chúng làm nơi review nội dung.

Checklist review

Trước khi gửi thay đổi tài liệu, tự kiểm tra:

  • File nằm đúng category dưới content/docs/ và tên file là kebab-case.
  • Frontmatter có titledescription rõ ràng.
  • Không có H1 viết bằng # trong body.
  • ## Mục lục ngay sau phần mở đầu và mục lục chứa đủ mọi ##/###.
  • Anchor trong mục lục khớp heading sau khi bỏ dấu câu.
  • Jargon được giải thích ở lần xuất hiện đầu tiên.
  • Link nội bộ trỏ tới route hoặc file thật, có trailing slash với route docs.
  • Nếu thêm trang, slug đã được thêm đúng meta.json và đúng thứ tự sidebar.
  • Component có syntax/import đúng; fenced code block có language tag phù hợp.
  • Không bịa file Compose, thư mục ví dụ, binding hoặc runtime chưa tồn tại.
  • Không sửa .source/, dist/ hoặc .next/.
  • Đã chạy npm run lintnpm run types:check; nếu cần static export, chạy thêm npm run build rồi npm run preview.

On this page