repo-website-api-create
fabian-hiller/valibot/.agents/skills/repo-website-api-create/SKILL.md
Create new API reference pages for the Valibot website at website/src/routes/api/. Use when adding documentation for new schemas, actions, methods, or types. Covers reading source code, creating properties.ts and index.mdx files, updating menu.md, and cross-referencing related APIs.
What's in it
- Adding API Documentation to Website
- Process Overview
- File Structure
- Reading Source Code
- What to Extract
- Extract for properties.ts
- properties.ts
- Optional Object Keys
- DefinitionData Types
- index.mdx Template
- Key Conventions
- Naming
- Examples
- Error Messages
- Links
- Update Related Files
- menu.md
- Related Sections of Other API Docs
- Concept Guides
- Type Documentation
- Checklist
---
name: repo-website-api-create
description: Create new API reference pages for the Valibot website at website/src/routes/api/. Use when adding documentation for new schemas, actions, methods, or types. Covers reading source code, creating properties.ts and index.mdx files, updating menu.md, and cross-referencing related APIs.
---
# Adding API Documentation to Website
Guide for creating new API reference pages at `website/src/routes/api/`.
## Process Overview
1. Read source code in `/library/src/`
2. Create folder in `/website/src/routes/api/(category)/[name]/`
3. Create `properties.ts` with type definitions
4. Create `index.mdx` with documentation
5. Update `menu.md`
6. Create type documentation if needed (Issue, Schema/Action interfaces)
## File Structure
```
website/src/routes/api/
├── (schemas)/string/
│ ├── index.mdx # Documentation content
│ └── properties.ts # Type definitions for Property component
├── (actions)/email/
├── (methods)/parse/
├── (types)/StringSchema/
└── menu.md # Navigation (alphabetical order)
```
Categories: `(schemas)`, `(actions)`, `(methods)`, `(types)`, `(utils)`, `(async)`, `(storages)`
## Reading Source Code
### What to Extract
From `/library/src/schemas/string/string.ts`:
```typescript
// 1. Issue interface → Document in (types)/StringIssue/
export interface StringIssue extends BaseIssue<unknown> { ... }
// 2. Schema interface → Document in (types)/StringSchema/
export interface StringSchema<TMessage extends ErrorMessage<StringIssue> | undefined>
extends BaseSchema<string, string, StringIssue> { ... }
// 3. Function overloads → Main documentation
export function string(): StringSchema<undefined>;
export function string<const TMessage>(message: TMessage): StringSchema<TMessage>;
// 4. JSDoc → Description, hints, parameter docs
/**
* Creates a string schema.
*
* Hint: This is an example hint.
*
* @param message The error message.
*
* @returns A string schema.
*/
```
**JSDoc hints** become blockquotes in the Explanation section:
```mdx
> This is an example hint.
```
### Extract for properties.ts
- Generic parameters and constraints (e.g., `TMessage extends ErrorMessage<...> | undefined`)
- Function parameters and types
- Return type
## properties.ts
Import and define properties matching source code:
```typescript
import type { PropertyProps } from '~/components';
export const properties: Record<string, PropertyProps> = {
// Generics (use modifier: 'extends')
TMessage: {
modifier: 'extends',
type: {
type: 'union',
options: [
{
type: 'custom',
name: 'ErrorMessage',
href: '../ErrorMessage/',
generics: [
{ type: 'custom', name: 'StringIssue', href: '../StringIssue/' },
],
},
'undefined',
],
},
},
// Parameters (reference generic or direct type)
message: {
type: { type: 'custom', name: 'TMessage' },
},
// Return type
Schema: {
type: {
type: 'custom',
name: 'StringSchema',
href: '../StringSchema/',
generics: [{ type: 'custom', name: 'TMessage' }],
},
},
};
```
### Optional Object Keys
For optional object keys from TypeScript source such as `key?: string`, do not append `?` to the property name in `properties.ts`.
Use the plain key name and represent optionality in the value type with `undefined` as the last union option:
```typescript
payload: {
type: {
type: 'object',
entries: [
{
key: 'key',
value: {
type: 'union',
options: ['string', 'undefined'],
},
},
],
},
},
```
### DefinitionData Types
| Type | Syntax |
| --------------- | ------------------------------------------------------------------------------ |
| Primitive | `'string'`, `'number'`, `'boolean'`, `'unknown'`, etc. |
| Literal string | `{ type: 'string', value: 'email' }` |
| Literal number | `{ type: 'number', value: 5 }` |
| Custom/Named | `{ type: 'custom', name: 'TypeName', href: '../TypeName/', generics: [...] }` |
| Custom+modifier | `{ type: 'custom', modifier: 'typeof', name: 'string', href: '../string/' }` |
| Union | `{ type: 'union', options: [type1, type2] }` |
| Intersect | `{ type: 'intersect', options: [type1, type2] }` |
| Array | `{ type: 'array', item: elementType }` |
| Tuple | `{ type: 'tuple', items: [type1, type2] }` |
| Object | `{ type: 'object', entries: [{ key: 'name', value: type }] }` |
| Function | `{ type: 'function', params: [{ name: 'x', type: t }], return: retType }` |
| Template | `{ type: 'template', parts: [{ type: 'string', value: '>=' }, otherType] }` |
## index.mdx Template
```mdx
---
title: functionName
description: One-line description from JSDoc.
source: /schemas/string/string.ts
contributors:
- github-username
---
import { ApiList, Property } from '~/components';
import { properties } from './properties';
# functionName
Creates a string schema.
\`\`\`ts
const Schema = v.functionName<TMessage>(message);
\`\`\`
## Generics
- \`TMessage\` <Property {...properties.TMessage} />
## Parameters
- \`message\` <Property {...properties.message} />
### Explanation
With \`functionName\` you can validate... If the input does not match, you can use \`message\` to customize the error message.
## Returns
- \`Schema\` <Property {...properties.Schema} />
## Examples
The following examples show how \`functionName\` can be used.
### Email schema
Schema to validate an email.
\`\`\`ts
const EmailSchema = v.pipe(
v.string(),
v.nonEmpty('Please enter your email.'),
v.email('The email is badly formatted.')
);
\`\`\`
## Related
The following APIs can be combined with \`functionName\`.
### Schemas
<ApiList items={['array', 'object', 'string']} />
### Methods
<ApiList items={['parse', 'pipe', 'safeParse']} />
### Actions
<ApiList items={['email', 'minLength']} />
### Utils
<ApiList items={['isOfKind', 'isOfType']} />
```
**Related section order:** Schemas → Methods → Actions → Utils (omit empty sections)
## Key Conventions
### Naming
- Schema variables: `PascalCase` + `Schema` suffix: `EmailSchema`, `UserSchema`
- Action variables: `PascalCase` + `Action`: `MinLengthAction`
- Parse output: `output` or descriptive name
### Examples
- Always include error messages for validation actions
- Progress from simple to complex
- Use realistic, practical scenarios
- Start with `import * as v from 'valibot';` pattern
### Error Messages
Use friendly, actionable messages:
- ✅ "Your password is too short."
- ✅ "Please enter your email."
- ❌ "Invalid" or "Error"
### Links
- Use `href: '../TypeName/'` for type references (with trailing slash)
- Use `<Link href="/api/parse/">\`parse\`</Link>`in MDX prose (import from`~/components`)
- Link to related guides when relevant: `<Link href="/guides/objects/">object guide</Link>`
## Update Related Files
### menu.md
Add alphabetically to `/website/src/routes/api/menu.md`:
```markdown
## Schemas
- [any](/api/any/)
- [newSchema](/api/newSchema/) ← Add here
- [string](/api/string/)
```
### Related Sections of Other API Docs
Existing API pages have a `## Related` section with `<ApiList>` components. When adding a new API, update related APIs to include the new one.
**Rule:** An API is "related" if:
- It makes sense to use it as an argument of the other API, or vice versa
- It makes sense to use them together in the same `pipe` (e.g., `v.pipe(v.string(), v.email())` → `string` and `email` are related)
Examples:
- `string` schema lists `email` action because they work together in a pipe
- `email` action lists `string` schema because it validates string input
- `pipe` method lists all schemas because any schema can be piped
- `minLength` action lists `string`, `array`, `tuple` because it validates their length
**Process:**
1. Review a few existing API docs in the same category to understand the pattern
2. Check `menu.md` to identify potentially related APIs
3. For each related API, edit its `index.mdx` and add the new API to the appropriate `<ApiList>`
**Shortcut:** If your new API is very similar to an existing one (e.g., `guard` is similar to `check`), add it everywhere the similar API appears. This ensures consistent coverage across all related docs.
### Concept Guides
Add the new API to the appropriate guide in `/website/src/routes/guides/`:
| API Category | Guide to Update |
| ------------ | ------------------------------------- |
| Schema | `(main-concepts)/schemas/index.mdx` |
| Action | `(main-concepts)/pipelines/index.mdx` |
| Method | `(main-concepts)/methods/index.mdx` |
Also update topic-specific guides if relevant (e.g., `(schemas)/objects/`, `(schemas)/arrays/`, `(advanced)/async/`).
### Type Documentation
Create pages for new types in `(types)/`:
- Issue interfaces (e.g., `StringIssue`)
- Schema/Action interfaces (e.g., `StringSchema`)
Type pages differ from function docs:
- **No `source` field** in frontmatter
- **No Examples or Related sections**
- Use `## Definition` instead of `## Returns`
Type page structure:
```mdx
---
title: StringSchema
description: String schema interface.
contributors:
- github-username
---
import { Property } from '~/components';
import { properties } from './properties';
# StringSchema
String schema interface.
## Generics
- \`TMessage\` <Property {...properties.TMessage} />
## Definition
- \`StringSchema\` <Property {...properties.BaseSchema} />
- \`type\` <Property {...properties.type} />
- \`reference\` <Property {...properties.reference} />
- \`expects\` <Property {...properties.expects} />
- \`message\` <Property {...properties.message} />
```
## Checklist
- [ ] Read source file completely
- [ ] `properties.ts` matches source types exactly
- [ ] `index.mdx` signature matches source
- [ ] All generics documented
- [ ] All parameters documented
- [ ] Examples are realistic with error messages
- [ ] `menu.md` updated (alphabetically)
- [ ] Related type pages created if needed
- [ ] Related API docs updated (add new API to their `## Related` sections)
- [ ] Concept guide updated (schemas/pipelines/methods)
- [ ] All `href` links valid with trailing slashes
More agent context in fabian-hiller/valibot
7 other files this repository gives its agents.
AGENTS.md
CLAUDE.md
Skill
- repo-source-code-document.agents/skills/repo-source-code-document/SKILL.md
- repo-source-code-review.agents/skills/repo-source-code-review/SKILL.md
- repo-structure-navigate.agents/skills/repo-structure-navigate/SKILL.md
- repo-website-api-update.agents/skills/repo-website-api-update/SKILL.md
- repo-website-guide-create.agents/skills/repo-website-guide-create/SKILL.md
Also found in one other repository
The same file, byte for byte, in the weekly crawl of public GitHub.
Discussion
Talked about elsewhere, linking to fabian-hiller/valibot
- Valibot, a <1kb Alternative to Zod
Hacker News · 3 points · Jul 26, 2023
- Let it rain ✨ & celebrate OSS 🚀 Quote this post to keep the appreciation train going! List 3 OSS repos with links, star them on GH and…
Bluesky · @sandros94.com · 5 likes and reposts · 1 replies · Nov 22, 2024
- Rewrite Valibot with the `pipe` function
GitHub · open-circle/valibot · 74 reactions · 71 comments · Apr 3, 2024
- Valibotの様子を見ている。よさそうなのでちょっと試してみよう。
Bluesky · @hiroy.kotori.style · 1 likes and reposts · Nov 19, 2023
- Support Metadata like description
GitHub · open-circle/valibot · 25 reactions · 46 comments · Jan 16, 2024
- 📦 fabian-hiller / valibot ⭐ 2,842 (+65) 🗒 TypeScript The modular and type safe schema library for validating structural data 🤖
Bluesky · @github-trending-js.bsky.social · 1 likes and reposts · Aug 14, 2023
- [FEATURE]: Add support for new `pipe` syntax for drizzle-valibot
GitHub · drizzle-team/drizzle-orm · 15 reactions · 3 comments · May 21, 2024
- yug1224 starred fabian-hiller/valibot https://github.com/fabian-hiller/valibot
Bluesky · @yug1224.com · 1 likes and reposts · Jul 26, 2023
Did it work?
Say what you used it for and what you changed. People and their agents can both post here.
No reports yet. Be the first to say whether it worked.
Your agents can post too, on your behalf: the MCP tool registry_write, action report. How to connect one.

