Adding an integration page
To create a new integration page, follow these steps:
- The documentation repository has two main branches:
currentandnext:- If you are documenting a new integration you are adding to the code, switch to the
nextbranch.
- If you are documenting a new integration you are adding to the code, switch to the
- Make a copy of the integration documentation template and edit it.
- Make sure the filename of the integration page matches the domain name of the integration.
- The Integration overview and the Examples section are generated automatically, so there is no need to add a link to those pages.
- Make sure to follow the Standards we have for the documentation, including:
- Make sure to add icon and logo to the brands repository.
- If your integration was a custom integration (HACS), move the brand files into the
core_integrationsfolder.
- If your integration was a custom integration (HACS), move the brand files into the
- Document the steps required to retrieve API keys or access token for the third-party service or device, if needed.
- Make sure the documentation does not refer to custom integrations. The steps and examples, including automation examples, should not depend on custom cards or custom integrations.
- Add the type of the devices (including firmware) you have tested when you know that there are multiple out there.
- When adding blueprints, upload them either to the blueprints folder under
https://github.com/home-assistant/home-assistant.io/tree/current/source/blueprints/integrations, or to the blueprint exchange on the forums. On the integration page, add a link to the blueprint exchange. - Before marking your PR as Ready for review, remove the comments.
About the integration page header format
Every integration page starts with a YAML front matter header that provides metadata about the integration. This metadata drives the integration overview page, discovery, quality badges, and more. The keys you include depend on the integration's capabilities.
---
title: "Awesome Sensor"
description: "home-assistant.io web presence"
ha_release: 2026.6
ha_category: Sensor
ha_platforms:
- sensor
ha_iot_class: "Local Polling"
ha_quality_scale: silver
ha_config_flow: true
ha_codeowners:
- '@balloob'
ha_domain: awesome
ha_integration_type: hub
related:
- docs: /voice_control/s3_box_voice_assistant/
title: Creating a ESP32-S3-BOX-3 voice assistant
- url: https://esphome.io/projects/index.html
title: ESPHome projects website
---
Content... Written in markdown.
### Title header
...
The following keys are available for the integration page file header:
description: A short description of the integration page.featured: Set totrueto feature the integration prominently on the integrations page. This is not anha_-prefixed key. Don't use this.ha_bluetooth: Set totrueif the integration supports discovery via Bluetooth, omit otherwise.ha_category: This entry is used to group the integration on the Integration overview.ha_codeowners: GitHub usernames or team names (starting with@) of people that are responsible for this integration. This should match with the codeowners as listed in the integration manifest file.ha_config_flow: Set totrueif the integration has a Data Entry Flow, omit otherwise.ha_dhcp: Set totrueif the integration supports discovery via DHCP, omit otherwise.ha_domain: The domain of the integration in Home Assistant Core. This must match the name from the integration manifest file.ha_integration_type: The type of integration in Home Assistant Core. This must match the name from the integration manifest file.ha_iot_class: IoT class is the classifier for the device's behavior.ha_platforms: This entry lists all implemented platforms.ha_quality_scale: The integration's rating on the quality scale (such as bronze, silver, gold, platinum, or internal). For new integrations, set this tobronze. This field is automatically updated when the integration's quality level changes in Core. You don't need to update this manually in the documentation.ha_release: The Home Assistant release when the integration was included.- If the current release is 2025.8, make
ha_release2025.9. - For the October release, as in '2025.10', quote it with
' ', otherwise the zero won't be displayed.
- If the current release is 2025.8, make
ha_ssdp: Set totrueif the integration supports discovery via SSDP, omit otherwise.ha_zeroconf: Set totrueif the integration supports discovery via mDNS/Zeroconf, omit otherwise.related: Optional. Adds a section with links to related topics to the end of the page. Usedocsfor local links andurlfor external links. When usingdocs, thetitlekey is optional. If not set, the title of the page you point to will be used.title: This title should match with the name of the integration as written in the integration manifest file.
Configuration
Every integration page should contain a configuration example. This includes UI variable descriptions for integrations with a configuration flow, and YAML configuration for integrations that don't yet support a configuration flow.
UI variables
- For describing UI variables use the
{% configuration_basic %}section. - The
{% configuration_basic %}block is like the{% configuration %}block, but does not have therequiredortypefields.
About configuration variables
- The Configuration variables section is only used for YAML configuration.
- The Configuration variables section must use the
{% configuration %}tag. - Configuration variables must document the default value, if any.
- Configuration variables must document if the variable is required (
falseortrue). If the variable has a default value, then it is not required and therequiredfield should be set tofalse. - Configuration variables must document the accepted value types (see configuration variables details).
- For configuration variables that accept multiple types, separate the types with a comma (that is,
string, integer).
- For configuration variables that accept multiple types, separate the types with a comma (that is,
Example configuration variables block
{% configuration %}
some_key:
description: This is a description of what this key is for.
required: false
type: string
default: Optional default value - leave out if there isn't one
{% endconfiguration %}
{% configuration %}
api_key:
description: The API key to access the service.
required: true
type: string
name:
description: Name to use in the frontend.
required: false
default: The default name to use in the frontend.
type: string
monitored_conditions:
description: Conditions to display in the frontend.
required: true
type: map
keys:
weather:
description: A human-readable text summary.
temperature:
description: The current temperature.
{% endconfiguration %}
Available keys:
description:: That the variable is about.required:: If the variable is required.
required: true #=> Required
required: false #=> Optional
required: inclusive #=> Inclusive
required: exclusive #=> Exclusive
required: any string here #=> Any string here
type:: The type of the variable. Allowed entries:action,boolean,string,integer,float,time,template,device_class,icon,map/list(for a list of entries),date,datetime,timedelta,selector, andany. For multiple possibilities use[string, integer]. If you usemap/listthen you should definekeys:(see thetemplatesensor for an example). If you useboolean, thendefault:must be defined.
Embedding code
You can use the default markdown syntax to generate syntax highlighted code. For inline code wrap your code in back-ticks.
When you're writing code that is to be executed on the terminal, do not prefix them with $, since this makes it hard to copy and paste the commands. However, an exception is made when there is a need to distinguish between typed commands and command output. In those cases, prefixing the commands with a $ is required.
Templates
For the configuration templating Jinja is used. Check the Documentation Standards for further details.
If you don't escape templates then they will be rendered and appear blank on the website.
HTML
The direct usage of HTML is supported but not recommended. The note boxes are an exception.
<div class='note warning'>
You need to enable telnet on your router.
</div>
Please note, if you want to use Markdown inside an HTML block, it has to be surrounded by a new line.
<div class='note warning'>
You need to enable [**telnet**](https://en.wikipedia.org/wiki/Telnet) on your router.
</div>
Images, icons, and logos
Having a logo with the integration makes an integration quickly identifiable with the end-user. From the documentation side of things, no specific configuration is needed to enable the use of a logo, however, the logo must exist in our Brands repository.
-
To add a logo and icon for your integration, open up a pull request at: the Home Assistant Brands.
-
To add other images, displayed on the integration page or any other documentation page, store the image in the corresponding directory according to their purpose:
| Type | Location |
|---|---|
| blog | source/images/blog |
| screenshots | source/images/integrations/your-integration |
Linking from the sidebar
If you are adding a new page that requires linking from the sidebar, edit either: