- Always use English for all documentation
- Section titles: Use Title Case formatting (e.g., "Configuration Variables", "Getting Started")
- Line length: Wrap lines at maximum 120 characters for readability
- Tone: Be clear, concise, and technical. Use present tense and active voice where possible
- Provide minimal examples that exclude optional configuration variables
- Examples should focus on the essential configuration only
- When components have dependencies:
- Include a sentence explaining the dependency
- Provide a link to the dependency's documentation
- Do NOT include the dependent component's configuration in the example
- ALWAYS use the literal string
GPIOXXin documentation examples - The
XXis literal - do NOT replace with actual numbers likeGPIO16 - Exception: Only use specific pin numbers when documenting hardware with fixed pins
- This ensures examples work across different boards and users replace with their actual pins
Every documentation page must start with YAML frontmatter:
---
title: "Component Name"
description: "Brief description of the component"
---Important:
- The
titlefield becomes the H1 heading automatically - Do NOT repeat the title as a
# Headingin the markdown content - The description should be concise (1-2 sentences)
- Both title and description should be quoted strings
-
Start with H2 (
##) for main sections -
Never use H1 (
#) in the content (it's generated from frontmatter) -
Use proper nesting: H2 → H3 → H4
-
Examples:
## Configuration Variables ### Required Options #### Advanced Settings
- Files use MDX format (
.mdxextension) which allows JSX components in Markdown - Import required components at the top of the file after frontmatter
- Use single backticks for inline code:
variable_name,sensor,GPIOXX - Use for: component names, variable names, short code snippets, pin numbers
- Use triple backticks with language identifier:
sensor:
- platform: dht
pin: GPIOXX
temperature:
name: "Living Room Temperature"- Common language identifiers:
yaml,cpp,python,bash
Use special formatting to indicate parameter requirements:
- Config key: Always bold
- Required label: Bold
- Optional label: Italics
Example:
- **pin** (**Required**, Pin): The pin where the sensor is connected.
- **update_interval** (*Optional*, Time): The interval to check the sensor. Defaults to `60s`.Standard markdown syntax:
[ESP32 Datasheet](https://www.espressif.com/sites/default/files/documentation/esp32_datasheet_en.pdf)Use relative paths starting with /:
- See [WiFi](/components/wifi/) for WiFi configuration
- Configure [I²C](/components/i2c/) first
- Check out the [Deep Sleep](/components/deep_sleep/) componentImportant: Always include trailing slash / for internal links.
Headings automatically create anchors using their slugified form. To link to a specific section:
See [Configuration Variables](#configuration-variables) for details.Wherever possible, use automatic anchors generated from headings. Never put a <span id="..."> in front of a heading:
the heading already has an anchor, and a page-prefixed id such as #wifi-manual_ip in front of ## Manual IPs on the
WiFi page only duplicates #manual-ips. Older pages still carry such spans; do not copy the pattern into new sections,
and leave the existing ones in place unless you also update every link that points to them.
Only when it is not feasible to use automatic anchors, for example a link target in the middle of a list or a paragraph, should you use HTML:
<span id="custom-section-name"></span>Directory Structure and Import Strategy:
-
Single-use images (used in only one file):
- Store in a local
images/directory next to the MDX file - Import at the top of the file
- Use imported image reference
import { Image } from 'astro:assets'; import myImageImg from './images/my-image.jpg'; <Image src={myImageImg} alt="Description" layout="constrained" />
- Store in a local
-
Multi-use images (used in multiple files):
- Store in
/public/images/ - Reference using absolute path
<Image src="/images/shared-image.jpg" alt="Description" layout="constrained" />
- Store in
-
ImgTable images (component index pages):
- MUST be in
/public/images/ - ImgTable component resolves to
/images/filename.png
- MUST be in
Image Optimization:
- ALWAYS optimize images before adding (use TinyPNG/TinyJPG)
- Maximum size: ~1000x800 pixels
- All images must be as small as possible to minimize page load times
- Variable names follow camelCase with
Imgsuffix (e.g.,myImageImg)
Image Attributes:
src: Either imported variable or absolute pathalt: Alternative text for accessibility (required)layout: Use"constrained"for responsive imageswidthandheight: Optional pixel values (not percentages)
Styling Images:
Use inline styles for sizing:
<Image
src={myImageImg}
alt="Description"
layout="constrained"
style="width: 50%; height: auto; margin: 0 auto; display: block;"
/>- Aspect ratio: 8:10 or 10:8 (portrait or landscape orientation)
- Format: SVG (heavily compressed) or JPG (max 300x300px)
- Location:
/public/images/directory - Reference: Use
/images/filenamepath in ImgTable - Used in component listings and cards
Use GitHub-style alert syntax:
> [!NOTE]
> This is an informational note for users.
> [!IMPORTANT]
> This provides important information that should be emphasized.
> [!TIP]
> This provides helpful tips and best practices.
> [!WARNING]
> This warns users about potential issues or breaking changes.
> [!CAUTION]
> This warns about critical issues that could cause damage.When to use:
NOTE: General information, clarifications, important contextIMPORTANT: Important information that needs emphasisTIP: Optimization suggestions, best practices, pro tipsWARNING: Potential issues, breaking changes, compatibility notesCAUTION: Critical warnings that could cause damage or data loss
Use LaTeX syntax with KaTeX for equations:
Inline math:
The formula is $E = mc^2$ where...Block equations:
$$
\text{formula} = \frac{a}{b}
$$Link to C++ API documentation:
import APIRef from '@components/APIRef.astro';
<APIRef text="component.h" path="component/component.h" />Create grids of component cards:
<ImgTable items={[
["Title", "/path/to/page/", "image.png"],
["Title 2", "/path/to/page2/", "image2.png", "caption"],
["Title 3", "/path/to/page3/", "image3.png", "caption", "dark-invert"],
]} />Important: All ImgTable images must be in /public/images/.
Add captions to images using the Figure component:
Simple text caption (using caption prop):
import Figure from '@components/Figure.astro';
import myImageImg from './images/my-image.jpg';
<Figure
src={myImageImg}
alt="Description"
caption="This caption appears below the image"
/>Caption with markdown links (using caption slot):
import Figure from '@components/Figure.astro';
<Figure
src="/images/badge.svg"
alt="Badge"
>
<p slot="caption">
Download: [svg](/images/badge.svg), [png](/images/badge.png)
</p>
</Figure>With absolute path for multi-use images:
<Figure
src="/images/shared-image.jpg"
alt="Description"
caption="Optional caption text"
style="width: 50%"
/>Props:
src: Either imported variable or absolute path (required)alt: Alternative text for accessibility (required)caption: Optional caption text for simple captions (string)layout: Use"constrained"for responsive images (default)style: Optional inline CSS styleswidth,height: Optional pixel values
Slots:
caption: For captions with markdown/links (use<Fragment slot="caption">with markdown content)
If your content needs the same HTML or CSS structure repeated many times — for example, every row in a table calling
the same widget — that pattern is a candidate for a reusable Astro component under src/components/.
LightEffectPreview is an example: it renders a small animated preview that the light effects table calls once per
row.
When you're not sure whether a new component is the right call, flag it in your PR description and let maintainers
decide. Avoid duplicating large blocks of inline <style> or HTML directly in MDX content.
When Markdown syntax produces the same rendered result, use it instead of raw HTML:
- Markdown tables (
| col1 | col2 |) over<table>blocks - Markdown links (
[text](url)) over<a href> - Markdown emphasis (
*italic*,**bold**) over<i>,<b>,<em>,<strong>
Raw HTML and JSX should appear only when Markdown cannot express what you need: invoking custom components like
LightEffectPreview or Figure, complex layouts, or specific accessibility attributes.
- Bug fixes and documentation corrections: Target the
currentbranch - New features and new component docs: Target the
nextbranch - Create separate branches for each pull request (one PR per feature/fix)
- Prefer small, focused pull requests: If a change spans multiple unrelated topics or files, split into separate PRs for easier review
- Always branch from the target branch: Use
git checkout -b <branch-name> currentorgit checkout -b <branch-name> nextto ensure you're branching from the correct base
- Use clear, descriptive commit messages
- Format:
[component] Brief description of change - Examples:
[dht] Fix temperature sensor example[wifi] Add WPA3 configuration documentation[docs] Update contributing guidelines
- Ensure all changes are committed to the feature branch
- Push to origin:
git push -u origin <branch-name> - Create the PR using the
.github/PULL_REQUEST_TEMPLATE.mdtemplate - fill out all sections completely - All automated tests must pass before review
- For new components, update
/src/content/docs/components/index.mdx
To preview documentation locally:
npm install
npm run devThen access the preview at http://localhost:4321/
npm run build- Check that all links work (internal and external with trailing slashes)
- Verify code examples are syntactically correct
- Ensure images are optimized and properly sized
- Confirm line length is ≤120 characters
- Validate YAML frontmatter is present and correct
- Test that headings follow proper hierarchy (H2→H3→H4)
- Verify no H1 headings in content (title comes from frontmatter)
- Verify images are imported correctly (single-use) or in /public/images/ (multi-use)
- Check that ImgTable images are in /public/images/
- Section headings use Title Case (e.g., "Configuration Variables")
- Variable names, parameter names, and short code snippets are wrapped in single backticks
- Markdown syntax used when it produces the same result as raw HTML
- No large inline
<style>blocks in MDX (raise with maintainers if you think one is needed)
A typical component page should follow this structure:
---
title: "Component Name"
description: "One-line description of what the component does"
---
import { Image } from 'astro:assets';
import myImageImg from './images/my-image.jpg';
import APIRef from '@components/APIRef.astro';
Brief introduction paragraph explaining what the component is and what it does.
<Image src={myImageImg} alt="Component image" layout="constrained" />
## Configuration
```yaml
# Minimal configuration example hereList of all configuration variables with proper formatting.
Additional examples showing common use cases.
Note: APIRef component would be used here but cannot be shown in markdown example.
Good example (minimal, focused):
sensor:
- platform: dht
pin: GPIOXX
temperature:
name: "Temperature"Bad example (includes unnecessary optional parameters):
sensor:
- platform: dht
pin: GPIOXX
model: AUTO_DETECT
update_interval: 60s
temperature:
name: "Temperature"
id: temp_sensor
unit_of_measurement: "°C"
accuracy_decimals: 1- Files use MDX format (
.mdxextension) - Import components at the top after frontmatter
- Never duplicate the title - it's automatically generated from frontmatter
- Start with H2, not H1
- Wrap at 120 characters maximum
- Use Title Case for section headings
- Optimize images before adding them
- Single-use images: Import from
./images/ - Multi-use images: Absolute path from
/public/images/ - ImgTable images: Must be in
/public/images/ - Keep examples minimal - only essential configuration
- Use literal
GPIOXX- the XX is literal, don't replace with numbers (unless fixed hardware) - Link to dependencies instead of including their config
- Target correct branch (current vs next)
- Internal links: Include trailing slash (e.g.,
/components/wifi/) - GitHub CLI not available - ask user for GitHub information if needed