Docs & ÉcritureSûr100100/100
Docs Features (TanStack)
Build documentation metadata with docsMarkdownExtensions, GitHub-style callouts, heading collection, comment components, heading/file/package- manager/bundler tabs, framework panels, and code-fence metadata. Load when authoring or consuming TanStack-style docs syntax and custom-element data contracts.
ou envoie-le directement à ton agent.
Installer dans ton projet
$ curl -fsSL https://arboristhree.xyz/cli/install-skill.mjs -o /tmp/arboris-install-skill.mjs && node /tmp/arboris-install-skill.mjs docs-features__tanstack-markdown__skills-227acc4c33e0TanStack
TanStack/markdown
Contenu à copier
---
name: 'docs-features'
description: >
Build documentation metadata with docsMarkdownExtensions, GitHub-style
callouts, heading collection, comment components, heading/file/package-
manager/bundler tabs, framework panels, and code-fence metadata. Load when
authoring or consuming TanStack-style docs syntax and custom-element data
contracts.
metadata:
origin: TanStack
type: core
library: '@tanstack/markdown'
library_version: '1.0.0'
requires:
- 'render-markdown'
sources:
- 'TanStack/markdown:docs/guides/docs-preset.md'
- 'TanStack/markdown:docs/reference/extensions.md'
- 'TanStack/markdown:src/extensions/docs.ts'
- 'TanStack/markdown:src/extensions/tabs.ts'
- 'TanStack/markdown:src/extensions/framework.ts'
- 'TanStack/markdown:src/extensions/headings.ts'
- 'TanStack/markdown:src/extensions/comment-components.ts'
---
This skill builds on [render-markdown](../render-markdown/SKILL.md). Read it first for parser options, AST reuse, rendering, and core trust boundaries.
# Docs Features
## Setup
Create one extension array and use it for parsing and rendering:
```ts
import { renderHtml } from '@tanstack/markdown/html'
import { parseMarkdown } from '@tanstack/markdown/parser'
import { docsMarkdownExtensions } from '@tanstack/markdown/extensions/docs'
const source = `# Deployment
> [!TIP] Parse once
> Reuse the document for every renderer.
## Install
Run the package-manager command for your application.`
const extensions = docsMarkdownExtensions()
const document = parseMarkdown(source, { extensions })
export const headings = document.headings
export const html = renderHtml(document, {
extensions,
headingAnchors: true,
})
```
The preset composes callouts, transformed comment components, and heading collection. It emits metadata and custom elements; it does not install documentation UI behavior.
## Core Patterns
### Collect headings without selector headings
```ts
import { parseMarkdown } from '@tanstack/markdown/parser'
import { docsMarkdownExtensions } from '@tanstack/markdown/extensions/docs'
const source = `# Guide
<!-- ::start:tabs -->
## React
React setup
## Solid
Solid setup
<!-- ::end:tabs -->
## API`
const extensions = docsMarkdownExtensions()
export const document = parseMarkdown(source, { extensions })
export const headings = document.headings
```
Heading collection defaults to skipping every heading inside a component named `tabs`. Pass `docsMarkdownExtensions({ collectHeadings: false })` to disable collection or an options object with `skipComponentNames` to replace the default skip set.
### Author each tab input shape
Heading tabs split at the shallowest heading:
```md
<!-- ::start:tabs -->
## React
React setup
## Solid
Solid setup
<!-- ::end:tabs -->
```
File tabs select fenced code blocks and use `title=` or `file=` as labels:
````md
<!-- ::start:tabs variant="files" -->
```tsx file="app.tsx"
export function App() {
return <main>Docs</main>
}
```
```css file="app.css"
main {
display: block;
}
```
<!-- ::end:tabs -->
````
Package-manager tabs consume `framework: package...` lines and shared `package...` lines, then remove their source children after creating metadata:
```md
<!-- ::start:tabs variant="package-manager" mode="dev-install" -->
react: @tanstack/react-query @tanstack/react-router
solid: @tanstack/solid-query @tanstack/solid-router
<!-- ::end:tabs -->
```
Bundler tabs accept only Vite and Rsbuild heading sections:
````md
<!-- ::start:tabs variant="bundler" -->
## Vite
```ts
export default { plugins: [] }
```
## Rsbuild
```ts
export default { plugins: [] }
```
<!-- ::end:tabs -->
````
Every transform returns the original component unchanged when its required structure is absent. See [docs metadata contracts](references/docs-metadata.md) for exact properties and fallback rules.
### Build framework-specific panels
```md
<!-- ::start:framework -->
# React
## Install
```tsx title="react.tsx"
export const framework = 'react'
```
# Solid
## Install
```tsx title="solid.tsx"
export const framework = 'solid'
```
<!-- ::end:framework -->
```
Framework blocks require level-one selector headings. They emit `md-framework-panel` children, lowercase framework names, label nested headings, and expose code-block metadata by framework.
### Read component metadata before rendering
```ts
import type { ComponentNode } from '@tanstack/markdown'
import { parseMarkdown } from '@tanstack/markdown/parser'
import { docsMarkdownExtensions } from '@tanstack/markdown/extensions/docs'
interface TabDescriptor {
slug: string
name: string
}
function isTabsNode(node: unknown): node is ComponentNode {
return (
typeof node === 'object' &&
node !== null &&
'type' in node &&
node.type === 'component' &&
'name' in node &&
node.name === 'tabs'
)
}
const source = `<!-- ::start:tabs -->
## React
React content
## Solid
Solid content
<!-- ::end:tabs -->`
const document = parseMarkdown(source, {
extensions: docsMarkdownExtensions(),
})
const tabsNode = document.children.find(isTabsNode)
const metadata = tabsNode?.properties?.['data-attributes']
export const tabs: TabDescriptor[] = metadata
? (JSON.parse(metadata) as { tabs: TabDescriptor[] }).tabs
: []
```
`ComponentNode.properties` holds strings. JSON-bearing values are serialized into escaped HTML attributes by the HTML renderer and must be parsed by the consuming application.
## Common Mistakes
### HIGH Assuming transformed tabs are interactive
Wrong:
```ts
import { renderHtml } from '@tanstack/markdown/html'
import { docsMarkdownExtensions } from '@tanstack/markdown/extensions/docs'
const source = `<!-- ::start:tabs -->
## React
React content
<!-- ::end:tabs -->`
export const interactiveTabs = renderHtml(source, {
extensions: docsMarkdownExtensions(),
})
```
Correct:
```ts
import type { ComponentNode } from '@tanstack/markdown'
import { parseMarkdown } from '@tanstack/markdown/parser'
import { docsMarkdownExtensions } from '@tanstack/markdown/extensions/docs'
const source = `<!-- ::start:tabs -->
## React
React content
<!-- ::end:tabs -->`
const document = parseMarkdown(source, {
extensions: docsMarkdownExtensions(),
})
const tabsNode = document.children.find(
(node): node is ComponentNode =>
node.type === 'component' && node.name === 'tabs',
)
export const tabPanels =
tabsNode?.children.filter(
(node): node is ComponentNode =>
node.type === 'component' && node.tagName === 'md-tab-panel',
) ?? []
```
The transform supplies a model and custom-element names; the site must bind those values to its own state, controls, and renderer components.
Source: `docs/guides/docs-preset.md`
### HIGH Leaving a component block unmatched
Wrong:
```ts
import { parseMarkdown } from '@tanstack/markdown/parser'
import { docsMarkdownExtensions } from '@tanstack/markdown/extensions/docs'
const source = `<!-- ::start:tabs -->
## React
React content`
export const document = parseMarkdown(source, {
extensions: docsMarkdownExtensions(),
})
```
Correct:
```ts
import { parseMarkdown } from '@tanstack/markdown/parser'
import { docsMarkdownExtensions } from '@tanstack/markdown/extensions/docs'
const source = `<!-- ::start:tabs -->
## React
React content
<!-- ::end:tabs -->`
export const document = parseMarkdown(source, {
extensions: docsMarkdownExtensions(),
})
```
An unmatched start is consumed as an empty component, while the following body remains ordinary Markdown.
Source: `src/extensions/comment-components.ts:41-63`
### MEDIUM Passing the wrong tab content shape
Wrong:
```ts
import { parseMarkdown } from '@tanstack/markdown/parser'
import { docsMarkdownExtensions } from '@tanstack/markdown/extensions/docs'
const source = `<!-- ::start:tabs variant="files" -->
This variant does not turn prose into a file.
<!-- ::end:tabs -->`
export const document = parseMarkdown(source, {
extensions: docsMarkdownExtensions(),
})
```
Correct:
````ts
import { parseMarkdown } from '@tanstack/markdown/parser'
import { docsMarkdownExtensions } from '@tanstack/markdown/extensions/docs'
const source = `<!-- ::start:tabs variant="files" -->
\`\`\`ts file="app.ts"
export const app = true
\`\`\`
<!-- ::end:tabs -->`
export const document = parseMarkdown(source, {
extensions: docsMarkdownExtensions(),
})
````
The file transform silently returns the original component when it finds no direct code-block children; the other variants have similarly specific input contracts.
Source: `src/extensions/tabs.ts:16-18`
### MEDIUM Expecting fence metadata to highlight code
Wrong:
````ts
import { renderHtml } from '@tanstack/markdown/html'
const source = `\`\`\`ts file="app.ts" {2}
const one = 1
const two = 2
\`\`\``
export const html = renderHtml(source)
````
Correct:
````ts
import { createHighlighter } from '@tanstack/highlight/core'
import { plaintext } from '@tanstack/highlight/languages/plaintext'
import { ts } from '@tanstack/highlight/languages/ts'
import { createTanStackMarkdownHighlighter } from '@tanstack/highlight/markdown'
import { renderHtml } from '@tanstack/markdown/html'
const source = `\`\`\`ts file="app.ts" {2}
const one = 1
const two = 2
\`\`\``
const highlighter = createHighlighter({
languages: [plaintext, ts],
})
export const html = renderHtml(source, {
highlighter: createTanStackMarkdownHighlighter(highlighter),
})
````
Fence metadata populates the AST and highlighter options, but tokenization, themes, and CSS stay outside this package.
Source: `docs/core-concepts/syntax-profile.md`
## Boundaries
- Docs transforms enrich trusted repository-authored content but do not execute MDX, JSX, or JavaScript expressions.
- Highlighter output is trusted HTML. Keep highlighting at build time or on the server and apply the checks in [production-pipelines](../production-pipelines/SKILL.md).
- Import individual extension entry points when the complete preset adds unused behavior or bundle cost.
- Use [custom-extensions](../custom-extensions/SKILL.md) when built-in comment components or transforms do not express the required deterministic syntax.
- Use the React or Octane renderer skill to map emitted tags such as `md-tab-panel` and `md-framework-panel` to framework components.
## References
- [Docs metadata contracts](references/docs-metadata.md)Colle ce Markdown dans ton agent ou utilise les boutons ci-dessus pour l’écrire dans ton projet.
Ce que fait Docs Features (TanStack)
Docs transforms enrich trusted repository-authored content but do not execute MDX, JSX, or JavaScript expressions.
Highlighter output is trusted HTML. Keep highlighting at build time or on the server and apply the checks in [production-pipelines](../production-pipelines/SKILL.md).
Import individual extension entry points when the complete preset adds unused behavior or bundle cost.
Use [custom-extensions](../custom-extensions/SKILL.md) when built-in comment components or transforms do not express the required deterministic syntax.
Comment utiliser Docs Features (TanStack)
1
Copie le prompt
Un clic copie le prompt packagé (ou l'envoie à ton agent).
2
L'agent installe le skill
Il ajoute le SKILL.md et ses ressources à ton projet.
3
Activation automatique
Le skill s'active dès que le contexte correspond.
Déclencheurs pour Docs Features (TanStack)
Dis simplement à ton agent quelque chose comme :
Applique le skill docs-features__tanstack-markdown__skills-227acc4c33e0 à cette tâche
Utilise docs-features__tanstack-markdown__skills-227acc4c33e0 pour améliorer cette implémentation
Passe en revue ce sujet avec docs-features__tanstack-markdown__skills-227acc4c33e0
Skills liés à Docs Features (TanStack)
Add Excel (Microsoft)
Adds Excel Online (Business) connector to a Power Apps code app. Use when reading or writing Excel workbook data from OneDrive or SharePoint.IA Usecase Assessment (Microsoft)
Use this skill whenever the user says "assess this use case", "score my AI use case", "prioritise these agent ideas", "generate a use case assessment report", or "update my AI use case report" — or when they attach a use-case document, SDR, or prior `*_AI_UseCase_Assessment_Report_*.html` and ask you to assess, strengthen, score, or refresh it. Invoke BEFORE writing any assessment content and BEFORE generating any report.Aibast Document Checklist 03 (Microsoft)
Use for document readiness questions in the Customer Onboarding Agent synthetic pilot.