Before you submit this support request, please ensure you have entered your configuration files and actually followed the steps from the troubleshooting guide linked above, if relevant. The troubleshooting steps often help to solve the problem.
Before you submit this support request, please ensure you have entered your configuration files and actually followed the steps from the troubleshooting guide linked above *and posted the output*, if relevant. The troubleshooting steps often help to solve the problem or at least can help figure it out.
*Please remember that this project is maintained by regular people **just like you**, so if you don't take the time to fill out the requested information, don't expect a reply back.*
@@ -35,6 +35,8 @@ What type of change does your PR introduce to Homepage?
## Checklist:
- [ ] If applicable, I have added corresponding documentation changes.
- [ ] If applicable, I have added or updated tests for new features and bug fixes.
- [ ] If applicable, I have reviewed the [feature / enhancement](https://gethomepage.dev/more/development/#new-feature-guidelines) and / or [service widget guidelines](https://gethomepage.dev/more/development/#service-widget-guidelines).
- [ ] I have checked that all code style checks pass using [pre-commit hooks](https://gethomepage.dev/more/development/#code-formatting-with-pre-commit-hooks) and [linting checks](https://gethomepage.dev/more/development/#code-linting).
- [ ] If applicable, I have tested my code for new features & regressions on both mobile & desktop devices, using the latest version of major browsers.
- [ ] In the description above I have disclosed the use of AI tools in the coding of this PR.
@@ -63,7 +63,7 @@ The homepage team appreciates all effort and interest from the community in fili
- Issues, pull requests and discussions that are closed will be locked after 30 days of inactivity.
- Discussions with a marked answer will be automatically closed.
- Discussions in the 'General' or 'Support' categories will be closed after 180 days of inactivity.
- Feature requests that do not meet the following thresholds will be closed: 10 "up-votes" after 180 days of inactivity or 20 "up-votes" after 365 days.
- Feature requests that do not meet the following thresholds will be closed: 20 "up-votes" after 180 days of inactivity or 40 "up-votes" after 365 days.
In all cases, threads can be re-opened by project maintainers and, of course, users can always create a new discussion for related concerns.
Finally, remember that all information remains searchable and 'closed' feature requests can still serve as inspiration for new features.
&& apk add --no-cache --virtual .gyp python3 make g++ \
&& npm install -g pnpm
RUN --mount=type=cache,id=pnpm-store,target=/root/.local/share/pnpm/store pnpm fetch | grep -v "cross-device link not permitted\|Falling back to copying packages from store"
RUN --mount=type=cache,id=pnpm-store,target=/root/.local/share/pnpm/store pnpm install -r --offline
<ahref="https://github.com/gethomepage/homepage/actions/workflows/docker-publish.yml"><imgalt="GitHub Workflow Status (with event)"src="https://img.shields.io/github/actions/workflow/status/gethomepage/homepage/docker-publish.yml"></a>
@@ -68,7 +70,7 @@ For configuration options, examples and more, [please check out the homepage doc
## Security Notice 🔒
Please note that when using features such as widgets, Homepage can access personal information (for example from your home automation system) and Homepage currently does not (and is not planned to) include any authentication layer itself. Thus, we recommend homepage be deployed behind a reverse proxy including authentication, SSL etc, and / or behind a VPN.
Please note that when using features such as widgets, Homepage can access personal information (for example from your home automation system) and Homepage currently does not (and is not planned to) include any authentication layer itself. If Homepage is reachable from any untrusted network, it **must** sit behind a reverse proxy (and/or VPN) that enforces authentication, TLS, and strictly validates Host headers. The built-in host check in Homepage is a best-effort guard and should not be treated as security when exposed publicly.
## With Docker
@@ -80,7 +82,7 @@ services:
image:ghcr.io/gethomepage/homepage:latest
container_name:homepage
environment:
HOMEPAGE_ALLOWED_HOSTS:gethomepage.dev# required, may need port
HOMEPAGE_ALLOWED_HOSTS:gethomepage.dev# required, may need port. See gethomepage.dev/installation/#homepage_allowed_hosts
PUID:1000# optional, your user id
PGID:1000# optional, your group id
ports:
@@ -154,16 +156,16 @@ This is a [Next.js](https://nextjs.org/) application, see their documentation fo
The homepage documentation is available at [https://gethomepage.dev/](https://gethomepage.dev/).
Homepage uses Material for MkDocs for documentation. To run the documentation locally, first install the dependencies:
Homepage uses Zensical for documentation. To run the documentation locally, first install the dependencies:
```bash
pip install -r requirements.txt
uv sync
```
Then run the development server:
```bash
mkdocs serve # or build, to build the static site
uv run zensical serve # or build, to build the static site
@@ -20,7 +20,7 @@ Since Docker supports connecting with TLS and client certificate authentication,
```yaml
my-remote-docker:
host:192.168.0.101
port:275
port:2375
tls:
keyFile:tls/key.pem
caFile:tls/ca.pem
@@ -66,6 +66,30 @@ my-docker:
port:2375
```
Use `protocol: https` if you’re connecting through a reverse proxy (e.g., Traefik) that serves the Docker API over HTTPS:
```yaml
my-docker:
host:dockerproxy
port:443
protocol:https
```
!!! note
Note: This does not require TLS certificates if the proxy handles encryption. Do not use `protocol: https` unless you’re sure the target host supports HTTPS.
You can also include `headers` for the connection, for example, if you are using a reverse proxy that requires authentication:
```yaml
my-docker:
host:dockerproxy
port:443
protocol:https
headers:
Authorization:Basic <base64-encoded-credentials>
```
## Using Socket Directly
If you'd rather use the socket directly, first make sure that you're passing the local socket into the Docker container.
@@ -165,6 +189,8 @@ labels: ...
- homepage.widgets[1].slug=youreventslughere
```
To pass custom HTTP headers with a widget request when using labels, use the same dot-notation: `homepage.widget.headers.X-Auth-Key=secret` (or `homepage.widgets[0].headers.X-Auth-Key=secret` when multiple widgets are present).
You can add specify fields for e.g. the [CustomAPI](../widgets/services/customapi.md) widget by using array-style dot notation:
```yaml
@@ -247,4 +273,4 @@ You can show the docker stats by clicking the status indicator but this can also
showStats:true
```
Also see the settings for [show docker stats](settings.md#show-docker-stats).
Also see the settings for [show docker stats](settings.md#show-container-stats).
@@ -163,6 +164,47 @@ If the `href` attribute is not present, Homepage will ignore the specific Ingres
Homepage also features automatic service discovery for Gateway API. Service definitions are read by annotating the HttpRoute custom resource definition and are indentical to the Ingress example as defined in [Automatic Service Discovery](#automatic-service-discovery).
To enable Gateway API HttpRoute update `kubernetes.yaml` to include:
```
gateway: true # enable gateway-api
```
#### Using the unoffocial helm chart?
If you are using the unofficial helm chart ensure that the `ClusterRole` has required permissions for `gateway.networking.k8s.io`.
See [ClusterRole and ClusterRoleBinding](../installation/k8s.md#clusterrole-and-clusterrolebinding)
## Caveats
Similarly to Docker service discovery, there currently is no rigid ordering to discovered services and discovered services will be displayed above those specified in the `services.yaml`.
## Adding extra configuration files
Some Homepage features (for example, [Proxmox](../configs/proxmox.md)) require additional configuration files such as `proxmox.yaml`.
When running Homepage on Kubernetes, these files must be provided via a `ConfigMap` and mounted into the container at `/app/config`.
### ConfigMap example
```yaml
apiVersion:v1
kind:ConfigMap
metadata:
name:homepage
data:
proxmox.yaml:|
pve:
url: https://proxmox.host.or.ip:8006
token: username@pam!Token ID
secret: secret
```
Mount the file into `/app/config` by updating the `Deployment`:
The Proxmox connection is configured in the `proxmox.yaml` file. See [Create token](#create-token) section below for details on how to generate the required API token.
To configure multiple nodes, ensure the key name in the `proxmox.yaml` matches the `proxmoxNode` field used in your service configuration.
```yaml
pve:# must match your actual Proxmox node name
url:https://proxmox.host.or.ip:8006
token:username@pam!Token ID
secret:secret
```
## Services
Once the Proxmox connection is configured, individual services can be configured to pull statistics of VMs or LXCs. Only CPU and Memory are currently supported.
### Configuration Options
-`proxmoxNode`: The name of the Proxmox node where your VM/LXC is running, must match with a node configured in the `proxmox.yaml`
-`proxmoxVMID`: The ID of the Proxmox VM or LXC container
-`proxmoxType`: (Optional) The type of Proxmox virtual machine. Defaults to `qemu` for VMs, but can be set to `lxc` for LXC containers
#### Examples
For a QEMU VM (default):
```yaml
- HomeAssistant:
icon:home-assistant.png
href:http://homeassistant.local/
description:Home automation
proxmoxNode:pve
proxmoxVMID:101
# proxmoxType: qemu # This is the default, so it can be omitted
```
For an LXC container:
```yaml
- Nginx:
icon:nginx.png
href:http://nginx.local/
description:Web server
proxmoxNode:pve
proxmoxVMID:200
proxmoxType:lxc
```
## Create token
You will need to generate an API Token for new or an existing user. Here is an example of how to do this for a new user.
1. Navigate to the Proxmox portal, click on Datacenter
2. Expand Permissions, click on Groups
3. Click the Create button
4. Name the group something informative, like api-ro-users
5. Click on the Permissions "folder"
6. Click Add -> Group Permission
- Path: /
- Group: group from bullet 4 above
- Role: PVEAuditor
- Propagate: Checked
7. Expand Permissions, click on Users
8. Click the Add button
- User name: something informative like `api`
- Realm: Linux PAM standard authentication
- Group: group from bullet 4 above
9. Expand Permissions, click on API Tokens
10. Click the Add button
- User: user from bullet 8 above
- Token ID: something informative like the application or purpose like `homepage`
- Privilege Separation: Checked
11. Go back to the "Permissions" menu
12. Click Add -> API Token Permission
- Path: /
- API Token: select the Token ID created in Step 10
@@ -101,6 +101,25 @@ Each service can have multiple widgets attached to it, for example:
Multiple widgets per service are not yet supported with Kubernetes ingress annotations.
#### Custom HTTP headers
Widgets that make HTTP calls support extra request headers via `headers`. This is useful when a reverse proxy expects a secret header.
```yaml
- UptimeRobot:
icon:uptimekuma.png
href:https://uptimerobot.com/
widget:
type:uptimerobot
url:https://api.uptimerobot.com
key:${UPTIMEROBOT_API_KEY}
headers:
User-Agent:homepage
X-Auth-Key:your-secret-here
```
If you define services via Docker labels or Kubernetes annotations, use the same key with dot-notation (for example `homepage.widget.headers.X-Auth-Key=secret` or `gethomepage.dev/widget.headers.X-Auth-Key: "secret"`).
#### Field Visibility
Each widget can optionally provide a list of which fields should be visible via the `fields` widget property. If no fields are specified, then all fields will be displayed. The `fields` property must be a valid YAML array of strings. As an example, here is the entry for Sonarr showing only a couple of fields.
@@ -118,6 +137,60 @@ Each widget can optionally provide a list of which fields should be visible via
key:apikeyapikeyapikeyapikeyapikey
```
### Block Highlighting
Widgets can tint their metric block text automatically based on rules defined alongside the service. Attach a `highlight` section to the widget configuration and map each block to one or more numeric or string rules using the field key (for example, `queued`, `lan_users`).
```yaml
- Sonarr:
icon:sonarr.png
href:http://sonarr.host.or.ip
widget:
type:sonarr
url:http://sonarr.host.or.ip
key:${SONARR_API_KEY}
highlight:
queued:
numeric:
- level:danger
when:gte
value:20
- level:warn
when:gte
value:5
- level:good
when:eq
value:0
status:
string:
- level:danger
when:regex
value:"(failed|import) pending"
- level:good
when:equals
value:"All good"
status_code:
string:
- level:warn
when:regex
value:"^5\\d{2}$"
```
Supported numeric operators for the `when` property are `gt`, `gte`, `lt`, `lte`, `eq`, `ne`, `between`, and `outside`. String rules support `equals`, `includes`, `startsWith`, `endsWith`, and `regex`. Each rule can be inverted with `negate: true`, and string rules may pass `caseSensitive: true` or custom regex `flags`. The highlight engine does its best to coerce formatted values, but you will get the most reliable results when you pass plain numbers or strings into `<Block>`.
#### Value Only Highlighting
You can optionally apply highlighting only to the value portion of a block (not the label) by setting `valueOnly: true` on the field configuration. This keeps the label visible while highlighting only the metric value itself.
You can apply a blur filter to the service & bookmark cards. Note this option is incompatible with the background blur, saturate and brightness filters.
```yaml
cardBlur:sm# sm, "", md, etc... see https://tailwindcss.com/docs/backdrop-blur
cardBlur:xs# xs, md, etc... see https://tailwindcss.com/docs/backdrop-blur
```
## Favicon
@@ -101,7 +101,7 @@ theme: dark # or light
## Color Palette
You can configured a fixed color palette (and disable the palette switcher) by passing the `color` option, like so:
You can configure a fixed color palette (and disable the palette switcher) by passing the `color` option, like so:
Any unspecified level falls back to the built-in defaults.
## Progressive Web App (PWA)
A progressive web app is an app that can be installed on a device and provide user experience like a native app. Homepage comes with built-in support for PWA with some default configurations, but you can customize them.
More information on PWAs can be found in [MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/Progressive_web_apps).
## App icons
You can set custom icons for installable apps. More information about how you can set them can be found in the [MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/Progressive_web_apps/Manifest/Reference/icons).
The default value is the Homepage icon in sizes 192x192 and 512x512.
For icon `src` you can pass either full URL or a local path relative to the `/app/public` directory. See [Background Image](#background-image) for more detailed information on how to provide your own files.
### Shortcuts
Shortcuts can e used to specify links to tabs, to be preselected when the homepage is opened as an app.
More information about how you can set them can be found in the [MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/Progressive_web_apps/Manifest/Reference/shortcuts).
```yaml
pwa:
shortcuts:
- name:First
url:"/#first"# opens the first tab
- name:Second
url:"/#second"# opens the second tab
- name:Third
url:"/#third"# opens the third tab
```
### Other PWA configurations
Homepage sets few other PWA configurations, that are based on global settings in `settings.yaml`:
-`name`, `short_name` - Both equal to the [`title`](#title) setting.
-`theme_color`, `background_color` - Both based on the [`color`](#color-palette) and [`theme`](#theme) settings.
-`display` - It is always set to "standalone".
-`start_url` - Equal to the [`startUrl`](#start-url) setting.
More information for wach of the PWA configurations can be found in the [MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/Progressive_web_apps/Manifest/Reference).
## Layout
You can configure service and bookmarks sections to be either "column" or "row" based layouts, like so:
@@ -254,15 +320,29 @@ layout:
columns:4
```
### Five Columns
### Full Width
You can add a fifth column to services (when `style: columns` which is default) by adding:
You can make homepage take up the entire window width by adding:
```yaml
fiveColumns:true
fullWidth:true
```
By default homepage will max out at 4 columns for services with `columns` style
### Maximum Group Columns
You can set the maximum number of columns of groups on larger screen sizes (note this is only for groups with the default `style: columns`, not groups with `style: row`) by adding:
```yaml
maxGroupColumns:8# default is 4 for services, 6 for bookmarks, max 8
```
By default homepage will max out at 4 columns for services and 6 for bookmarks, thus the minimum for this setting is _5_. Of course, if you're setting this to higher numbers, you may want to consider enabling the [fullWidth](#full-width) option as well.
If you want to set the maximum columns for bookmark groups separately, you can do so by adding:
```yaml
maxBookmarkGroupColumns:6# default is 6, max 8
```
### Collapsible sections
@@ -368,7 +448,9 @@ Set your desired language using:
language:fr
```
Currently supported languages: ca, de, en, es, fr, he, hr, hu, it, nb-NO, nl, pt, ru, sv, vi, zh-CN, zh-Hant
Currently supported languages: ca, de, en, es, fr, he, hr, hu, it, nb-NO, nl, pt, ru, sv, vi, zh-Hans (Simplified), zh-Hant (Traditional)
`zh-CN` will still work and is automatically mapped to `zh-Hans` for backwards compatibility.
You can also specify locales e.g. for the DateTime widget, e.g. en-AU, en-GB, etc.
@@ -427,6 +509,7 @@ There are a few optional settings for the Quick Launch feature:
-`showSearchSuggestions`: show search suggestions for the internet search. If this is not specified then the setting will be inherited from the search widget. If it is not specified there either, it will default to false. For custom providers the `suggestionUrl` needs to be set in order for this to work.
-`provider`: search engine provider. If none is specified it will try to use the provider set for the Search Widget, if neither are present then internet search will be disabled.
-`hideVisitURL`: disable detecting and offering an option to open URLs. This is false by default, enabling the feature.
-`mobileButtonPosition`: enables and sets the position of the mobile quicklaunch button. Options are `top-left`, `top-right`, `bottom-left`, `bottom-right`. This is empty by default, disabling the feature.
```yaml
quicklaunch:
@@ -471,9 +554,9 @@ logpath: /logfile/path
By default, logs are sent both to `stdout` and to a file at the path specified. This can be changed by setting the `LOG_TARGETS` environment variable to one of `both` (default), `stdout` or `file`.
## Show Docker Stats
## Show Container Stats
You can show all docker stats expanded in `settings.yaml`:
You can show all docker or proxmox stats expanded in `settings.yaml`:
```yaml
showStats:true
@@ -542,3 +625,18 @@ or per service widget (`services.yaml`) with:
```
If either value is set to true, the error message will be hidden.
## Disable Search Engine Indexing
You can request that search engines not to index your Homepage instance by enabling the `disableIndexing` setting.
```yaml
disableIndexing:true
```
When enabled, this will:
- Disallow all crawlers in `robots.txt`
- Add `<meta name="robots" content="noindex, nofollow">` tags to prevent indexing
:simple-docker: [ Install on Docker :octicons-arrow-right-24:](docker.md)
[:simple-docker: Install on Docker :octicons-arrow-right-24:](docker.md)
{ .card }
:simple-kubernetes: [ Install on Kubernetes :octicons-arrow-right-24:](k8s.md)
[:simple-kubernetes: Install on Kubernetes :octicons-arrow-right-24:](k8s.md)
{ .card }
:simple-unraid: [ Install on UNRAID :octicons-arrow-right-24:](unraid.md)
[:simple-unraid: Install on UNRAID :octicons-arrow-right-24:](unraid.md)
{ .card }
:simple-nextdotjs: [ Building from source :octicons-arrow-right-24:](source.md)
[:simple-nextdotjs: Building from source :octicons-arrow-right-24:](source.md)
{ .card }
</div>
### `HOMEPAGE_ALLOWED_HOSTS`
As of v1.0 there is one required environment variable when deploying via a public URL, <code>HOMEPAGE_ALLOWED_HOSTS</code>. This is a comma separated list of allowed hosts (sometimes with the port) that can access your homepage. See the [docker](docker.md) and [source](source.md) installation pages for examples.
As of v1.0 there is one required environment variable to access homepage via a URL other than `localhost`, <code>HOMEPAGE_ALLOWED_HOSTS</code>. The setting helps prevent certain kinds of attacks when retrieving data from the homepage API proxy.
The value is a comma-separated (no spaces) list of allowed hosts (sometimes with the port) that can host your homepage install. See the [docker](docker.md), [kubernetes](k8s.md) and [source](source.md) installation pages for more information about where / how to set the variable.
`localhost:3000` and `127.0.0.1:3000` are always included, but you can add a domain or IP address to this list to allow that host such as `HOMEPAGE_ALLOWED_HOSTS=gethomepage.dev,192.168.1.2:1234`, etc.
If you are seeing errors about host validation, check the homepage logs and ensure that the host exactly as output in the logs is in the `HOMEPAGE_ALLOWED_HOSTS` list.
This can be disabled by setting `HOMEPAGE_ALLOWED_HOSTS` to `*` but this is not recommended. Public deployments must rely on a reverse proxy (and/or VPN) that enforces authentication, TLS, and unexpected Host headers; the built-in host check is a best-effort guard for local setups and is not a substitute for edge protections.
There is an [unofficial helm chart](https://github.com/jameswynn/helm-charts/tree/main/charts/homepage) that creates all the necessary manifests, including the service account and RBAC entities necessary for service discovery.
If you don't want to use the unofficial Helm chart, you can also create your own Kubernetes manifest(s) and apply them with `kubectl apply -f filename.yaml`.
@@ -302,6 +223,9 @@ spec:
- name:homepage
image:"ghcr.io/gethomepage/homepage:latest"
imagePullPolicy:Always
env:
- name:HOMEPAGE_ALLOWED_HOSTS
value:gethomepage.dev# required, may need port. See gethomepage.dev/installation/#homepage_allowed_hosts
@@ -19,7 +19,7 @@ All service widgets work essentially the same, that is, homepage makes a proxied
1. URLs should not end with a / or other API path. Each widget will handle the path on its own.
2. All services with a widget require a unique name.
2. All services with a widget require a unique name as well as a unique group (and all subgroups) name.
3. Verify the homepage installation can connect to the IP address or host you are using for the widget `url`. This is most simply achieved by pinging the server from the homepage machine, in Docker this means _from inside the container_ itself, e.g.:
@@ -33,6 +33,32 @@ Once dependencies have been installed you can lint your code with
pnpm lint
```
## Testing
Homepage uses [Vitest](https://vitest.dev/) for unit and component tests.
Run the test suite:
```bash
pnpm test
```
Run the test suite with coverage:
```bash
pnpm test:coverage
```
### What tests to include
- New or updated widgets should generally include a component test near the widget component (for example `src/widgets/<widget>/component.test.jsx`) that covers realistic behavior: loading/placeholder state, error state, and a representative "happy path" render.
- If you add or change a widget definition file (`src/widgets/<widget>/widget.js`), add/update its corresponding unit test (`src/widgets/<widget>/widget.test.js`) to cover the config/mapping behavior.
- If your widget requires a custom proxy (`src/widgets/<widget>/proxy.js`), add a proxy unit test (`src/widgets/<widget>/proxy.test.js`) that validates:
- request construction (URL, query params, headers/auth)
- Avoid placing test files under `src/pages/**` (Next.js treats files there as routes). Page tests should live under `src/__tests__/pages/**`.
## Code formatting with pre-commit hooks
To ensure a consistent style and formatting across the project source, the project utilizes Git [`pre-commit`](https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks) hooks to perform some formatting and linting before a commit is allowed.
@@ -62,3 +88,4 @@ To ensure cohesiveness of various widgets, the following should be used as a gui
- Minimize the number of API calls
- Avoid the use of custom proxy unless absolutely necessary
- Widgets should be 'read-only', as in they should not make write changes using the relevant tool's API. Homepage widgets are designed to surface information, not to be a (usually worse) replacement for the tool itself.
- Widgets should not allow manually overriding the "refresh interval" setting, as misconfigured refresh intervals can easily lead to performance issues for users.
The `method` property is a string that represents the HTTP method that should be used to make the API request. The default value is `GET`.
```js
const widgetExample = {
api: "{url}/api/{endpoint}",
mappings: {
// `/api/stats`
stats: {
endpoint: "stats",
method: "POST",
},
},
};
```
The `method` represents the HTTP method that should be used to make the API request. The default value is `GET`. Note that `POST` requests are not allowed via the
Proxy handlers are a complex topic and require a good understanding of JavaScript and the Homepage codebase. If you are new to Homepage, we recommend using the built-in proxy handlers.
## Testing proxy handlers
Proxy handlers are a common source of regressions because they deal with authentication, request formatting, and sometimes odd upstream API behavior.
When you add a new proxy handler or custom widget proxy, include tests that focus on behavior:
- **Request construction:** the correct URL/path, query params, headers, and auth (and that secrets are not accidentally logged).
- **Response mapping:** the payload shape expected by the widget/component (including optional/missing fields).
- **Error handling:** upstream non-200s, invalid JSON, timeouts, and unexpected payloads should produce a predictable result.
Test locations:
- Shared handlers live in `src/utils/proxy/handlers/*.js` with tests alongside them (for example `src/utils/proxy/handlers/generic.test.js`).
- Widget-specific proxies live in `src/widgets/<widget>/proxy.js` with tests in `src/widgets/<widget>/proxy.test.js`.
@@ -34,7 +34,7 @@ Homepage uses the [next-i18next](https://github.com/i18next/next-i18next) librar
Homepage uses translated and localized strings for **all text and numerical content** in widgets. English is the default language, and other languages can be added via [Crowdin](https://crowdin.com/project/gethomepage). To add the English translations for your widget, follow these steps:
Open the `public/locales/en/common.js` file.
Open the `public/locales/en/common.json` file.
Add a new object for your widget to the bottom of the list, like this:
@@ -150,7 +150,7 @@ This will render the widget with placeholders for the data, i.e., a skeleton vie
!!! tip "Translation Tips"
The `label` prop in the `Block` component corresponds to the translation key we defined earlier in the `common.js` file. All text and numerical content should be translated.
The `label` prop in the `Block` component corresponds to the translation key we defined earlier in the `common.json` file. All text and numerical content should be translated.
@@ -32,7 +32,7 @@ More detail on configuring service widgets can be found in the [Service Widgets
## Info Widgets
Info widgets are used to display information in the header, often about your system or environment. Info widgets are defined your `widgets.yaml` file. Here's an example:
Info widgets are used to display information in the header, often about your system or environment. Info widgets are defined in your `widgets.yaml` file. Here's an example:
@@ -9,7 +9,7 @@ The widget has two modes, a single system with detailed info if `systemId` is pr
The `systemID` is the `id` field on the collections page of Beszel under the PocketBase admin panel. You can also use the 'nice name' from the Beszel UI.
A "superuser" is currently required to access the data from tbe Beszel API.
A "superuser" is currently required to access the data from the Beszel API.
Allowed fields for 'overview' mode: `["systems", "up"]`
Allowed fields for a single system: `["name", "status", "updated", "cpu", "memory", "disk", "network"]`
Note that older versions of the widget accepted fields as a yaml object, which is still supported. E.g.:
```yaml
mappings:
- field:
locations:
1:name# Citadel of Ricks
@@ -138,7 +138,15 @@ You can manipulate data with the following tools `remap`, `scale`, `prefix` and
prefix:"$"
```
## List View
## Display Options
The widget supports different display modes that can be set using the `display` property.
### Block View (Default)
The default display mode is `block`, which shows fields in a block format.
### List View
You can change the default block view to a list view by setting the `display` option to `list`.
@@ -162,13 +170,54 @@ The list view can optionally display an additional field next to the primary fie
- any:true# will map all other values
to:Unknown
additionalField:
field:
hourly:
time:key
field:hourly.time.key
color:theme
format:date
```
### Dynamic List View
To display a list of items from an array in the API response, set the `display` property to `dynamic-list` and configure the `mappings` object with the following properties:
```yaml
widget:
type:customapi
url:https://example.com/api/servers
display:dynamic-list
mappings:
items:data# optional, the path to the array in the API response. Omit this option if the array is at the root level
name:id# required, field in each item to use as the item name (left side)
label:ip_address# required, field in each item to use as the item label (right side)
limit:5# optional, limit the number of items to display
format:text# optional - format of the label field
target:https://example.com/server/{id}# optional, makes items clickable with template support
```
This configuration would work with an API that returns a response like:
Learn more about [Filebrowser](https://filebrowser.org).
If you are using [Proxy header authentication](https://filebrowser.org/configuration/authentication-method#proxy-header) you have to set `authHeader` and `username`.
Allowed fields: `["available", "used", "total"]`.
```yaml
widget:
type:filebrowser
url:http://filebrowserhostorip:port
username:username
password:password
authHeader:X-My-Header# If using Proxy header authentication
@@ -7,7 +7,7 @@ Learn more about [Gitea](https://gitea.com).
API token requires `notifications`, `repository` and `issue` permissions. See the [gitea documentation](https://docs.gitea.com/development/api-usage#generating-and-listing-api-tokens) for details on generating tokens.
@@ -9,13 +9,20 @@ Learn more about [Gluetun](https://github.com/qdm12/gluetun).
Requires [HTTP control server options](https://github.com/qdm12/gluetun-wiki/blob/main/setup/advanced/control-server.md) to be enabled. By default this runs on port `8000`.
To setup authentication, follow [the official Gluetun documentation](https://github.com/qdm12/gluetun-wiki/blob/main/setup/advanced/control-server.md#authentication). Note that to use the api key method, you must add the route `GET /v1/publicip/ip` to the `routes` array in your Gluetun config.toml.
To setup authentication, follow [the official Gluetun documentation](https://github.com/qdm12/gluetun-wiki/blob/main/setup/advanced/control-server.md#authentication). Note that to use the api key method, you must add the route `GET /v1/publicip/ip` to the `routes` array in your Gluetun config.toml. Similarly, if you want to include the `port_forwarded` field, you must add the route `GET /v1/openvpn/portforwarded` (or `/v1/portforward`) to your Gluetun config.toml.
| Gluetun Version | Homepage Widget Version |
| --------------- | ----------------------- |
| <3.40.1|1(default)|
|>= 3.40.1 | 2 |
```yaml
widget:
type:gluetun
url:http://gluetun.host.or.ip:port
key:gluetunkey# Not required if /v1/publicip/ip endpoint is configured with `auth = none`
@@ -9,14 +9,21 @@ You can create an API key from inside Jellyfin at `Settings > Advanced > Api Key
As of v0.6.11 the widget supports fields `["movies", "series", "episodes", "songs"]`. These blocks are disabled by default but can be enabled with the `enableBlocks` option, and the "Now Playing" feature (enabled by default) can be disabled with the `enableNowPlaying` option.
| Jellyfin Version | Homepage Widget Version |
| ---------------- | ----------------------- |
| <10.12|1(default)|
|>= 10.12 | 2 |
```yaml
widget:
type:jellyfin
url:http://jellyfin.host.or.ip
key:apikeyapikeyapikeyapikeyapikey
version:2# optional, default is 1
enableBlocks:true# optional, defaults to false
enableNowPlaying:true# optional, defaults to true
enableUser:true# optional, defaults to false
enableMediaControl:false# optional, defaults to true
showEpisodeNumber:true# optional, defaults to false
expandOneStreamToTwoRows:false# optional, defaults to true
This widget shows either details about all containers or stacks (if `showStacks` is true) managed by [Komodo](https://komo.do/) or the number of running servers, containers and stacks when `showSummary` is enabled.
The api key and secret can be found in the Komodo settings.
Learn more about [Pangolin](https://github.com/fosrl/pangolin).
This widget shows sites (online/total), resources (healthy/total), targets (healthy/total), and traffic statistics for a Pangolin organization. A resource is considered healthy if at least one of its targets is healthy, or if it has no targets.
Find your organization ID in the URL when logged in (e.g., `https://app.pangolin.net/{org-id}/...`).
## API Key Setup
Create an API key with the following permissions:
- **List Sites**
- **List Resources**
**Self-Hosted:** Enable the [Integration API](https://docs.pangolin.net/self-host/advanced/integration-api) in your Pangolin configuration before creating the key.
@@ -7,12 +7,16 @@ Learn more about [Portainer](https://github.com/portainer/portainer).
You'll need to make sure you have the correct environment set for the integration to work properly. From the Environments section inside of Portainer, click the one you'd like to connect to and observe the ID at the end of the URL (should be), something like `#!/endpoints/1`, here `1` is the value to set as the `env` value. In order to generate an API key, please follow the steps outlined here https://docs.portainer.io/api/access.
Allowed fields:`["running", "stopped", "total"]`.
Allowed fields:
- For Docker mode (default): `["running", "stopped", "total"]`
- For Kubernetes mode (`kubernetes: true`): `["applications", "services", "namespaces"]`
@@ -7,34 +7,7 @@ Learn more about [Proxmox](https://www.proxmox.com/en/).
This widget shows the running and total counts of both QEMU VMs and LX Containers in the Proxmox cluster. It also shows the CPU and memory usage of the first node in the cluster.
You will need to generate an API Token for new or an existing user. Here is an example of how to do this for a new user.
1. Navigate to the Proxmox portal, click on Datacenter
2. Expand Permissions, click on Groups
3. Click the Create button
4. Name the group something informative, like api-ro-users
5. Click on the Permissions "folder"
6. Click Add -> Group Permission
- Path: /
- Group: group from bullet 4 above
- Role: PVEAuditor
- Propagate: Checked
7. Expand Permissions, click on Users
8. Click the Add button
- User name: something informative like `api`
- Realm: Linux PAM standard authentication
- Group: group from bullet 4 above
9. Expand Permissions, click on API Tokens
10. Click the Add button
- User: user from bullet 8 above
- Token ID: something informative like the application or purpose like `homepage`
- Privilege Separation: Checked
11. Go back to the "Permissions" menu
12. Click Add -> API Token Permission
- Path: /
- API Token: select the Token ID created in Step 10
- Role: PVE Auditor
- Propagate: Checked
See the [Proxmox configuration documentation](../../configs/proxmox.md#create-token) for details on creating API tokens.
Use `username@pam!Token ID` as the `username` (e.g `api@pam!homepage`) setting and `Secret` as the `password` setting.
@@ -5,6 +5,8 @@ description: Proxmox Backup Server Widget Configuration
Learn more about [Proxmox Backup Server](https://www.proxmox.com/en/proxmox-backup-server/overview).
Create a user and an API token similar to the [Proxmox VE description](proxmox.md). The "Audit" role is required for both the user and token (not group).
Learn more about [Trilium](https://github.com/TriliumNext/Notes).
This widget is compatible with [TriliumNext](https://github.com/TriliumNext/Notes) versions >= [v0.94.0](https://github.com/TriliumNext/Notes/releases/tag/v0.94.0).
Find (or create) your ETAPI key under `Options > ETAPI > Create new ETAPI token`.
@@ -11,10 +11,17 @@ Note: by default `["connected", "enabled", "total"]` are displayed.
To detect if a device is connected the time since the last handshake is queried. `threshold` is the time to wait in minutes since the last handshake to consider a device connected. Default is 2 minutes.
| Wg-Easy API Version | Homepage Widget Version |
| ------------------- | ----------------------- |
| <v15|1(default)|
|>= v15 | 2 |
```yaml
widget:
type:wgeasy
url:http://wg.easy.or.ip
version:2# optional, default is 1
username:yourwgusername# required for v15 and above
"errorWhenLoadingData":"Error when loading calendar data"
},
"romm":{
"platforms":"Platforms",
@@ -883,9 +923,10 @@
"species":"Species"
},
"gitea":{
"notifications":"Notifications",
"issues":"Issues",
"pulls":"Pull Requests"
"notifications":"Notifications",
"issues":"Issues",
"pulls":"Pull Requests",
"repositories":"Repositories"
},
"stash":{
"scenes":"Scenes",
@@ -1023,12 +1064,112 @@
"bcharge":"Battery Charge",
"timeleft":"Time Left"
},
"hoarder":{
"karakeep":{
"bookmarks":"Bookmarks",
"favorites":"Favorites",
"archived":"Archived",
"highlights":"Highlights",
"lists":"Lists",
"tags":"Tags"
},
"slskd":{
"slskStatus":"Network",
"connected":"Connected",
"disconnected":"Disconnected",
"updateStatus":"Update",
"update_yes":"Available",
"update_no":"Up to Date",
"downloads":"Downloads",
"uploads":"Uploads",
"sharedFiles":"Files"
},
"jellystat":{
"songs":"Songs",
"movies":"Movies",
"episodes":"Episodes",
"other":"Other"
},
"checkmk":{
"serviceErrors":"Service issues",
"hostErrors":"Host issues"
},
"komodo":{
"total":"Total",
"running":"Running",
"stopped":"Stopped",
"down":"Down",
"unhealthy":"Unhealthy",
"unknown":"Unknown",
"servers":"Servers",
"stacks":"Stacks",
"containers":"Containers"
},
"filebrowser":{
"available":"Available",
"used":"Used",
"total":"Total"
},
"wallos":{
"activeSubscriptions":"Subscriptions",
"thisMonthlyCost":"This Month",
"nextMonthlyCost":"Next Month",
"previousMonthlyCost":"Prev. Month",
"nextRenewingSubscription":"Next Payment"
},
"unraid":{
"STARTED":"Started",
"STOPPED":"Stopped",
"NEW_ARRAY":"New Array",
"RECON_DISK":"Reconstructing Disk",
"DISABLE_DISK":"Disk Disabled",
"SWAP_DSBL":"Swap Disable",
"INVALID_EXPANSION":"Invalid Expansion",
"PARITY_NOT_BIGGEST":"Parity Not Biggest",
"TOO_MANY_MISSING_DISKS":"Too Many Missing Disks",
"NEW_DISK_TOO_SMALL":"New Disk Too Small",
"NO_DATA_DISKS":"No Data Disks",
"notifications":"Notifications",
"status":"Status",
"cpu":"CPU",
"memoryUsed":"Memory Used",
"memoryAvailable":"Memory Available",
"arrayUsed":"Array Used",
"arrayFree":"Array Free",
"poolUsed":"{{pool}} Used",
"poolFree":"{{pool}} Free"
},
"backrest":{
"num_plans":"Plans",
"num_success_30":"Successes",
"num_failure_30":"Failures",
"num_success_latest":"Succeeding",
"num_failure_latest":"Failing",
"bytes_added_30":"Bytes Added"
},
"yourspotify":{
"songs":"Songs",
"time":"Time",
"artists":"Artists"
},
"arcane":{
"containers":"Containers",
"images":"Images",
"image_updates":"Image Updates",
"images_unused":"Unused",
"environment_required":"Environment ID Required"
},
"dockhand":{
"running":"Running",
"stopped":"Stopped",
"cpu":"CPU",
"memory":"Memory",
"images":"Images",
"volumes":"Volumes",
"events_today":"Events Today",
"pending_updates":"Pending Updates",
"stacks":"Stacks",
"paused":"Paused",
"total":"Total",
"environment_not_found":"Environment Not Found"
}
}
Some files were not shown because too many files have changed in this diff
Show More
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.