Nakafa Content Creation
Guidelines for creating educational content and exercises for the Nakafa platform.
Language
For This Skill (Documentation)
Use normal English - clear and straightforward.
For Actual Content (MDX Files)
-
Indonesian (id.mdx): Use proper Indonesian grammar with natural, engaging tone
- Use "kita" (we) and "kalian" (you all) to engage readers
- Write like you're explaining to a friend, but keep it educational
- Example: "Mari kita mulai dengan...", "Pernahkah kalian memperhatikan..."
-
English (en.mdx): Use proper English grammar with natural, engaging tone
- Write clearly and conversationally
- Keep it educational but not stiff
Content Types
1. Subject Content (packages/contents/subject/)
Educational materials organized by level:
subject/
├── high-school/
│ ├── 10/mathematics/{topic}/
│ ├── 11/mathematics/{topic}/
│ └── 12/mathematics/{topic}/
└── university/
└── bachelor/
└── ai-ds/
Each topic contains:
id.mdx: Indonesian version (Source of Truth) - natural, engaging tone
en.mdx: English translation - natural, engaging tone
graph.tsx: Shared graph component (if needed)
2. Exercises (packages/contents/exercises/)
exercises/
├── high-school/
│ ├── tka/mathematics/{material}/{set}/{number}/
│ └── snbt/{subject}/{material}/{set}/{number}/
└── middle-school/
Exercise structure per number:
{number}/
├── _question/
│ ├── id.mdx
│ └── en.mdx
├── _answer/
│ ├── id.mdx
│ └── en.mdx
└── choices.ts
MDX Components
Auto-Imported (No Import Required)
Available in all MDX files without importing:
mdx
1<BlockMath math="x^2 + y^2 = r^2" />
2
3<InlineMath math="5" />
4
5<MathContainer>
6 <BlockMath math="a = b" />
7 <BlockMath math="c = d" />
8</MathContainer>
9
10<CodeBlock
11 data={[
12 { language: "typescript", filename: "example.ts", code: "const x = 1;" },
13 ]}
14/>
15
16<Mermaid chart="graph TD; A-->B;" />
Content Components (Import Required)
From @repo/design-system/components/contents/*:
typescript
1import { LineEquation } from "@repo/design-system/components/contents/line-equation";
2import { NumberLine } from "@repo/design-system/components/contents/number-line";
3import { Triangle } from "@repo/design-system/components/contents/triangle";
4import { UnitCircle } from "@repo/design-system/components/contents/unit-circle";
5import { Vector3d } from "@repo/design-system/components/contents/vector-3d";
6import { VectorChart } from "@repo/design-system/components/contents/vector-chart";
7import { Inequality } from "@repo/design-system/components/contents/inequality";
8import { FunctionChart } from "@repo/design-system/components/contents/function-chart";
9import { ScatterDiagram } from "@repo/design-system/components/contents/scatter-diagram";
10import { BarChart } from "@repo/design-system/components/contents/bar-chart";
11import { AnimationBacterial } from "@repo/design-system/components/contents/animation-bacterial";
Color System
Always use getColor() for deterministic colors:
typescript
1import { getColor } from "@repo/design-system/lib/color";
2
3// Available colors: RED, ORANGE, AMBER, YELLOW, LIME, GREEN, EMERALD,
4// TEAL, CYAN, SKY, BLUE, INDIGO, VIOLET, PURPLE, FUCHSIA, PINK, ROSE
5
6<LineEquation
7 data={[{
8 points: Array.from({ length: 100 }, (_, i) => {
9 const x = -5 + (i / 99) * 10;
10 return { x, y: x * x, z: 0 };
11 }),
12 color: getColor("INDIGO"),
13 smooth: true,
14 showPoints: false,
15 }]}
16/>
Never use default RED, GREEN, or BLUE for lines.
Components
- Inline math:
<InlineMath math="x + y" />
- Block math:
<BlockMath math="x^2 + y^2 = r^2" />
- Multiple blocks: Wrap with
<MathContainer>
Numbers
- Use
<InlineMath math="5" /> for numbers in text (not plain 5)
- Use
<InlineMath math="(1)" /> for numbered references
- Units:
<InlineMath math="5 \text{ cm}" />
Variables in Text
Italicize variables: x, y, f(x)
Decimals (Indonesian)
Use comma: 3,14 (not 3.14)
Backslash Escaping
MDX files (InlineMath/BlockMath): Use single backslash
mdx
1<InlineMath math="\frac{a}{b}" />
2<BlockMath math="\sqrt{x}" />
choices.ts (TypeScript strings): Use escaped double backslash
typescript
1{ label: "$$\\frac{a}{b}$$", value: true }
Writing Guidelines
Headings
- Start at h2 (
##)
- Maximum depth: h4 (
####)
- Descriptive titles (NOT "Step 1")
- NO symbols or math in headings
- NO parentheses in headings (use "Analysis 1" not "Analysis (1)")
Correct:
md
1## Finding the Value of x
2
3#### Analysis 1
Incorrect:
md
1## Step 1: Finding <InlineMath math="x" />
2
3#### Analysis (1)
Lists
Use hyphens -:
md
1- First item
2- Second item
3- Third item
No nested lists. No blank lines between items.
Be Creative and Concise
- Be Creative: Use various Markdown formatting and LaTeX math syntax creatively to present content engagingly
- NO Bloated Explanations: Get straight to the point. Avoid unnecessary introductory text
- NO Excessive Lists: Lists are okay but don't overuse them. NEVER use nested lists
- Images are Reference Only: If you find errors in questions or calculations from source images, fix them directly. The source is just a reference for the calculation method, not absolute truth
- Provide Context: Explain the reasoning and context so students understand WHY, not just WHAT
Paragraphs and Math
Always add blank line between text and math:
mdx
1Some text here.
2
3<BlockMath math="x = 5" />
4
5More text here.
Exercise Creation
Question File (_question/id.mdx)
mdx
1export const metadata = {
2 title: "Soal 1",
3 authors: [{ name: "Author Name" }],
4 date: "06/11/2025", // MM/DD/YYYY format
5};
6
7Diketahui <InlineMath math="a = 5" /> dan <InlineMath math="b = 3" />.
8
9Hitunglah nilai dari <InlineMath math="a + b" />.
Answer File (_answer/id.mdx)
mdx
1export const metadata = {
2 title: "Pembahasan Soal 1",
3 authors: [{ name: "Author Name" }],
4 date: "06/11/2025",
5};
6
7#### Analisis Soal
8
9Diketahui <InlineMath math="a = 5" /> dan <InlineMath math="b = 3" />.
10
11<MathContainer>
12 <BlockMath math="a + b = 5 + 3" />
13 <BlockMath math="a + b = 8" />
14</MathContainer>
15
16Jadi, nilai <InlineMath math="a + b" /> adalah <InlineMath math="8" />.
Choices File (choices.ts)
typescript
1import type { ExercisesChoices } from "@repo/contents/_types/exercises/choices";
2
3const choices: ExercisesChoices = {
4 id: [
5 { label: "$$7$$", value: false },
6 { label: "$$8$$", value: true }, // correct answer
7 { label: "$$9$$", value: false },
8 { label: "$$10$$", value: false },
9 { label: "Tidak ada jawaban", value: false }, // plain text
10 ],
11 en: [
12 { label: "$$7$$", value: false },
13 { label: "$$8$$", value: true },
14 { label: "$$9$$", value: false },
15 { label: "$$10$$", value: false },
16 { label: "No answer", value: false },
17 ],
18};
19
20export default choices;
Math in choices: Use $$...$$ for math expressions and numbers, plain text for normal labels.
Important: In TypeScript strings, backslashes must be escaped with an additional backslash. For example:
typescript
1// CORRECT - escape the backslash
2{ label: "$$\\frac{a}{b}$$", value: true }
3{ label: "$$\\sqrt{x}$$", value: false }
4{ label: "$$\\infty$$", value: false }
5
6// WRONG - unescaped backslash causes error
7{ label: "$$\frac{a}{b}$$", value: true }
Key Rules for Exercises
- Date Format: Must be
MM/DD/YYYY (e.g., "06/11/2025")
- Clarity: Explanations must be clear and unambiguous
- NO Option Letters: Never refer to (A), (B), (C) in explanations
- Consistent Math: Use same notation in question and answer
- Numbered References: Use
<InlineMath math="(1)" /> not (1)
3D Visualization Patterns
Generating Points
Never hard-code points. Use Array.from() with math calculations:
typescript
1// For a parabola y = x^2 from x=-5 to x=5
2points: Array.from({ length: 100 }, (_, i) => {
3 const x = -5 + (i / 99) * 10; // Range from -5 to 5
4 const y = x * x;
5 return { x, y, z: 0 };
6})
7
8// For a circle
9points: Array.from({ length: 100 }, (_, i) => {
10 const angle = (i / 99) * 2 * Math.PI;
11 const x = Math.cos(angle);
12 const y = Math.sin(angle);
13 return { x, y, z: 0 };
14})
2D Graph Settings
For 2D visualizations:
tsx
1<LineEquation
2 title={<>Graph of f(x)</>}
3 description="Visualization of the function"
4 showZAxis={false}
5 cameraPosition={[0, 0, 15]} // Perpendicular to plane
6 data={[{
7 points: [...],
8 color: getColor("TEAL"),
9 smooth: true,
10 showPoints: false,
11 }]}
12/>
Labels
Ensure labels don't overlap:
tsx
1labels: [
2 { text: "y = x²", at: 50, offset: [1, 0.5, 0] }
3]
Code vs Math
- Programming code: Use inline code (
`const x = 5`)
- Math values: Use
<InlineMath math="5" />
- Math functions: Use
<InlineMath math="f(x)" />
- Programming functions: Use inline code (
`function()`)
Quality Checklist
Before submitting content: