{"id":41305539,"url":"https://github.com/lovelylain/hass_ingress","last_synced_at":"2026-04-02T18:15:59.273Z","repository":{"id":225610603,"uuid":"766376848","full_name":"lovelylain/hass_ingress","owner":"lovelylain","description":"Home Assistant ingress feature, add additional ingress panels to your Home Assistant frontend.","archived":false,"fork":false,"pushed_at":"2025-12-14T05:16:15.000Z","size":675,"stargazers_count":223,"open_issues_count":42,"forks_count":16,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-12-16T07:30:45.078Z","etag":null,"topics":["custom-component","home-assistant","ingress"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/lovelylain.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2024-03-03T04:53:18.000Z","updated_at":"2025-12-14T05:15:34.000Z","dependencies_parsed_at":"2024-05-18T16:31:01.915Z","dependency_job_id":"79439fc4-723e-4eaf-8841-25e654e8a6ee","html_url":"https://github.com/lovelylain/hass_ingress","commit_stats":null,"previous_names":["lovelylain/hass_ingress"],"tags_count":26,"template":false,"template_full_name":null,"purl":"pkg:github/lovelylain/hass_ingress","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lovelylain%2Fhass_ingress","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lovelylain%2Fhass_ingress/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lovelylain%2Fhass_ingress/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lovelylain%2Fhass_ingress/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lovelylain","download_url":"https://codeload.github.com/lovelylain/hass_ingress/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lovelylain%2Fhass_ingress/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28680623,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-23T04:33:33.518Z","status":"ssl_error","status_checked_at":"2026-01-23T04:33:30.433Z","response_time":59,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["custom-component","home-assistant","ingress"],"created_at":"2026-01-23T05:02:40.922Z","updated_at":"2026-04-02T18:15:59.249Z","avatar_url":"https://github.com/lovelylain.png","language":"Python","funding_links":["https://www.buymeacoffee.com/lovelylain"],"categories":["Python"],"sub_categories":[],"readme":"# hass_ingress\n\n![GitHub actions](https://github.com/lovelylain/hass_ingress/actions/workflows/validate.yaml/badge.svg)\n\n**💡 Tip:** If this project helps you, consider giving me a tip for the time I spent building this project:\n\n\u003ca href=\"https://www.buymeacoffee.com/lovelylain\" target=\"_blank\"\u003e\n  \u003cimg src=\"https://cdn.buymeacoffee.com/buttons/default-yellow.png\" alt=\"Buy Me A Coffee\" width=\"150px\"\u003e\n\u003c/a\u003e\n\nv1.2.4 Feature: [Multiple Tabs](#multiple-tabs) without reloading when switch tabs.\n\nv1.2.5 Feature: [Static Token](#static-token) public links that never expire.\n\nv1.3.0 Feature: [User Info](#user-info) support user info in headers.\n\nHass.io provides a very nice feature called [Hass.io Ingress](https://www.home-assistant.io/blog/2019/04/15/hassio-ingress/), `hass_ingress` extracts this feature into a standalone integration, it allows you to add additional ingress panels to your Home Assistant frontend. The panels are listed in the sidebar and can contain external resources like the web frontend of your router, your monitoring system, or your media server. Home Assistant will take care of the authentication and the secure connection, so users can access the external resources without extra login.\n\n![overview](images/overview.png)\n\n## Features\n\n- Ingress function similar to [Hass.io Ingress](https://www.home-assistant.io/blog/2019/04/15/hassio-ingress/). (option: `work_mode: ingress`)\n- Sidebar function similar to [Webpage dashboard](https://www.home-assistant.io/dashboards/dashboards/#webpage-dashboard). (option: `work_mode: iframe`)\n- Work with nginx auth_request for backend services can't be proxied by ingress. (option: `work_mode: auth`)\n- Support hassio add-on ingress. (option: `work_mode: hassio` `url: addonSlug`)\n- Add any HA page as a sidebar panel. (option: `ui_mode: replace`)\n- Hide header on ingress panel pages. (option: `ui_mode: normal`)\n- Show header on ingress panel pages. (option: `ui_mode: toolbar`)\n- Hide ingress panels from sidebar. (option: `parent: parent_panel`)\n- Additional http headers passed to the backend service, such as `authorization` and `host`, so that we can access the external resources without extra login. (option: `work_mode: ingress` `header: {map}`)\n- Embed in other pages. (url: `/api/ingress/{name}/`)\n- Passing url parameters. (url: `/{panel}?index={overwrite_index}`)\n- Reload Ingress configuration without restarting HA.\n- Toggle Home Assistant sidebar via swipe gestures(code from [hass-sidebar-swipe](https://github.com/breakthestatic/hass-sidebar-swipe)).\n- Support custom view and switch between iframes without reloading.\n\n## Installation\n\n### HACS\n\nUse this link to directly go to the repository in HACS\n\n[![Open your Home Assistant instance and open a repository inside the Home Assistant Community Store.](https://my.home-assistant.io/badges/hacs_repository.svg)](https://my.home-assistant.io/redirect/hacs_repository/?owner=lovelylain\u0026repository=hass_ingress)\n\n_or_\n\n1. Install HACS if you don't have it already\n1. Open HACS in Home Assistant\n1. ~~Add custom repository~~ https://github.com/lovelylain/hass_ingress\n1. Search for `Ingress` integration\n1. Click the download button ⬇️\n\n### Manual\n\n1. Download the [latest release](https://github.com/lovelylain/hass_ingress/releases/latest) and unzip.\n2. Put the `custom_components/ingress` folder into your `config/custom_components` folder.\n\n## Configuration\n\nTo enable Ingress panels in your installation, add the following to your `configuration.yaml` file, then restart HA:\n\n```yaml\ningress:\n  link_automation:\n    work_mode: iframe\n    ui_mode: replace\n    title: Automation\n    icon: mdi:link\n    url: /config/automation/dashboard\n  frigate:\n    ui_mode: toolbar\n    title: Frigate\n    icon: mdi:cctv\n    url: http://172.30.32.2:5000\n  nodered:\n    require_admin: true\n    title: Node-RED\n    icon: mdi:sitemap\n    url: http://127.0.0.1:45180\n    headers:\n      authorization: !secret nodered_auth\n  nodered_ui:\n    parent: nodered\n    title: Node-RED Dashboard\n    icon: mdi:monitor-dashboard\n    url: http://127.0.0.1:45180\n    index: /ui/\n    headers:\n      authorization: !secret nodered_auth\n  openwrt:\n    title: OpenWrt\n    icon: mdi:router-wireless-settings\n    url: http://192.168.0.1/\n    headers:\n      # auto login for openwrt ingress\n      http-auth-user: !secret openwrt_user\n      http-auth-pass: !secret openwrt_auth\n    # \"fix\" absolute URLs by rewriting the response body\n    rewrite:\n      # for HTML response\n      - mode: body\n        match: /(luci-static|cgi-bin)/\n        replace: $http_x_ingress_path/\\1/\n      # for JS init code\n      - mode: body\n        match: \\\\/(luci-static|cgi-bin|ubus)\\\\/\n        replace: $http_x_ingress_path\\/\\1\\/\n      # for login response\n      - mode: header\n        name: \"(Location|Set-Cookie)\"\n        match: /cgi-bin/\n        replace: $http_x_ingress_path/cgi-bin/\n```\n\nAfter you modify the Ingress configuration, you can go to `developer-tools` page and click `INGRESS` to reload without restarting HA.\n\n![reload](images/reload.png)\n\n## Configuration variables\n\n- **ingress**: map (REQUIRED) Enables the hass_ingress integration. Only allowed once.\n  - **panel_name**: map (REQUIRED) Name of the panel. Only allowed once.\n    - **title**: string (REQUIRED) Friendly title for the panel. Will be used in the sidebar.\n    - **icon**: [icon](https://www.home-assistant.io/docs/configuration/customizing-devices/#icon) (optional) Icon for entry.\n    - **require_admin**: boolean (optional, default: false) If admin access is required to see this iframe.\n    - **work_mode**: string (oneof `ingress` `subapp` `iframe` `auth` `hassio` `custom`, default: ingress)\n      - ingress: Ingress function similar to [Hass.io Ingress](https://www.home-assistant.io/blog/2019/04/15/hassio-ingress/).\n      - iframe: Sidebar function similar to [Webpage dashboard](https://www.home-assistant.io/dashboards/dashboards/#webpage-dashboard).\n      - auth: Work with nginx auth_request for backend services can't be proxied by ingress.\n        ```ini\n        auth_request api: /api/ingress/_/auth\n        request header: X-Ingress-Name(ingress_name), X-Original-URL($scheme://$http_host$request_uri), X-Hass-Origin(hass_url)\n        response header: Set-Cookie(ingress_token) if succ, Location(login_url_path) if 401.\n        ```\n      - hassio: Support hassio add-on ingress, in this case set url with add-on slug, for example `url: a0d7b954_grafana`. This mode does not enable add-ons that do not support ingress to support ingress, it only provides some personalized functions for the ingress sidebar, such as customizing the sidebar title and hiding the header.\n    - **ui_mode**: string (oneof `replace` `normal` `toolbar`, default: normal)\n      - replace: Redirect to the target url, useful when adding an HA page as a sidebar panel.\n      - normal: No header on ingress panel pages.\n      - toolbar: Show header on ingress panel pages.\n    - **url**: string (REQUIRED) The absolute URL or relative URL with an absolute path to open.\n      If you want to use multiple front-end domains for `iframe` and `auth` mode, you can enable the extended configuration for the `url` option:\n      ```yaml\n      url:\n        match: JS regular expression to match scheme://host[:port].\n        replace: JS regular replacement to build real url.\n        default: Default url when regular expression does not match.\n      ```\n      For example, you use http://hass.web.local to access HA from the internal network, and https://hass.example.com from the external, you want to use http://openwrt.web.local to access auth mode openwrt from the internal, and https://openwrt.example.com from the external. You can set `match: (\\w+://)hass(\\..+)`, `replace: $1openwrt$2`, `default: https://openwrt.example.com` to achieve your goal.\n    - **index**: string (optional, default empty) The relative URL of index page. If the `url` is http://127.0.0.1:45180/ui/, all access must be under the /ui/ path; if the `url` is http://127.0.0.1:45180 and the `index` is /ui/, all paths of http://127.0.0.1:45180 can be accessed.\n    - **parent**: string (optional, default empty) Parent ingress panel name. If non-empty, this panel will be hidden from the HA sidebar and you can access it via the `/{parent panel_name}/{child panel_name}` link. For example, the parent panel `nodered`, the sub-panel `ui` or `nodered_ui`, you can access the sub-panel through `/nodered/ui`.\n    - **headers**: map (optional) Additional http headers passed to the backend service, such as `authorization` for `basic auth`.\n    - **rewrite**: list (optional) List of response body/header rewrite rules:\n      - **mode**: string (REQUIRED, oneof `body` `header`) Whether to rewrite response body or headers.\n      - **path**: string (optional) URL prefix to apply this rule to, uses RegEx. E.g. `/.*` for everything.\n      - **name**: string (optional, only with `header`) Header whole name to match, uses RegEx.\n      - **match**: string (REQUIRED) RegEx pattern to search in body or header value.\n      - **replace**: string (REQUIRED) Python Replacement for the matched RegEx, use `\\1`, `\\2` to reference capture groups. `$http_x_ingress_path` in this option will be replaced with `/api/ingress/{name}`.\n    - **expire_time**: integer (optional, default: 3600) Hass ingress generates a token for each panel, which is used to access the panel. This option is used to specify the token validity period.\n    - **cookie_name**: string (optional, default: ingress_token) Hass ingress uses cookies to pass tokens, if the cookie name conflicts with the backend service, you can use other value through this option.\n    - **static_token**: string (optional, default empty) You provide the token instead of dynamically generating one, so you can obtain access links (`/api/ingress/t-{static_token}/`) that never expire. For example set static_token=`a-secret-token-value`, you can access the backend service without login HA through `/api/ingress/t-a-secret-token-value/`.\n\n_Notice: Not all backend services can be proxied by ingress, it must use relative paths or use `X-Ingress-Path` http header to generate correct absolute paths. For unsupported backend services, you can try `work_mode: auth` to work with another domain reverse proxied by nginx, or use nginx's sub_filter to fix the absolute paths in the response._\n\n_Another option is to use body rewrite rules, see the OpenWrt example above._\n\n## Multiple Tabs\n\nWith the following configuration, you can display web pages in multiple tabs without reloading the iframe when switching tabs.\n\n![tabs](images/tabs.png)\n\n```yaml\ningress:\n  tabs:\n    work_mode: custom # MUST\n    url: /files/ingress/ha-tabs-ingress.js # MUST\n    title: Ingress\n    icon: mdi:cursor-default-click\n  ttyd:\n    parent: tabs\n    work_mode: ingress\n    title: Terminal\n    url:\n  nodered:\n    parent: tabs\n    work_mode: hassio\n    title: Node-RED\n    url:\n```\n\nYou can directly visit tabs mode nodered through `/tabs/_/nodered`, or dashboard mode through `/tabs/nodered`.\n\n## Static Token\n\nWith static token feature, you can access the backend service without login HA through `/api/ingress/t-{static_token}/`.\n\n```yaml\ningress:\n  ttyd: # you can access ttyd with /api/ingress/t-secret-token-value-for-ttyd/ without login.\n    work_mode: ingress\n    title: Terminal\n    url:\n    static_token: secret-token-value-for-ttyd\n  nodered_webhook: # you can access ttyd with /api/ingress/t-secret-token-value-for-nodered_webhook/ without login.\n    parent: nodered\n    work_mode: ingress\n    url:\n    static_token: secret-token-value-for-nodered_webhook\n```\n\n## User Info\n\nStarting from v1.3.0, the token generation method has been changed to be associated with the user rather than the application, and user information can be used in headers.\n\n```yaml\ningress:\n  foobar:\n    headers:\n      # $user_id is user.id\n      # $user_name is Name of user\n      # $username is user login name\n      Remote-User: $username\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flovelylain%2Fhass_ingress","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flovelylain%2Fhass_ingress","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flovelylain%2Fhass_ingress/lists"}