Modernize sidebar menu and consolidate content (#1619)

* Modernize sidebar menu

* Move more architecture things over

* Move APIs to their application docs

* Clean up some titles and de-duplicate

* Consolidate repair platform and issue registry

* More moving

* Address comments

* Move API down
This commit is contained in:
Paulus Schoutsen 2023-01-09 13:44:44 -05:00 committed by GitHub
parent cae42c9fe3
commit 0c8a7b6048
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 313 additions and 336 deletions

View File

@ -1,6 +1,5 @@
---
title: "Architecture"
sidebar_label: "Introduction"
title: "Architecture Overview"
---
Home Assistant provides a platform for home control and home automation. Home Assistant is not just an application: it's an embedded system that provides an experience like other consumer off-the-shelf products: onboarding, configuration and updating is all done via an easy to use interface.

View File

@ -1,6 +1,6 @@
---
title: Integration Configuration
sidebar_label: Configuration
title: Integration Config Entry
sidebar_label: Config Entry
---
Integrations can be set up via the user interface by adding support for a config flow to create a config entry. Components that want to support config entries will need to define a Config Flow Handler. This handler will manage the creation of entries from user input, discovery or other sources (like Home Assistant OS).

View File

@ -2,13 +2,41 @@
title: "Repairs"
---
A fixable [repairs issue](/docs/issue_registry_index) may optionally be repaired by a custom repairs flow.
Home Assistant keeps track of issues which should be brought to the user's attention. These issues can be created by integrations or by Home Assistant itself. Issues can either be fixable via a RepairsFlow or by linking to a website with information on how the user can solve it themselves.
This is done by adding the function (`async_create_fix_flow`) to `repairs.py`
## Creating an issue
## Adding support
```python
from homeassistant.helpers import issue_registry as ir
Create a new file in your integration folder called `repairs.py` and add code according to the pattern below.
ir.async_create_issue(
hass,
DOMAIN,
"manual_migration",
breaks_in_ha_version="2022.9.0",
is_fixable=False,
severity=IssueSeverity.ERROR,
translation_key="manual_migration",
)
```
| Attribute | Type | Default | Description |
| --------- | -------- | ------- | ----------- |
| domain | string | | Domain raising the issue
| issue_id | string | | An identifier for the issue, must be unique within `domain`
| breaks_in_ha_version | string | `None` | The version in which the issue is breaking
| data | dict | `None` | Arbitrary data, not shown to the user
| is_fixable | boolean | | True if the issue can be automatically fixed
| is_persistent | boolean | | True if the issue should persists across restarts of Home Assistant
| issue_domain | string | `None` | Set by integrations creating issues on behalf of other integrations
| learn_more_url | string | `None` | URL where the user can find more details about an issue
| severity | IssueSeverity | | Severity of the issue
| translation_key | str | | Translation key with a brief explanation of the issue
| translation_placeholders | dict | `None` | Placeholders which will be injected in the translation
## Offering a repair
Create a new platform file in your integration folder called `repairs.py` and add code according to the pattern below.
```python
@ -50,3 +78,32 @@ async def async_create_fix_flow(
if issue_id == "issue_1":
return Issue1RepairFlow()
```
## Issue life cycle
### Issue persistence
An issue will be kept in the issue registry until it's removed by the integration that created it or by the user [fixing](#fixing-an-issue) it.
The `is_persistent` flag controls if an issue should be shown to the user after a restart of Home Assistant:
- If the `is_persistent` flag is set on the issue, the issue will be shown again to the user after a restart. Use this for issues that can only be detected when they occur (update failed, unknown service in automation).
- If the `is_persistent` flag is not set on the issue, the issue will not be shown again to the user after a restart until it's created again by its integration. Use this for issues that can be checked for, like low disk space.
### Ignored issues
It's possible for the user to "ignore" issues. An ignored issue is ignored until it's explicitly deleted - either by the integration or by the user successfully walking through its [repair flow](#fixing-an-issue) - and then created again. Ignoring an issue takes effect across restarts of Home Assistant regardless of [issue persistence](#issue-persistence).
## Deleting an issue
Integrations typically don't need to delete issues, but it may be useful in some cases.
```python
from homeassistant.helpers import issue_registry as ir
ir.async_delete_issue(hass, DOMAIN, "manual_migration")
```
## Fixing an issue
If an issue has the `is_fixable` issue set to `True`, the user will be allowed to fix the issue. An issue which is succesfully fixed will be removed from the issue registry.

View File

@ -4,7 +4,7 @@ title: Data Entry Flow
Data Entry Flow is a data entry framework that is part of Home Assistant. Data entry is done via data entry flows. A flow can represent a simple login form or a multi-step setup wizard for a component. A Flow Manager manages all flows that are in progress and handles creation of new flows.
Data Entry Flow is used in Home Assistant to create config entries.
Data Entry Flow is used in Home Assistant to login, create config entries, handle options flow, repair issues.
## Flow Manager

View File

@ -1,28 +1,32 @@
---
title: "Using Config"
title: "Config"
---
Based on where you are in the code, `config` can mean various things.
On [the hass object](./dev_101_hass.md) there is an instance of the Config class. The Config class contains the users preferred units, the path to the config directory and which components are loaded.
### On the hass object
| Name | Type | Description |
| ---- | ---- | ----------- |
| latitude | float | Latitude of the instance location |
| longitude | float | Longitude of the instance location |
| elevation | int | Elevation of the instance |
| location_name | str | Name of the instance |
| time_zone | str | Timezone |
| units | UnitSystem | Unit system |
| internal_url | str | URL the instance can be reached on internally |
| external_url | str | URL the instance can be reached on externally |
| currency | str | Preferred currency |
| country | str | Country the instance is in |
| language | str | Preferred language |
| config_source | ConfigSource | If the configuration was set via the UI or stored in YAML |
| skip_pip | bool | If True, pip install is skipped for requirements on startup |
| skip_pip_packages | list[str] | List of packages to skip when installing requirements on startup |
| components | set[str] | List of loaded components |
| api | ApiConfig | API (HTTP) server configuration |
| config_dir | str | Directory that holds the configuration |
| allowlist_external_dirs | set[str] | List of allowed external dirs to access |
| allowlist_external_urls | set[str] | List of allowed external URLs that integrations may use |
| media_dirs | dict[str, str] | Dictionary of Media folders that integrations may use |
| safe_mode | bool | If Home Assistant is running in safe mode |
| legacy_templates | bool | Use legacy template behavior |
On the hass object it is an instance of the Config class. The Config class contains the users preferred units, the path to the config directory and which components are loaded. [See available methods.](https://dev-docs.home-assistant.io/en/dev/api/core.html#homeassistant.core.Config)
### Config passed into component setup
The `config` parameter passed to a component setup is a dictionary containing all of the user supplied configuration. The keys of the dictionary are the component names and the value is another dictionary with the component configuration.
The object will have already been validated using your `CONFIG_SCHEMA` or `PLATFORM_SCHEMA` if available. If you have defined a `PLATFORM_SCHEMA`, all references to your component (ie `light 2:` etc) will have been changed to be accessible as a list under `config[DOMAIN]`.
If your configuration file contains the following lines:
```yaml
example:
host: paulusschoutsen.nl
```
Then in the setup method of your component you will be able to refer to `config['example']['host']` to get the value `paulusschoutsen.nl`.
### Passed into platform setup
The `config` parameter passed to a platform setup function is only the config for that specific platform.
It also provides some helper methods. [See available methods.](https://dev-docs.home-assistant.io/en/dev/api/core.html#homeassistant.core.Config)

View File

@ -1,5 +1,5 @@
---
title: "Using Events"
title: "Events"
---
The core of Home Assistant is driven by events. That means that if you want to respond to something happening, you'll have to respond to events. Most of the times you won't interact directly with the event system but use one of the [event listener helpers][helpers].

View File

@ -1,5 +1,5 @@
---
title: "Using States"
title: "States"
---
Home Assistant keeps track of the states of entities in a state machine. The state machine has very few requirements:

View File

@ -1,10 +1,10 @@
---
title: "Starting with Development"
title: "Home Assistant Core"
sidebar_label: Introduction
---
Home Assistant is built from the ground up to be easily extensible using integrations. In this section, we're focusing on how to develop integrations.
The core of Home Assistant is built from the ground up to be easily extensible using integrations. In this section, we're focusing on how to develop integrations.
Before you start, make sure that you have read up on the [Home Assistant architecture](architecture_index.md) so that you are familiar with the concepts that make up Home Assistant.
Before you start, make sure that you have read up on the overall [Home Assistant architecture](architecture_index.md) so that you are familiar with the concepts that make up Home Assistant.
If you run into trouble following this documentation, don't hesitate to join our #devs_core channel on [Discord](https://www.home-assistant.io/join-chat/).

View File

@ -1,68 +0,0 @@
---
title: Repairs Issue Registry
---
The repairs issue registry is a registry where Home Assistant keeps track of repairs issues which should be brought to the user's attention.
## Issue properties
| Attribute | Type | Default | Description |
| --------- | -------- | ------- | ----------- |
| domain | string | | Domain raising the issue
| issue_id | string | | An identifier for the issue, must be unique within `domain`
| breaks_in_ha_version | string | `None` | The version in which the issue is breaking
| data | dict | `None` | Arbitrary data, not shown to the user
| is_fixable | boolean | | True if the issue can be automatically fixed
| is_persistent | boolean | | True if the issue should persists across restarts of Home Assistant
| issue_domain | string | `None` | Set by integrations creating issues on behalf of other integrations
| learn_more_url | string | `None` | URL where the user can find more details about an issue
| severity | IssueSeverity | | Severity of the issue
| translation_key | str | | Translation key with a brief explanation of the issue
| translation_placeholders | dict | `None` | Placeholders which will be injected in the translation
## Creating an issue
```python
from homeassistant.helpers import issue_registry as ir
ir.async_create_issue(
hass,
DOMAIN,
"manual_migration",
breaks_in_ha_version="2022.9.0",
is_fixable=False,
severity=IssueSeverity.ERROR,
translation_key="manual_migration",
)
```
## Issue life cycle
### Issue persistence
An issue will be kept in the issue registry until it's removed by the integration that created it or by the user [fixing](#fixing-an-issue) it.
The `is_persistent` flag controls if an issue should be shown to the user after a restart of Home Assistant:
- If the `is_persistent` flag is set on the issue, the issue will be shown again to the user after a restart. Use this for issues that can only be detected when they occur (update failed, unknown service in automation).
- If the `is_persistent` flag is not set on the issue, the issue will not be shown again to the user after a restart until it's created again by its integration. Use this for issues that can be checked for, like low disk space.
### Ignored issues
It's possible for the user to "ignore" issues. An ignored issue is ignored until it's explicitly deleted - either by the integration or by the user successfully walking through its [repair flow](#fixing-an-issue) - and then created again. Ignoring an issue takes effect across restarts of Home Assistant regardless of [issue persistence](#issue-persistence).
## Deleting an issue
Integrations typically don't need to delete issues, but it may be useful in some cases.
```python
from homeassistant.helpers import issue_registry as ir
ir.async_delete_issue(hass, DOMAIN, "manual_migration")
```
## Fixing an issue
If an issue has the `is_fixable` issue set to `True`, the user will be allowed to fix the issue. An issue which is succesfully fixed will be removed from the issue registry.
If the integration can perform some steps to fix an issue or to verify that the user has made the necessary manual steps, it should implement a [`repairs` platform](/docs/core/platform/repairs.md).
In some cases, fixing an issue may be done by the user by performing some manual steps which can't be verified by the integration, and no repairs platform is needed.

View File

@ -1,45 +0,0 @@
---
title: "Maintenance"
---
This page documents a couple of points for maintaining the Home Assistant code. Most of the tasks don't need to be performed on a regular basis thus the steps, used tools, or details are preserved here.
## Source code
### Line separator
People are using various operating systems to develop components and platforms for Home Assistant. This could lead to different line endings in files. We prefer `LN`. Especially Microsoft Windows tools tend to use `CRLF`.
```shell
$ find homeassistant -name "*.py" -exec file {} \; | grep BOM
$ find homeassistant -name "*.py" -exec file {} \; | grep CRLF
```
To fix the line separator, use `dos2unix` or `sed`.
```shell
$ dos2unix homeassistant/components/notify/kodi.py
```
### File permissions
Most files don't need to be executable. `0644` is fine.
### Dependencies
A lot of components and platforms depend on third-party Python modules. The dependencies which are stored in the `requirements_all.txt` files can be tracked with [`pur`](https://pypi.org/project/pur/) or [`pip-upgrader`](https://github.com/simion/pip-upgrader).
If you update the requirements of a component/platform by updating `manifest.json`, run the provided script to update the `requirements_*.txt` file(s).
```shell
$ script/gen_requirements_all.py
```
Start a test run of Home Assistant. If that was successful, include all files in a Pull Request. Add a short summary of the changes, a sample configuration entry, details about the tests you performed to ensure the update works, and other useful information to the description.
## Documentation
- Merge `current` into `next` on a regular basis.
- Optimize the images.

View File

@ -20,7 +20,7 @@ module.exports = {
position: "left",
items: [
{
label: "Architecture",
label: "Overview",
to: "docs/architecture_index",
},
{
@ -31,7 +31,6 @@ module.exports = {
{ to: "docs/supervisor", label: "Supervisor" },
{ to: "docs/add-ons", label: "Add-ons" },
{ to: "docs/operating-system", label: "Operating System" },
{ to: "docs/internationalization", label: "Internationalization" },
],
},
{
@ -40,7 +39,10 @@ module.exports = {
items: [
{ label: "Getting Started", to: "docs/documenting" },
{ label: "Standards", to: "docs/documenting/standards" },
{ label: "YAML Style Guide", to: "docs/documenting/yaml-style-guide" },
{
label: "YAML Style Guide",
to: "docs/documenting/yaml-style-guide",
},
{
label: "Create a new page",
to: "docs/documenting/create-page",
@ -48,19 +50,6 @@ module.exports = {
],
},
{ label: "Translations", to: "docs/translations", position: "left" },
{
label: "API",
position: "left",
items: [
{ label: "REST API", to: "docs/api/rest" },
{ label: "WebSocket API", to: "docs/api/websocket" },
{ label: "Supervisor API", to: "docs/api/supervisor/endpoints" },
{
label: "Native App Integration",
to: "docs/api/native-app-integration",
},
],
},
{ to: "docs/misc", label: "Misc", position: "left" },
{ to: "blog", label: "Blog", position: "left" },
],

View File

@ -17,31 +17,7 @@ module.exports = {
"add-ons/repository",
"add-ons/security",
],
API: [
"api/rest",
"api/websocket",
{
type: "category",
label: "Supervisor API",
items: [
"api/supervisor/endpoints",
"api/supervisor/models",
"api/supervisor/examples",
],
},
{
type: "category",
label: "Native App Integration",
items: [
"api/native-app-integration",
"api/native-app-integration/setup",
"api/native-app-integration/sending-data",
"api/native-app-integration/sensors",
"api/native-app-integration/notifications",
"api/native-app-integration/webview",
],
},
],
Overview: ["architecture_index"],
Documenting: [
"documenting",
"documenting/standards",
@ -90,118 +66,182 @@ module.exports = {
"operating-system/board-metadata",
"operating-system/deployment",
],
Supervisor: ["supervisor", "supervisor/development", "supervisor/debugging"],
// Old structure, still to move/migrate
Architecture: {
Architecture: [
"architecture_index",
"architecture/core",
"architecture_components",
],
Authentication: [
"auth_index",
"auth_permissions",
"auth_api",
"auth_auth_provider",
"auth_auth_module",
],
Configuration: ["config_entries_index", "data_entry_flow_index"],
"Integrating devices & services": [
"architecture/devices-and-services",
"entity_registry_index",
"entity_registry_disabled_by",
"device_registry_index",
"area_registry_index",
],
},
Core: {
"Development Workflow": [
"development_index",
"development_environment",
"development_submitting",
"development_guidelines",
"development_testing",
"development_catching_up",
"development_tips",
],
"Building Integrations": [
"creating_component_index",
"creating_integration_file_structure",
"creating_integration_brand",
"creating_integration_manifest",
"config_entries_config_flow_handler",
"config_entries_options_flow_handler",
"configuration_yaml_index",
"dev_101_services",
"creating_platform_index",
"creating_component_generic_discovery",
"integration_fetching_data",
"integration_setup_failures",
"integration_events",
"integration_listen_events",
"network_discovery",
"bluetooth",
],
"Development Checklist": [
"development_checklist",
"creating_component_code_review",
"creating_platform_code_review",
"integration_quality_scale_index",
],
"Accessing the Core": [
"dev_101_hass",
"dev_101_events",
"dev_101_states",
"dev_101_config",
],
Entities: [
"core/entity",
{
type: "autogenerated",
dirName: "core/entity",
},
],
Platforms: [
{
type: "autogenerated",
dirName: "core/platform",
},
],
Registries: [
"area_registry_index",
"device_registry_index",
"entity_registry_index",
"entity_registry_disabled_by",
"issue_registry_index",
],
"Device Automations": [
"device_automation_index",
"device_automation_trigger",
"device_automation_condition",
"device_automation_action",
],
Intents: [
"intent_index",
"intent_firing",
"intent_handling",
"intent_builtin",
"intent_conversation_api",
],
Misc: ["development_validation", "development_typing", "instance_url"],
},
Misc: {
Introduction: ["misc"],
"Building a Python library": [
"api_lib_index",
"api_lib_auth",
"api_lib_data_models",
],
asyncio: [
"asyncio_index",
"asyncio_101",
"asyncio_categorizing_functions",
"asyncio_working_with_async",
],
"Maintainer docs": ["maintenance"],
},
Supervisor: [
"supervisor",
"supervisor/development",
"supervisor/debugging",
{
type: "category",
label: "Supervisor API",
items: [
"api/supervisor/endpoints",
"api/supervisor/models",
"api/supervisor/examples",
],
},
],
Core: [
"development_index",
{
type: "category",
label: "Architecture",
items: ["architecture/core", "architecture_components"],
},
{
type: "category",
label: "Development Workflow",
items: [
"development_environment",
"development_submitting",
"development_guidelines",
"development_testing",
"development_catching_up",
"development_tips",
],
},
{
type: "category",
label: "Building Integrations",
items: [
"creating_component_index",
"creating_integration_file_structure",
"creating_integration_brand",
"creating_integration_manifest",
"config_entries_config_flow_handler",
"config_entries_options_flow_handler",
"configuration_yaml_index",
"dev_101_services",
"creating_platform_index",
"creating_component_generic_discovery",
"integration_fetching_data",
"integration_setup_failures",
"integration_events",
"integration_listen_events",
"network_discovery",
"bluetooth",
],
},
{
type: "category",
label: "Development Checklist",
items: [
"development_checklist",
"creating_component_code_review",
"creating_platform_code_review",
"integration_quality_scale_index",
],
},
{
type: "category",
label: "The `hass` object",
items: [
"dev_101_hass",
"dev_101_events",
"dev_101_states",
"dev_101_config",
],
},
{
type: "category",
label: "Entities",
items: [
"core/entity",
{
type: "autogenerated",
dirName: "core/entity",
},
],
},
{
type: "category",
label: "Areas, Devices and Entities",
items: [
"architecture/devices-and-services",
"entity_registry_index",
"entity_registry_disabled_by",
"device_registry_index",
"area_registry_index",
],
},
{
type: "category",
label: "Authentication",
items: [
"auth_index",
"auth_permissions",
"auth_api",
"auth_auth_provider",
"auth_auth_module",
],
},
"config_entries_index",
"data_entry_flow_index",
{
type: "category",
label: "Device Automations",
items: [
"device_automation_index",
"device_automation_trigger",
"device_automation_condition",
"device_automation_action",
],
},
{
type: "category",
label: "Intents",
items: [
"intent_index",
"intent_firing",
"intent_handling",
"intent_builtin",
"intent_conversation_api",
],
},
{
type: "category",
label: "Native App Integration",
items: [
"api/native-app-integration",
"api/native-app-integration/setup",
"api/native-app-integration/sending-data",
"api/native-app-integration/sensors",
"api/native-app-integration/notifications",
"api/native-app-integration/webview",
],
},
"core/platform/application_credentials",
"core/platform/backup",
"core/platform/repairs",
"core/platform/reproduce_state",
"core/platform/significant_change",
{
type: "category",
label: "External APIs",
items: ["api/websocket", "api/rest"],
},
{
type: "category",
label: "Misc",
items: ["development_validation", "development_typing", "instance_url"],
},
],
Misc: [
"misc",
{
type: "category",
label: "Building a Python library",
items: ["api_lib_index", "api_lib_auth", "api_lib_data_models"],
},
{
type: "category",
label: "asyncio",
items: [
"asyncio_index",
"asyncio_101",
"asyncio_categorizing_functions",
"asyncio_working_with_async",
],
},
],
};

View File

@ -1,7 +1,7 @@
import React from "react";
import clsx from 'clsx';
import clsx from "clsx";
import Layout from "@theme/Layout";
import BrowserOnly from '@docusaurus/BrowserOnly';
import BrowserOnly from "@docusaurus/BrowserOnly";
import useDocusaurusContext from "@docusaurus/useDocusaurusContext";
import useBaseUrl from "@docusaurus/useBaseUrl";
import styles from "./styles.module.css";
@ -15,29 +15,22 @@ const features = [
<>
<p>
<b>
<a href="docs/architecture_index">Architecture</a>.
<a href="docs/architecture_index">Overview</a>.
</b>{" "}
Explains various layers that make up Home Assistant.
</p>
<p>
<b>
<a href="docs/development_index">Core</a>.
</b>{" "}
Explains how to build new integrations for Home Assistant.
</p>
<p>
<b>
<a href="docs/frontend">Frontend</a>.
</b>{" "}
Explains how to develop the user interface of Home Assistant.
</p>
<p>
<b>
<a href="docs/development_index">Backend</a>.
</b>{" "}
Explains how to build new integrations for Home Assistant.
</p>
<p>
<b>
<a href="docs/misc">Misc</a>.
</b>{" "}
External APIs, Internationalization, asyncio, Home Assistant add-ons,
updating documentation.
</p>
</>
),
},
@ -54,10 +47,7 @@ const features = [
<a href="docs/internationalization">Translate Home Assistant</a>
</li>
<li>
<a href="docs/frontend">Improve the frontend</a>
</li>
<li>
<a href="docs/api/rest">Extract data from the Home Assistant API</a>
<a href="docs/api/websocket">Home Assistant API</a>
</li>
</ul>
<h3>Source Code</h3>
@ -89,7 +79,7 @@ const features = [
))}
</ul>
</>
)
),
},
{
title: <>Upcoming Events</>,
@ -101,17 +91,20 @@ const features = [
function UpcomingEvents() {
return (
<BrowserOnly>
{() => <iframe
{() => (
<iframe
title="Upcoming Events Calendar"
src={`https://calendar.google.com/calendar/embed?height=400&wkst=2&bgcolor=%23ffffff&ctz=${Intl.DateTimeFormat().resolvedOptions().timeZone || "UTC"}&src=cDA3bjk4Z28xMW9uYW1kMDhkMGttcTZqaHNAZ3JvdXAuY2FsZW5kYXIuZ29vZ2xlLmNvbQ&color=%23039BE5&title=Release%20Schedule&mode=AGENDA&showPrint=0&showTabs=0&showCalendars=0&showTz=1&showNav=0&showDate=0&showTitle=0`}
src={`https://calendar.google.com/calendar/embed?height=400&wkst=2&bgcolor=%23ffffff&ctz=${
Intl.DateTimeFormat().resolvedOptions().timeZone || "UTC"
}&src=cDA3bjk4Z28xMW9uYW1kMDhkMGttcTZqaHNAZ3JvdXAuY2FsZW5kYXIuZ29vZ2xlLmNvbQ&color=%23039BE5&title=Release%20Schedule&mode=AGENDA&showPrint=0&showTabs=0&showCalendars=0&showTz=1&showNav=0&showDate=0&showTitle=0`}
style={{ borderWidth: 0, margin: "auto" }}
width="300"
height="200"
frameBorder="0"
scrolling="no"
/>}
/>
)}
</BrowserOnly>
);
}
@ -142,14 +135,21 @@ function Home() {
<header className={clsx("hero hero--primary", styles.heroBanner)}>
<div className="container">
<div className="row">
<div className={clsx('col col--5')}>
<img className={styles.heroLogo} alt="Home Assistant Logo" src="/img/logo-white.svg" />
<div className={clsx("col col--5")}>
<img
className={styles.heroLogo}
alt="Home Assistant Logo"
src="/img/logo-white.svg"
/>
</div>
<div className={clsx('col col--5')}>
<div className={clsx("col col--5")}>
<h1 className={styles.heroTitle}>{siteConfig.title}</h1>
<p className={styles.heroTagline}>{siteConfig.tagline}</p>
<p>
<a className={styles.heroText} href="https://www.home-assistant.io">
<a
className={styles.heroText}
href="https://www.home-assistant.io"
>
Not a developer? Go to the normal website
</a>
</p>

View File

@ -10,6 +10,7 @@
/docs/app_integration_webview /docs/api/native-app-integration/webview
/docs/architecture_entities /docs/core/entity
/docs/architecture_hassio /docs/supervisor
/docs/dev_101_index /docs/dev_101_hass
/docs/documentation_create_page /docs/documenting/create-page
/docs/documentation_index /docs/documenting
/docs/documentation_standards /docs/documenting/standards
@ -59,11 +60,11 @@
/docs/internationalization_index /docs/internationalization
/docs/internationalization_translation /docs/translations
/docs/internationalization_translation.html /docs/translations
/docs/issue_registry_index /docs/platform/repairs
/docs/lovelace_custom_card /docs/frontend/custom-ui/lovelace-custom-card
/docs/supervisor/developing /docs/supervisor/development
/docs/dev_101_index /docs/dev_101_hass
/docs/reproduce_state_index /docs/core/platform/reproduce_state
/docs/significant_change_index /docs/core/platform/significant_change
/docs/supervisor/developing /docs/supervisor/development
# Tidying moved pages