- 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. Only when it is not feasible to use automatic anchors 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