# Prompt Engineering Guide — Administrator & Developer Guide

This guide covers the architecture, deployment, internals, and extension of the Prompt Engineering Guide (PEG) — a Nextra-based documentation site maintained by DAIR.AI. It is written for developers who need to modify, deploy, or understand the codebase. See the User Guide for content navigation and usage.

## 1. Architecture Overview

### What the System Does

The Prompt Engineering Guide is a statically generated, multilingual documentation website built on the Nextra framework (which itself is built on Next.js). The site serves structured educational content about prompt engineering through MDX pages, with interactive React components for code copying, AI assistant integration, and course promotion. The entire content layer is file-based — MDX files in the `pages/` directory define both the site structure and the rendered content.

### Architecture Diagram

```text
Browser Request
      │
      ▼
┌─────────────┐
│  Next.js     │
│  Server      │
│  (SSG/SSR)   │
├─────────────┤
│  Nextra      │  MDX → React pages
│  v2.13.2     │  i18n routing
│  Theme: docs │  Search indexing
├─────────────┤
│  Custom      │  AnnouncementBar, CopyPageDropdown,
│  Components  │  CourseCard, CodeBlock, Pre,
│              │  TabsComponent, PromptFiles,
│              │  ContentFileNames, Screenshot
├─────────────┤
│  API Routes  │  /api/contentFiles
│  (3 routes)  │  /api/getPageContent
│              │  /api/promptsFiles
├─────────────┤
│  pages/      │  MDX content (14 locales)
│  (1500+      │  _meta.*.json (navigation)
│   files)     │  img/ (static assets)
└─────────────┘
```

> [!NOTE]
> The project is titled `nextra-docs-template` in `package.json` — it was bootstrapped from Nextra's documentation template and customized with DAIR.AI-specific components and content. This has no functional impact but appears in build logs and lock files.

### Component Inventory

| Component | Path | Role |
|-----------|------|------|
| Next.js App | `pages/_app.tsx` | Root app with analytics, announcement bar, global CSS |
| Middleware | `middleware.js` | Nextra locale detection and routing |
| Next Config | `next.config.js` | Nextra plugin config, i18n locales, SVG webpack rules |
| Theme Config | `theme.config.tsx` | Site branding, navigation, i18n labels, CopyPageDropdown injection |
| AnnouncementBar | `components/AnnouncementBar.tsx` | Top-of-page promotional banner |
| CodeBlock | `components/CodeBlock.tsx` | Code display with copy button (FontAwesome icons) |
| ContentFileNames | `components/ContentFileNames.tsx` | Dynamic card grid for section content listing |
| CopyPageDropdown | `components/CopyPageDropdown.tsx` | Copy-as-markdown, Open in Claude/ChatGPT dropdown |
| CourseCard | `components/CourseCard.tsx` | Course promotion cards with dark mode support |
| PromptFiles | `components/PromptFiles.jsx` | Dynamic listing of Prompt Hub categories and entries |
| TabsComponent | `components/TabsComponent.tsx` | Multi-model API code example tabs |
| Pre | `components/pre.tsx` | Custom code block wrapper with word-wrap toggle and copy |
| Screenshot | `components/screenshot/index.jsx` | Image display with border and styling |
| Icons | `components/icons/index.ts` | SVG icon exports (28 icons) |
| Button | `components/button.tsx` | Reusable styled button |
| CopyToClipboard | `components/copy-to-clipboard.tsx` | Clipboard copy with visual feedback |
| Copy/Check Icons | `components/copy.tsx`, `components/check.tsx` | SVG icons for copy/check states |
| WordWrap Icon | `components/word-wrap.tsx` | SVG icon for word-wrap toggle |
| Counters | `components/counters.tsx` | Example React counter component |

### Technology Stack

| Layer | Technology | Version |
|-------|-----------|---------|
| Framework | Next.js | ^13.5.6 |
| Documentation | Nextra | ^2.13.2 |
| Theme | nextra-theme-docs | ^2.13.2 |
| UI | React | ^18.2.0 |
| Language | TypeScript | ^4.9.5 |
| Icons (code blocks) | FontAwesome | ^6.5.1 |
| Icons (SVG components) | @svgr/webpack | ^8.1.0 |
| Git info | @napi-rs/simple-git | ^0.1.19 |
| Analytics | @vercel/analytics | ^0.1.11 |
| Math rendering | KaTeX | ^0.16.27 |
| Utility | clsx | ^2.1.0 |

## 2. System Requirements

### Build Requirements

| Requirement | Minimum |
|-------------|---------|
| Node.js | 16+ (Next.js 13 requirement) |
| Package Manager | npm or pnpm |
| Disk Space | ~500 MB (including `node_modules`) |
| Memory | 4 GB RAM recommended for build |

### Development

```bash
# Clone the repository
git clone https://github.com/dair-ai/Prompt-Engineering-Guide.git
cd Prompt-Engineering-Guide

# Install dependencies
npm install
# or
pnpm install

# Start development server
npm run dev
```

```text
ready - started server on 0.0.0.0:3000
```

> [!IMPORTANT]
> The project uses `pnpm-lock.yaml` alongside `package-lock.json`. If both are present, ensure you use the same package manager consistently to avoid dependency resolution conflicts.

### Build and Production

```bash
# Build for production
npm run build

# Start production server
npm start
```

## 3. Configuration Reference

### `next.config.js`

The core configuration file applies the Nextra plugin and configures Next.js.

```javascript
const withNextra = require('nextra')({
  theme: 'nextra-theme-docs',
  themeConfig: './theme.config.tsx',
  latex: true
})

module.exports = withNextra({
  i18n: {
    locales: ['en', 'zh', 'jp', 'pt', 'tr', 'es', 'it', 'fr', 'kr', 'ca', 'fi', 'ru', 'de', 'ar'],
    defaultLocale: 'en',
  },
  webpack(config) {
    // SVG handling for components/icons/
    const allowedSvgRegex = /components\/icons\/.+\.svg$/
    const fileLoaderRule = config.module.rules.find(rule => rule.test?.test?.('.svg'))
    fileLoaderRule.exclude = allowedSvgRegex
    config.module.rules.push({
      test: allowedSvgRegex,
      use: ['@svgr/webpack']
    })
    return config
  }
})
```

| Setting | Value | Purpose |
|---------|-------|---------|
| `theme` | `nextra-theme-docs` | Nextra documentation theme |
| `themeConfig` | `./theme.config.tsx` | Theme customization file |
| `latex` | `true` | Enables KaTeX rendering in MDX |
| `i18n.locales` | 14 locale codes | Supported languages |
| `i18n.defaultLocale` | `en` | Default language |
| SVG webpack rule | `@svgr/webpack` | Allows importing SVGs in `components/icons/` as React components |

### `theme.config.tsx`

Controls site branding, navigation, and layout customization.

| Setting | Value | Purpose |
|---------|-------|---------|
| `logo` | SVG + "Prompt Engineering Guide" text | Site logo with three-dot icon |
| `i18n` | Array of 14 locale objects | Language selector labels |
| `head` | Custom `<head>` with OG tags, favicon | SEO and favicon configuration |
| `project.link` | GitHub repo URL | GitHub link in header |
| `chat.link` | Discord invite URL | Discord link in header |
| `docsRepositoryBase` | GitHub tree URL | "Edit this page" link base |
| `footer.text` | "Copyright 2026 DAIR.AI" | Footer content |
| `search.placeholder` | "Search..." | Search bar placeholder |
| `gitTimestamp` | Custom component with SerpAPI sponsor | Last-updated display with sponsor logo |
| `components.pre` | Custom `Pre` component | Replaces default code blocks with copy/word-wrap |
| `main` | Custom wrapper | Injects `CopyPageDropdown` on English non-index pages |
| `navbar.extraContent` | "Services" button | Purple CTA button in navbar |

> [!IMPORTANT]
> The `main` wrapper conditionally renders `CopyPageDropdown` only when `router.locale === 'en'` and `router.pathname !== '/'`. Modifying locale routing logic may break this feature.

### Google Analytics

Analytics are configured directly in `pages/_app.tsx`:

```typescript
<Script async src="https://www.googletagmanager.com/gtag/js?id=G-ST7R3WQ353"/>
```

Tracking ID: `G-ST7R3WQ353`

Vercel Analytics is also enabled via `@vercel/analytics/react`.

## 4. Deployment & Scaling

### Build Pipeline

The standard Next.js build process applies:

```bash
npm run build    # Generates .next/ directory
npm start        # Starts production server
```

The site is designed for deployment on Vercel (evidenced by `@vercel/analytics` integration and Nextra's Vercel-optimized defaults), but can be deployed to any platform that supports Next.js.

### Static Export Considerations

Nextra with `i18n` enabled requires server-side rendering for locale detection (via `middleware.js`). A fully static export (`next export`) is not supported with the current configuration due to:

1. The `i18n` configuration in `next.config.js`
2. The API routes in `pages/api/`
3. The middleware-based locale routing

> [!WARNING]
> Do not attempt `next export` with this configuration. The middleware and API routes require a Node.js runtime.

### Deployment Checklist

- [ ] All dependencies installed (`npm install`)
- [ ] Build completes without errors (`npm run build`)
- [ ] Verify search works on production URL
- [ ] Verify locale switching works
- [ ] Verify CopyPageDropdown works on English pages
- [ ] Verify LaTeX/KaTeX rendering on research pages
- [ ] Confirm Google Analytics is receiving events

## 5. Operations

### Content Updates

Content is managed entirely through MDX files. The update workflow:

1. Edit or add `.mdx` files in the appropriate `pages/` subdirectory
2. Add corresponding `_meta.*.json` entries for navigation
3. Test locally with `npm run dev`
4. Commit and push — deployment handles the rest

### Adding a New Content Page

1. Create the MDX file with the locale suffix:
   ```text
   pages/techniques/new-technique.en.mdx
   ```

2. Add the page to the English navigation metadata:
   ```json
   // pages/techniques/_meta.en.json
   {
     "new-technique": "New Technique Name"
   }
   ```

3. For translations, create locale-specific files and metadata:
   ```text
   pages/techniques/new-technique.zh.mdx
   pages/techniques/new-technique.de.mdx
   ```

> [!TIP]
> You only need to add metadata entries for languages where a translation exists. Nextra gracefully handles missing translations by not showing those pages in the sidebar for that locale.

### Adding a New Language

1. Add the locale code to `next.config.js`:
   ```javascript
   i18n: {
     locales: ['en', 'zh', /* ... */, 'new-locale'],
     defaultLocale: 'en',
   }
   ```

2. Add the locale label to `theme.config.tsx`:
   ```typescript
   i18n: [
     // ... existing locales
     { locale: 'new-locale', text: 'Language Name' },
   ]
   ```

3. Create `_meta.new-locale.json` files in each section directory
4. Create `.new-locale.mdx` content files

### Monitoring

- **Google Analytics** (G-ST7R3WQ353) — page views, user geography, session data
- **Vercel Analytics** — web vitals, performance metrics (if deployed on Vercel)
- **Git timestamps** — each page shows its last update date via `@napi-rs/simple-git`

> [!NOTE]
> The `@napi-rs/simple-git` dependency enables the "Last updated on" timestamp feature. It reads git history for each file. If the git history is shallow (e.g., `--depth 1` clone), timestamps may be inaccurate or missing.

## 6. Performance

### Build Performance

With 1,556 files across 14 locales, build times can be significant. Key factors:

| Factor | Impact |
|--------|--------|
| Number of locales | Linear — each locale multiplies page count |
| MDX compilation | KaTeX-enabled pages are slower to compile |
| SVG processing | @svgr/webpack adds overhead for icon imports |
| Package lock size | `package-lock.json` is large due to Nextra's dependency tree |

### Runtime Performance

- **Static generation** — most pages are statically generated at build time
- **API routes** — `contentFiles`, `promptsFiles`, and `getPageContent` run on the server and read the filesystem at request time
- **Client-side** — CopyPageDropdown fetches page content from GitHub raw URLs via the `/api/getPageContent` route

> [!TIP]
> The `/api/getPageContent` route fetches content from `https://raw.githubusercontent.com/dair-ai/Prompt-Engineering-Guide/main/pages/` at request time. This means the "Copy page" feature always serves the latest `main` branch content, not the deployed version.

## 7. Security

### API Route Input Validation

The three API routes perform basic input validation:

**`/api/getPageContent`** — the most security-sensitive route:
- Validates `pagePath` parameter exists and is a string
- Restricts to `.en.mdx` files only (hardcoded)
- Constructs URLs from user input — path traversal is mitigated by the `.en.mdx` suffix requirement and GitHub's own URL validation
- Fetches from a hardcoded GitHub raw URL base

**`/api/contentFiles`** and **`/api/promptsFiles`** — read local filesystem:
- Accept `section` and `lang` parameters
- Construct filesystem paths using `path.join(process.cwd(), 'pages', section)`
- No explicit sanitization of the `section` parameter — directory traversal is limited by Next.js's API route sandboxing and the fact that `fs.existsSync` / `fs.readdirSync` would fail for non-existent paths

> [!WARNING]
> The `section` parameter in `/api/contentFiles` is used directly in `path.join` without sanitization. While Next.js provides some protection, a defense-in-depth approach would validate that `section` contains no `..` or path separators. This is low-risk in practice since the API only reads metadata files.

### Third-Party Scripts

| Script | Purpose | Privacy Impact |
|--------|---------|---------------|
| Google Analytics (`G-ST7R3WQ353`) | Usage tracking | Sends page views and user data to Google |
| Vercel Analytics | Performance monitoring | Sends web vitals to Vercel |
| SerpAPI logo | Sponsor attribution | External image load from `cdn.rawgit.com` |

### External Data Flows

| Feature | External Call | Data Sent |
|---------|--------------|-----------|
| Copy page / Open in Claude | `/api/getPageContent` then GitHub raw | Page path |
| Open in Claude | Redirects to `claude.ai` | Current page URL in prompt |
| Open in ChatGPT | Redirects to `chatgpt.com` | Current page URL in prompt |
| Course links | Redirects to `academy.dair.ai` | None (navigation only) |

> [!CAUTION]
> The "Open in Claude" and "Open in ChatGPT" features construct URLs that include the current page's URL. Ensure no sensitive internal routes are accidentally exposed through this mechanism.

## 8. Developer Internals

### Repository Structure

```text
Prompt-Engineering-Guide/
├── middleware.js              # Nextra locale routing
├── next.config.js             # Next.js + Nextra configuration
├── theme.config.tsx           # Site theme and branding
├── package.json               # Dependencies and scripts
├── tsconfig.json              # TypeScript configuration
├── CITATION.cff               # Academic citation metadata
├── LICENSE.md                  # MIT License
├── components/                # React components
│   ├── AnnouncementBar.tsx    # Promotional banner
│   ├── CodeBlock.tsx          # Code display with copy
│   ├── ContentFileNames.tsx   # Dynamic content card grid
│   ├── CopyPageDropdown.tsx   # AI integration dropdown
│   ├── CourseCard.tsx         # Course promotion cards
│   ├── PromptFiles.jsx       # Prompt Hub listing
│   ├── TabsComponent.tsx     # Multi-model code tabs
│   ├── button.tsx            # Reusable button
│   ├── check.tsx             # Check icon SVG
│   ├── copy.tsx              # Copy icon SVG
│   ├── copy-to-clipboard.tsx # Clipboard utility
│   ├── counters.tsx          # Example counter
│   ├── pre.tsx               # Custom code block
│   ├── word-wrap.tsx         # Word-wrap icon SVG
│   ├── counters.module.css   # Counter styles
│   ├── icons/                # SVG icons (28 files)
│   │   └── index.ts          # Icon barrel exports
│   └── screenshot/           # Screenshot component
│       └── index.jsx         # Image display
├── pages/                     # Content and routing
│   ├── _app.tsx              # App root (analytics, announcement bar)
│   ├── style.css             # Global styles
│   ├── _meta.*.json          # Navigation metadata (per locale)
│   ├── index.*.mdx           # Homepage (per locale)
│   ├── about.*.mdx           # About page
│   ├── api/                  # API routes
│   │   ├── contentFiles.js   # Section content listing
│   │   ├── getPageContent.ts # Fetch page markdown from GitHub
│   │   └── promptsFiles.js   # Prompt Hub category listing
│   ├── introduction/         # Introduction section
│   ├── techniques/           # Prompting techniques
│   ├── agents/               # AI Agents (English only)
│   ├── guides/               # Topical guides (English only)
│   ├── applications/         # Application guides
│   ├── prompts/              # Prompt Hub
│   ├── models/               # Model guides
│   ├── risks/                # Risks & Misuses
│   └── research/             # Research findings
├── guides/                    # Legacy markdown guides
├── notebooks/                 # Jupyter notebooks (13 files)
├── img/                       # Static images
├── lecture/                   # Lecture PDF
├── ar-pages/                  # Arabic locale pages
└── public/                    # Static assets (favicons)
```

### Content File Naming Convention

All content files follow a strict naming pattern:

```text
{page-slug}.{locale}.mdx
```

Examples:
- `pages/techniques/cot.en.mdx` — Chain-of-Thought page, English
- `pages/techniques/cot.zh.mdx` — Chain-of-Thought page, Chinese
- `pages/techniques/cot.de.mdx` — Chain-of-Thought page, German

Navigation metadata follows the same pattern:

```text
_meta.{locale}.json
```

Each `_meta.*.json` file maps page slugs to display titles for that locale:

```json
{
  "cot": "Chain-of-Thought Prompting",
  "fewshot": "Few-shot Prompting"
}
```

> [!NOTE]
> Arabic (`ar`) uses a different directory structure — content lives in `ar-pages/` rather than within `pages/`. Arabic-locale metadata files use the `.ar.json` and `.ar.mdx` suffixes but are in a separate directory tree. This is an architectural inconsistency — all other locales coexist within `pages/`.

### API Routes

#### `GET /api/contentFiles`

Returns ordered page listings for a given section and locale.

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `section` | string | `research` | Directory name under `pages/` |
| `lang` | string | `en` | Locale code |

**Response:** `{ fileNames: [{ slug, title }] }`

Reads `_meta.{lang}.json` from the specified section directory and returns page slugs with their titles in metadata-defined order.

#### `GET /api/getPageContent`

Fetches cleaned markdown content from GitHub.

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `pagePath` | string | Yes | Path to the `.en.mdx` file relative to `pages/` |

**Response:** `{ content, pagePath }`

Processing steps:
1. Validates that `pagePath` ends with `.en.mdx`
2. Fetches raw content from `https://raw.githubusercontent.com/dair-ai/Prompt-Engineering-Guide/main/pages/{pagePath}`
3. Strips `import` statements, `export` statements, and YAML frontmatter
4. Returns cleaned markdown

#### `GET /api/promptsFiles`

Returns the complete Prompt Hub structure.

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `lang` | string | `en` | Locale code |

**Response:** Array of `{ folderKey, folderName, files: [{ slug, title }] }`

Reads the prompts directory structure and returns category folders with their page listings.

### Component Architecture

#### CopyPageDropdown

The most complex component — provides AI integration features.

**Rendering logic:** Injected into every English non-index page via `theme.config.tsx`'s `main` wrapper.

**State management:**
- `isOpen` — dropdown visibility
- `showMarkdownModal` — markdown preview modal
- `markdownContent` — fetched page content
- `copyStatus` — `idle` | `copying` | `success`
- `hoveredButton` — hover state for styling

**Clipboard implementation:** Two-tier approach:
1. Modern `navigator.clipboard.writeText()` for HTTPS contexts
2. Fallback using `document.execCommand('copy')` with iOS-specific handling (selection range, 16px font to prevent zoom)

**External redirects:**
- Claude: `https://claude.ai/new?q={encoded_prompt}`
- ChatGPT: `https://chatgpt.com/?prompt={encoded_prompt}`

#### CourseCard System

Three exported components for course promotion:
- `CourseCard` — individual course card with tag, title, description, metadata
- `CoursesSection` — grid container for multiple CourseCards
- `CoursePromo` — single-card inline promotion with CTA button

All three support dark mode via a `useDarkMode` hook that observes `document.documentElement.classList` for the `dark` class.

#### Pre Component

Replaces Nextra's default `<pre>` element via `theme.config.tsx`:

```typescript
components: {
  pre: Pre,
}
```

Features:
- Word-wrap toggle (persisted via `document.documentElement.dataset.nextraWordWrap`)
- Copy-to-clipboard (reads from the rendered `<code>` element's `textContent`)
- Optional filename header display

#### ContentFileNames and PromptFiles

Dynamic components that fetch navigation data from the API routes and render Nextra `Cards`:

- `ContentFileNames` — fetches `/api/contentFiles` and renders a card grid for a section
- `PromptFiles` — fetches `/api/promptsFiles` and renders categorized prompt listings with section headers

### Internationalization Deep Dive

The i18n system has three layers:

1. **Next.js i18n routing** (`next.config.js`) — handles URL locale prefixes and detection
2. **Nextra locale middleware** (`middleware.js`) — `export { locales as middleware } from 'nextra/locales'`
3. **Theme i18n labels** (`theme.config.tsx`) — maps locale codes to display names for the language selector

**Content resolution order:**
1. Look for `{slug}.{locale}.mdx` in the current section
2. If not found, the page is not shown in the sidebar for that locale
3. There is no fallback to English — missing translations are simply absent

**Metadata resolution:**
1. Look for `_meta.{locale}.json` in the section directory
2. Pages without metadata entries are still accessible by URL but not shown in navigation

### Code Patterns and Conventions

| Pattern | Usage |
|---------|-------|
| Client-side dark mode detection | `document.documentElement.classList.contains('dark')` via `MutationObserver` |
| Inline styles over CSS classes | Most components use React `style` props; only Nextra utility classes (`nx-*`) are used for theme-consistent styling |
| Hover state management | `onMouseOver` / `onMouseOut` handlers with direct `style` mutation |
| Data fetching | Client-side `fetch()` in `useEffect` hooks; no SWR or React Query |
| TypeScript strictness | Mixed — some components are `.tsx` (typed), some are `.jsx` (untyped) |
| State management | Local React `useState` only; no global state management library |
| SVG icons | Two systems — `@svgr/webpack` for `components/icons/*.svg`, FontAwesome for code block copy buttons |

> [!NOTE]
> The codebase uses two different icon systems (SVGR and FontAwesome) and two different clipboard implementations (the `CopyToClipboard` component and the `CopyPageDropdown`'s inline implementation). This is a historical artifact, not a deliberate architectural choice.

### Testing

No test files or test configuration were found in the repository. The `package.json` does not include a `test` script, and no testing framework (Jest, Vitest, Playwright, Cypress) is present in dependencies.

> [!WARNING]
> The project has no automated tests. Changes to components, API routes, or configuration should be manually verified in the development server across multiple locales before deployment.

### Potential Improvements

Based on source analysis:

1. **Input sanitization for API routes** — the `section` parameter in `/api/contentFiles` should be validated against an allowlist of known section names
2. **Consolidate icon systems** — unify on either SVGR or FontAwesome, not both
3. **Consolidate clipboard implementations** — the `CopyToClipboard` component and `CopyPageDropdown`'s inline clipboard code could share a utility
4. **Add TypeScript to `.jsx` components** — `PromptFiles.jsx` and `screenshot/index.jsx` lack type annotations
5. **Arabic content directory** — consider migrating `ar-pages/` into the standard `pages/` directory with `.ar.mdx` suffixes for consistency
6. **Stale GitHub fetch in `getPageContent`** — fetching from GitHub's `main` branch at request time means the "Copy page" content may differ from the deployed version; consider reading from the local filesystem instead
7. **Add automated testing** — at minimum, smoke tests for API routes and critical component rendering

## 9. Integration Points

### External Services

| Service | Integration Point | Purpose |
|---------|-------------------|---------|
| GitHub | Repository hosting, `getPageContent` API | Source code, raw content serving |
| Vercel | Deployment platform (implied) | Hosting, analytics |
| Google Analytics | `_app.tsx` script tag | Usage tracking |
| SerpAPI | Sponsor logo in git timestamp footer | Sponsorship attribution |
| DAIR.AI Academy | Course links in navbar and CourseCard components | Paid course promotion |
| Discord | Chat link in theme config | Community support |

### Content Pipeline

```text
MDX files → Nextra MDX compiler → React pages → Static HTML (build)
                                                → Server-rendered (API routes)
```

The content pipeline is entirely file-based:
1. Authors write or edit `.mdx` files
2. Navigation structure is defined in `_meta.*.json` files
3. Nextra compiles MDX to React components at build time
4. The search index is built automatically by Nextra
5. Git timestamps provide "last updated" dates

### Adding New Sections

To add a top-level section (e.g., "Benchmarks"):

1. Create the directory: `pages/benchmarks/`
2. Add metadata for each supported locale:
   ```json
   // pages/benchmarks/_meta.en.json
   { "overview": "Benchmarks Overview" }
   ```
3. Add content files: `pages/benchmarks/overview.en.mdx`
4. Register in the top-level navigation metadata:
   ```json
   // pages/_meta.en.json (add the key)
   { "benchmarks": "Benchmarks" }
   ```
5. Repeat metadata entries for other locales as translations become available

## 10. Contributing

### Prerequisites

- Node.js 16+
- Git
- Familiarity with MDX (Markdown + JSX)

### Development Workflow

1. Fork and clone the repository
2. Install dependencies: `npm install`
3. Create a feature branch
4. Make changes
5. Test locally: `npm run dev`
6. Verify across at least 2 locales (English + one other)
7. Submit a pull request

### Content Contribution Guidelines

- Write content in MDX format
- Follow existing page structure for consistency
- Add `_meta.*.json` entries for new pages
- Include images in the appropriate `img/` subdirectory
- Test LaTeX rendering if mathematical notation is used

### Component Contribution Guidelines

- Use TypeScript (`.tsx`) for new components
- Follow the existing inline-style pattern (or propose a migration to CSS modules)
- Support dark mode using the `useDarkMode` pattern from `CourseCard.tsx`
- Test in both light and dark modes
- Verify mobile responsiveness

### Open Community Issues

From GitHub issues (as of source commit):

| Issue | Topic |
|-------|-------|
| #749 | Feedback for Introduction section |
| #741 | Homepage should define what a prompt is |
| #738 | Feedback for Meta Prompting |
| #734 | Korean translation — remaining untranslated pages |
| #724 | Feedback for Prompt Chaining |
| #702 | Feedback: unlisted technique, potential naming conflict with meta-prompting |
| #743 | Feature request: add StoryRoute AI app |
| #742 | Resource suggestion: ORCH CLI for multi-agent teams |
| #730 | Suggestion: reference WFGY problem map in RAG sections |

---

_Generated May 2026 from dair-ai/Prompt-Engineering-Guide at 5767372. AI-generated documentation. The library is checked by sampling (three repositories so far); this guide was not individually reviewed. Verify against the project before relying on it. Unofficial; not affiliated with or reviewed by the project._
