Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7bafe1ce75 | ||
|
|
ca95112466 | ||
|
|
32732680e5 | ||
|
|
4905ea6738 | ||
|
|
ca856f9f54 | ||
|
|
ef2ed6c602 | ||
|
|
9b4970583e | ||
|
|
4641839fa4 | ||
|
|
00e9dbe268 | ||
|
|
34a17932ae | ||
|
|
c224e62f30 | ||
|
|
25c2fbab51 | ||
|
|
5b58be347e | ||
|
|
7fcc36adff | ||
|
|
d11f34a6f2 | ||
|
|
ff8ef7a403 | ||
|
|
76758ff7bc | ||
|
|
45c1507bfa | ||
|
|
1c34d95976 | ||
|
|
eb33ff1372 | ||
|
|
c3a090e880 | ||
|
|
def3a3a6fa | ||
|
|
ad0bb41fe4 | ||
|
|
6e76e8c0dd | ||
|
|
e06d95ee7a | ||
|
|
865e96b5b1 | ||
|
|
66313055df | ||
|
|
2283ec7113 | ||
|
|
e5d6b6be87 | ||
|
|
e3e5730a39 | ||
|
|
d776078ecf | ||
|
|
4ca02a9133 | ||
|
|
f4891447d3 | ||
|
|
2067d851cf | ||
|
|
3aedd312b7 | ||
|
|
e8ca63d9c0 | ||
|
|
d89bf25e21 | ||
|
|
07770e862c | ||
|
|
576cc0b418 | ||
|
|
81d5070a8b | ||
|
|
44df54ecb8 | ||
|
|
07867cc3db | ||
|
|
818e9bb0c5 | ||
|
|
3b73f0bc4c | ||
|
|
c92ca2af5f | ||
|
|
124a5526b4 | ||
|
|
b52b2b5f3c | ||
|
|
1f3e7afd5e | ||
|
|
2c8134ee02 | ||
|
|
0482c040ec | ||
|
|
1088f058e3 | ||
|
|
47861c0194 | ||
|
|
0e7d7e0a2f | ||
|
|
5ca5bd3bda | ||
|
|
bcb732a26c | ||
|
|
8c9e2c8bfa | ||
|
|
14c7e58e17 | ||
|
|
2eea916013 | ||
|
|
5a7607ddf7 | ||
|
|
e466208c09 | ||
|
|
cfce8ada4e | ||
|
|
36661e810f | ||
|
|
308e478733 | ||
|
|
59ce3c7158 | ||
|
|
6ea7a6ff09 | ||
|
|
1611a9033b | ||
|
|
20f4f87361 | ||
|
|
4130b62f24 | ||
|
|
a3b7b0835e | ||
|
|
e225424ab1 | ||
|
|
237b6cb119 | ||
|
|
557b3f8d5f | ||
|
|
8f0efd508e | ||
|
|
876f312a2e | ||
|
|
e662a175c0 | ||
|
|
52c261c034 | ||
|
|
d8108f3375 | ||
|
|
0ae2203aaa | ||
|
|
6b30ba3707 | ||
|
|
2e945805b2 | ||
|
|
780e5928cd | ||
|
|
f61e07ae58 | ||
|
|
7a8b37c906 | ||
|
|
70b0df45b3 | ||
|
|
fa946e1b33 | ||
|
|
f01969b9fc | ||
|
|
11b941285b | ||
|
|
3148ecb823 | ||
|
|
71811dda55 | ||
|
|
e4cb8da5e2 | ||
|
|
aab12bbe64 | ||
|
|
12c436cd5c | ||
|
|
14d426764b | ||
|
|
b3b5a58116 | ||
|
|
5f7429063b | ||
|
|
2ffb05e746 | ||
|
|
921aac0560 | ||
|
|
24bd63d216 | ||
|
|
8b87967a12 | ||
|
|
d44db87d43 | ||
|
|
73b7df44d7 | ||
|
|
c6cf75e561 | ||
|
|
3c3232e85a | ||
|
|
c1aaa1a955 | ||
|
|
5e6ebef961 | ||
|
|
c3436d43e6 | ||
|
|
d825cb7051 | ||
|
|
de682abadc | ||
|
|
6afa4d2f4a | ||
|
|
95473d1b7f | ||
|
|
fd58f9a358 | ||
|
|
a89877b461 | ||
|
|
b362ed1e68 | ||
|
|
83355510c0 | ||
|
|
6cf34af845 | ||
|
|
0f2f9e6e59 | ||
|
|
2f5f89426a | ||
|
|
427db07a95 | ||
|
|
fc07e911d1 | ||
|
|
94ec244fad | ||
|
|
4184721b9a | ||
|
|
8dc5a0540f | ||
|
|
71d1cef139 | ||
|
|
a97605e0f7 | ||
|
|
0876992a9a | ||
|
|
5a65ff47bf | ||
|
|
4060f9299f | ||
|
|
ca8163c061 | ||
|
|
cb1a73a6ac | ||
|
|
7899d8677c | ||
|
|
16e3f54512 | ||
|
|
39a14a18f9 | ||
|
|
ed705c9e34 | ||
|
|
b0ec746081 | ||
|
|
00fa1192d7 | ||
|
|
c7b0c1bcf0 | ||
|
|
9da3ff3e9d | ||
|
|
93113234a7 | ||
|
|
9ef4bf803d | ||
|
|
4920063318 | ||
|
|
68d236fd63 | ||
|
|
ebce24ba67 | ||
|
|
039bfb9b93 | ||
|
|
faf01e82c8 | ||
|
|
54d7821e24 | ||
|
|
f29e604bc1 | ||
|
|
50deb638fb | ||
|
|
b1f25f779d | ||
|
|
df874dd2db | ||
|
|
26ede97407 | ||
|
|
b5fbf0085f | ||
|
|
a65dc2841f | ||
|
|
09a85e69c1 | ||
|
|
e53f63b373 | ||
|
|
ea1e07c74f | ||
|
|
4635e3ce4e | ||
|
|
345d9e6fa4 | ||
|
|
f86120016c | ||
|
|
68b70ac01a | ||
|
|
c65e6cdbd4 | ||
|
|
073d9ce127 | ||
|
|
6da471d24a | ||
|
|
c157001455 | ||
|
|
00e4cc8100 | ||
|
|
d3205d886a | ||
|
|
97d26bde5e | ||
|
|
12f950ce4a | ||
|
|
381a257dbc | ||
|
|
16c86079e6 | ||
|
|
fd69cd28f0 | ||
|
|
3b6de1f91f | ||
|
|
f0747fd28b | ||
|
|
5c96c52e64 | ||
|
|
bc2aff17f3 | ||
|
|
90e30ce577 | ||
|
|
485a54d6d8 | ||
|
|
45954837ed | ||
|
|
aef0a6d340 | ||
|
|
e74d5e2aae | ||
|
|
7453e6c559 | ||
|
|
b3ec1381e9 | ||
|
|
30c00ea30d | ||
|
|
4df62221c7 | ||
|
|
dec04da806 | ||
|
|
866b3ab78b | ||
|
|
92c6e4668d | ||
|
|
df70d06606 | ||
|
|
4d0c2f8eec | ||
|
|
9887c018d2 | ||
|
|
e93f14acdf | ||
|
|
85db534fa7 | ||
|
|
8ac35083e6 | ||
|
|
f481007b9a | ||
|
|
f88fbb5a19 | ||
|
|
d4cecde0f0 | ||
|
|
0356eb427c | ||
|
|
b3e6d35b79 | ||
|
|
be9c69f325 | ||
|
|
e93293f8a9 | ||
|
|
967ed8dd73 | ||
|
|
5454bcc8ac | ||
|
|
ec54ddcfa6 | ||
|
|
25a4aca8c0 | ||
|
|
d1f76b24c0 | ||
|
|
6a2e7d0610 | ||
|
|
438f0d80eb | ||
|
|
673b1a74d6 | ||
|
|
84db2f9d49 | ||
|
|
2e3dca3e87 | ||
|
|
7d5ec15017 | ||
|
|
f6baaa0c3b | ||
|
|
9d3c0acb95 | ||
|
|
3079eb1767 | ||
|
|
5059a16181 | ||
|
|
444ae82352 | ||
|
|
65a7e84bea | ||
|
|
55226842f9 | ||
|
|
e84b05e91c | ||
|
|
d6359d595c | ||
|
|
f876b2fd06 | ||
|
|
c256bd644c | ||
|
|
c9fe69c5ec | ||
|
|
64a57bac82 | ||
|
|
39e408c53f | ||
|
|
f404f77002 | ||
|
|
21a38b3004 | ||
|
|
3b76381262 | ||
|
|
bb97ce5a01 | ||
|
|
2e323677f4 | ||
|
|
f2dd7c10a2 | ||
|
|
ccabc2dab6 | ||
|
|
5633bc4775 | ||
|
|
d20bb18b08 | ||
|
|
747ccdfa9e | ||
|
|
bbcfc505bc | ||
|
|
2b1053e243 | ||
|
|
154753ddda | ||
|
|
74599b0b65 | ||
|
|
7bfd10210e | ||
|
|
19befee8a5 | ||
|
|
77cbd9f723 | ||
|
|
1fa345edd1 | ||
|
|
6331c88911 | ||
|
|
4c69c4ec45 | ||
|
|
ff31208c37 | ||
|
|
177ea49469 | ||
|
|
f03bf6a917 | ||
|
|
80d1416ad6 | ||
|
|
d2a935b6c1 | ||
|
|
758c300d9e | ||
|
|
53185701ce | ||
|
|
21cc0b19b3 | ||
|
|
a882a227f1 | ||
|
|
e535ff393e | ||
|
|
349dfa6d41 | ||
|
|
6c8dbc182f | ||
|
|
d880c4a281 | ||
|
|
d7083fc14c | ||
|
|
c7431ef1f5 | ||
|
|
419c8434f9 | ||
|
|
49ef7748ad | ||
|
|
a9f1293077 | ||
|
|
2344896ba9 | ||
|
|
0aa3b98675 | ||
|
|
f003d9ddc9 | ||
|
|
56346b2aa8 | ||
|
|
e321ee27a2 | ||
|
|
afd73565c9 | ||
|
|
36d7ef0562 | ||
|
|
99a871344c | ||
|
|
010ba45468 | ||
|
|
777bbd89a1 | ||
|
|
6f2cd7fc2b | ||
|
|
1a5e083fd0 | ||
|
|
9607bf65cd | ||
|
|
6caa1c8224 | ||
|
|
556179deb5 | ||
|
|
ab012b4a32 | ||
|
|
d635e4d80f | ||
|
|
6afd21fe98 | ||
|
|
cf7ec0a31f | ||
|
|
5be2226c39 | ||
|
|
082f2271c5 | ||
|
|
5a03640a1b | ||
|
|
80132ae71f | ||
|
|
9b8b6c7cfe | ||
|
|
282997e016 | ||
|
|
c973f54c8e | ||
|
|
8dd984fcb3 | ||
|
|
2d17e9f58a | ||
|
|
3fe3d1714a | ||
|
|
add61ce9a3 | ||
|
|
1332f5626b | ||
|
|
203711e570 | ||
|
|
2cb69c4ea3 | ||
|
|
7368262149 | ||
|
|
b9858b5ba4 | ||
|
|
b84502ef9b | ||
|
|
b39bff43a9 | ||
|
|
d5dbf6fc17 | ||
|
|
c6c96c4870 | ||
|
|
f438ea8aa9 | ||
|
|
279aeb3269 | ||
|
|
f5ac662aeb | ||
|
|
0b1c2f856f | ||
|
|
dd11fd8381 | ||
|
|
07e6598f75 | ||
|
|
b7eb099977 | ||
|
|
5ab3ee7d02 | ||
|
|
59106053f2 | ||
|
|
078c41b6ec | ||
|
|
1f5311e93b | ||
|
|
5bde4d3cc5 | ||
|
|
94074c368d | ||
|
|
bf91f92d56 | ||
|
|
b7693c4238 | ||
|
|
fb18ac8fc5 | ||
|
|
336ba76fef | ||
|
|
0110a2ef63 | ||
|
|
5dc4dbeaef | ||
|
|
f3f2778f1f | ||
|
|
c08b8979ee | ||
|
|
9a7a828618 | ||
|
|
352a8ed0d0 | ||
|
|
6d3f7e3e36 | ||
|
|
7833cca86b | ||
|
|
6edf78acd7 | ||
|
|
7d43f6e5d9 | ||
|
|
1723a9e744 | ||
|
|
2ba31fd37b | ||
|
|
327e5c15ae | ||
|
|
3efe64a062 | ||
|
|
40b726b8bc | ||
|
|
d2d0d16e4d | ||
|
|
63ad879022 | ||
|
|
2ae0c2ab43 | ||
|
|
2410ba5f5c | ||
|
|
8f0039245d | ||
|
|
0871e4cf0d | ||
|
|
db9f42520a | ||
|
|
3ebcedec26 | ||
|
|
c41a3d427e | ||
|
|
71c39aa18e | ||
|
|
000c51a131 | ||
|
|
2c44c7f2b8 | ||
|
|
c2cf25b4fb | ||
|
|
03ebb8c2db | ||
|
|
f0b153aa37 | ||
|
|
965d130ce7 | ||
|
|
a87a16edb1 | ||
|
|
1493252e28 | ||
|
|
46ff20b0a0 | ||
|
|
1bc84dd90e | ||
|
|
14cbc03621 | ||
|
|
9ec35b0cda | ||
|
|
2d6dd2f0d0 | ||
|
|
572bc71396 | ||
|
|
d4b1739c46 | ||
|
|
76495948e2 | ||
|
|
a95052c787 | ||
|
|
400127b45c | ||
|
|
f77c47b94b | ||
|
|
825636c4f6 | ||
|
|
3aa14e22ed | ||
|
|
acdfcbb18e | ||
|
|
3a1245cbc5 | ||
|
|
f0963405ca | ||
|
|
d078d761d9 | ||
|
|
84fcf02729 | ||
|
|
c308ae5c6e | ||
|
|
93192cfedc | ||
|
|
0f9ae13560 | ||
|
|
f4a6f37415 | ||
|
|
95bfaf5127 | ||
|
|
83e3b22f9a | ||
|
|
cd71404288 | ||
|
|
7a089ab177 | ||
|
|
2513e8454f |
No files matched your search
@@ -66,8 +66,6 @@ homarr/
|
|||||||
│ ├── analytics/ # Server-side analytics (Umami)
|
│ ├── analytics/ # Server-side analytics (Umami)
|
||||||
│ ├── server-settings/ # Server setting keys/types
|
│ ├── server-settings/ # Server setting keys/types
|
||||||
│ ├── settings/ # User-facing settings UI context
|
│ ├── settings/ # User-facing settings UI context
|
||||||
│ ├── old-import/ # Legacy Homarr import
|
|
||||||
│ ├── old-schema/ # Legacy Homarr zod schemas
|
|
||||||
│ └── cli/ # Node CLI for ops (brocli)
|
│ └── cli/ # Node CLI for ops (brocli)
|
||||||
├── tooling/
|
├── tooling/
|
||||||
│ ├── typescript/ # Base tsconfig
|
│ ├── typescript/ # Base tsconfig
|
||||||
|
|||||||
@@ -263,15 +263,6 @@ Even hidden options need translation keys or the translation test fails:
|
|||||||
"widget.mywidget.option.columnWidths.label": "Column widths"
|
"widget.mywidget.option.columnWidths.label": "Column widths"
|
||||||
```
|
```
|
||||||
|
|
||||||
### Old-import mappings
|
|
||||||
|
|
||||||
Add to `packages/old-import/src/widgets/options.ts`:
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
columnOrder: () => undefined,
|
|
||||||
columnWidths: () => undefined,
|
|
||||||
```
|
|
||||||
|
|
||||||
### Dynamic storeKey
|
### Dynamic storeKey
|
||||||
|
|
||||||
Use a key that includes `itemId` and sorted column names. This prevents cross-widget localStorage bleeding:
|
Use a key that includes `itemId` and sorted column names. This prevents cross-widget localStorage bleeding:
|
||||||
@@ -610,13 +601,12 @@ if (isEditMode) rowContextMenuHandler = undefined;
|
|||||||
4. Add CSS file for transparent backgrounds (if widget context)
|
4. Add CSS file for transparent backgrounds (if widget context)
|
||||||
5. Add responsive column visibility (if widget context)
|
5. Add responsive column visibility (if widget context)
|
||||||
6. Add hidden options + hydration logic (if column persistence needed)
|
6. Add hidden options + hydration logic (if column persistence needed)
|
||||||
7. Add old-import mappings for new options
|
7. Add translation keys (including hidden option labels)
|
||||||
8. Add translation keys (including hidden option labels)
|
8. Add context menu if row actions exist
|
||||||
9. Add context menu if row actions exist
|
9. Add row expansion if detail view exists
|
||||||
10. Add row expansion if detail view exists
|
10. Add error handling on all mutations
|
||||||
11. Add error handling on all mutations
|
11. Add accessibility attributes
|
||||||
12. Add accessibility attributes
|
12. Test at multiple widget widths
|
||||||
13. Test at multiple widget widths
|
13. Update docs in `apps/docs/docs/widgets/` if applicable
|
||||||
14. Update docs in `apps/docs/docs/widgets/` if applicable
|
14. Run `pnpm turbo typecheck`
|
||||||
15. Run `pnpm turbo typecheck` — catches old-import mismatches
|
15. Run translation spec — catches missing keys
|
||||||
16. Run translation spec — catches missing keys
|
|
||||||
@@ -95,6 +95,12 @@ jobs:
|
|||||||
- name: Validate checked-in OpenAPI schema
|
- name: Validate checked-in OpenAPI schema
|
||||||
run: pnpm check:openapi
|
run: pnpm check:openapi
|
||||||
|
|
||||||
|
- name: Validate feature contracts
|
||||||
|
run: pnpm check:feature-contracts
|
||||||
|
|
||||||
|
- name: Test feature platform
|
||||||
|
run: pnpm test:feature-platform
|
||||||
|
|
||||||
- name: Validate Custom Widget bundle budget
|
- name: Validate Custom Widget bundle budget
|
||||||
run: |
|
run: |
|
||||||
pnpm --filter nextjs build
|
pnpm --filter nextjs build
|
||||||
|
|||||||
@@ -84,3 +84,11 @@ apps/docs/.docusaurus
|
|||||||
apps/docs/build
|
apps/docs/build
|
||||||
.pnpm-store
|
.pnpm-store
|
||||||
benchmark-results
|
benchmark-results
|
||||||
|
|
||||||
|
# local performance investigation (never ship benchmark data or restored backups)
|
||||||
|
.widget-performance/
|
||||||
|
.bench/
|
||||||
|
homarr-backup*.zip
|
||||||
|
*.sqlite-wal
|
||||||
|
*.sqlite-shm
|
||||||
|
/scripts/benchmarks/
|
||||||
@@ -40,8 +40,6 @@ homarr/
|
|||||||
│ ├── analytics/ # Server-side analytics (Umami)
|
│ ├── analytics/ # Server-side analytics (Umami)
|
||||||
│ ├── server-settings/ # Server setting keys/types
|
│ ├── server-settings/ # Server setting keys/types
|
||||||
│ ├── settings/ # User-facing settings UI context
|
│ ├── settings/ # User-facing settings UI context
|
||||||
│ ├── old-import/ # Legacy Homarr import
|
|
||||||
│ ├── old-schema/ # Legacy Homarr zod schemas
|
|
||||||
│ └── cli/ # Node CLI for ops (brocli)
|
│ └── cli/ # Node CLI for ops (brocli)
|
||||||
├── tooling/
|
├── tooling/
|
||||||
│ ├── typescript/ # Base tsconfig
|
│ ├── typescript/ # Base tsconfig
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ For a single consolidated file with all content, use:
|
|||||||
- [How to integrate custom input with use-form hook?](https://mantine.dev/llms/q-custom-input-use-form.md): Learn how to add use-form support for custom inputs
|
- [How to integrate custom input with use-form hook?](https://mantine.dev/llms/q-custom-input-use-form.md): Learn how to add use-form support for custom inputs
|
||||||
- [How to prevent Modal from closing?](https://mantine.dev/llms/q-how-to-prevent-modal-from-closing.md): Learn how to prevent Modal from closing when the user clicks outside of it or presses the Escape key
|
- [How to prevent Modal from closing?](https://mantine.dev/llms/q-how-to-prevent-modal-from-closing.md): Learn how to prevent Modal from closing when the user clicks outside of it or presses the Escape key
|
||||||
- [How to scroll to the top of the form if the form is submitted with errors?](https://mantine.dev/llms/q-scroll-to-the-top-of-the-form.md): Learn how to call a function when the form is submitted with errors
|
- [How to scroll to the top of the form if the form is submitted with errors?](https://mantine.dev/llms/q-scroll-to-the-top-of-the-form.md): Learn how to call a function when the form is submitted with errors
|
||||||
- [How to update Mantine dependencies?](https://mantine.dev/llms/q-how-to-update-dependencies.md): Learn how to update @mantine/_, @mantinex/_ and postcss-preset-mantine dependencies manually or with ncu script
|
- [How to update Mantine dependencies?](https://mantine.dev/llms/q-how-to-update-dependencies.md): Learn how to update `@mantine/*`, `@mantinex/*` and `postcss-preset-mantine` dependencies manually or with ncu script
|
||||||
- [How to use Dropzone with @mantine/form?](https://mantine.dev/llms/q-how-to-use-dropzone-with-form.md): Learn how to use Dropzone with @mantine/form to handle file selection state
|
- [How to use Dropzone with @mantine/form?](https://mantine.dev/llms/q-how-to-use-dropzone-with-form.md): Learn how to use Dropzone with @mantine/form to handle file selection state
|
||||||
- [How to use Mantine template on GitHub?](https://mantine.dev/llms/q-templates-usage.md): Learn how to create a new repository based on Mantine template
|
- [How to use Mantine template on GitHub?](https://mantine.dev/llms/q-templates-usage.md): Learn how to create a new repository based on Mantine template
|
||||||
- [I get hydration warning about data-mantine-color-scheme attribute, what does it mean?](https://mantine.dev/llms/q-color-scheme-hydration-warning.md): Learn how hydration works and how to fix warnings
|
- [I get hydration warning about data-mantine-color-scheme attribute, what does it mean?](https://mantine.dev/llms/q-color-scheme-hydration-warning.md): Learn how hydration works and how to fix warnings
|
||||||
|
|||||||
@@ -13,8 +13,6 @@ This will be a one time occurrence and version > ``1.0`` will have less breaking
|
|||||||
This time more important than every; **read the breaking changes** list and **create a backup** before updating.
|
This time more important than every; **read the breaking changes** list and **create a backup** before updating.
|
||||||
Some third party installation methods may take multiple days or weeks to update to the new version.
|
Some third party installation methods may take multiple days or weeks to update to the new version.
|
||||||
|
|
||||||
See [this guide on how to import your previous Homarr dashboard](/docs/getting-started/after-the-installation#importing-a-zip-from-version-before-100)
|
|
||||||
|
|
||||||
## Changes at a glance
|
## Changes at a glance
|
||||||
- **Asynchronous integrations system**: In versions prior to ``1.0``, we fetched data upon each request synchronously.
|
- **Asynchronous integrations system**: In versions prior to ``1.0``, we fetched data upon each request synchronously.
|
||||||
This means that the user had to wait for the requests to finish so any data would appear.
|
This means that the user had to wait for the requests to finish so any data would appear.
|
||||||
|
|||||||
@@ -10,12 +10,11 @@ If you are still on a version before 0.15.10, please update to 0.15.10 where we
|
|||||||
|
|
||||||
<!-- truncate -->
|
<!-- truncate -->
|
||||||
|
|
||||||
## Export your data
|
## Preserve your old installation
|
||||||
|
|
||||||
As 1.0 is a complete rewrite of Homarr and therefor not compatible with the old docker mounts, we need to export your data first.
|
Homarr 1.0 is a complete rewrite and cannot reuse the old Docker mounts. Keep the 0.15 installation and its data intact while you build the replacement. The historical `Management` > `Tools` > `Migrate to 1.0` export can still be kept as a record, but current Homarr releases cannot import that ZIP or its secret key.
|
||||||
For this you can navigate to the `Migrate to 1.0` page which you can find under `Management` > `Tools` > `Migrate to 1.0`.
|
|
||||||
Here you can select which things you want to export and download the zip file.
|
Plan to recreate your apps, integrations, and boards manually in the new installation. A SQLite database backup can be restored from the onboarding welcome screen only when it was created by a compatible current Homarr release; it is not a conversion path for a 0.15 database.
|
||||||
It will also show you a secret key which you will need to import the secret data like user password hashes, salts and integration secrets.
|
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
@@ -28,25 +27,12 @@ Please note that if you are using docker you need to specify a diffrent external
|
|||||||
So in your compose file the ports would be `7576:7575` instead of `7575:7575`.
|
So in your compose file the ports would be `7576:7575` instead of `7575:7575`.
|
||||||
|
|
||||||
## Import your data
|
## Import your data
|
||||||
Once the installation is completed you can access the new installation. During the onboarding you'll need to select `Import from Homarr before 1.0`.
|
|
||||||
|
|
||||||

|
:::warning Legacy guide
|
||||||
|
|
||||||
After that you can upload the zip file you downloaded in the first step.
|
The pre-1.0 ZIP importer is no longer included in current Homarr releases. Keep the old installation available until you have manually verified the replacement. Compatible SQLite backups from current releases can still be restored from the onboarding welcome screen.
|
||||||
|
|
||||||

|
:::
|
||||||
|
|
||||||
After that you'll get a list with all your boards that can be imported. You can configure how it should be imported and can select which screensizes it should import.
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
Once you have selected everything you can click on `Confirm import and continue` which will open the encryption key input dialog where you can input the secret key you got during the export.
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
After that you can continue the onboarding and you should see all your boards and data in the new installation.
|
|
||||||
|
|
||||||
See [After the installation](https://homarr.dev/docs/getting-started/after-the-installation) for more information.
|
|
||||||
|
|
||||||
## Remove the old installation
|
## Remove the old installation
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"label": "Advanced",
|
"label": "Advanced",
|
||||||
"collapsed": true,
|
"collapsed": true,
|
||||||
"position": 4,
|
"position": 5,
|
||||||
"link": {
|
"link": {
|
||||||
"type": "generated-index",
|
"type": "generated-index",
|
||||||
"title": "Advanced Concepts or features"
|
"title": "Advanced Concepts or features"
|
||||||
|
|||||||
@@ -57,51 +57,73 @@ Homarr becomes the instance administrator.
|
|||||||
Use `pnpm docker:dev:up` instead when you only need Redis in the background. Running the migration also seeds the
|
Use `pnpm docker:dev:up` instead when you only need Redis in the background. Running the migration also seeds the
|
||||||
default data; use `pnpm db:seed` to seed it explicitly later.
|
default data; use `pnpm db:seed` to seed it explicitly later.
|
||||||
|
|
||||||
### Run PocketBase and documentation
|
Workshop contributors can set up PocketBase and Docusaurus with the dedicated
|
||||||
|
[Workshop development guide](../../workshop/development).
|
||||||
|
|
||||||
Start PocketBase in another terminal:
|
### Scaffold a native feature
|
||||||
|
|
||||||
|
Run `pnpm generate:feature` and choose `native-integration`, `widget`, or `integration-widget`. The generator creates
|
||||||
|
implementation, focused test, documentation, and English translation skeletons and updates the current explicit
|
||||||
|
registries. It stops before writing if a target exists, a registry anchor is ambiguous, or a supported integration is
|
||||||
|
unknown.
|
||||||
|
|
||||||
|
The generated code is a starting contract, not a finished feature. Replace the placeholder request, UI, tests, secrets,
|
||||||
|
categories, configuration, error states, and documentation with behavior specific to the service. Then run:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
cp apps/workshop/.env.example apps/workshop/.env
|
pnpm check:feature-contracts
|
||||||
docker compose --env-file apps/workshop/.env -f apps/workshop/docker-compose.yml up --build workshop
|
pnpm test:feature-platform
|
||||||
```
|
```
|
||||||
|
|
||||||
Then start Docusaurus in a third terminal:
|
The contract check reports the exact registry, docs path, translation, support mapping, or package export that needs
|
||||||
|
repair. It intentionally follows today's explicit registries; a future canonical feature descriptor can replace those
|
||||||
|
patches without changing the contributor-facing generator names.
|
||||||
|
|
||||||
|
Integration-capable widgets declare their server-safe relationship in `nativeFeatureCapabilities`. Homarr derives the
|
||||||
|
widget-to-integration map, reverse integration-to-widget map, optional-connection set, and server selection limits from
|
||||||
|
that descriptor. Widget definitions still mirror the supported list for client-side type inference; the focused widget
|
||||||
|
manifest test and `check:feature-contracts` prevent drift until those definition types can consume the descriptor
|
||||||
|
directly.
|
||||||
|
|
||||||
|
New integration skeletons also include response fixtures using `simulateResponseContractAsync`. Replace the generated
|
||||||
|
minimal schema and fixtures with representative upstream payloads: at least one successful response, important optional
|
||||||
|
or version-specific shapes, and a malformed response that must be rejected. The simulator uses the real parser without
|
||||||
|
network access and reports every fixture mismatch, so parser contracts can be reviewed before credentials are available.
|
||||||
|
|
||||||
|
### Review native feature states
|
||||||
|
|
||||||
|
In a development server, administrators can open `/manage/tools/feature-workbench` to inspect the shared `CatalogItem`
|
||||||
|
and integration response-contract fixtures. The workbench uses the application Mantine theme and the same segmented
|
||||||
|
fixture controls as the custom-widget preview. It covers ready, setup-required, standalone, connection-error, selected,
|
||||||
|
loading, disabled, parser-success, and parser-failure states without requiring a live service.
|
||||||
|
|
||||||
|
Use the workbench after changing shared catalog presentation or generated parser contracts, then run the focused test:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
WORKSHOP_API_URL=http://127.0.0.1:8090 pnpm dev:docs
|
pnpm exec vitest run "apps/nextjs/src/app/[locale]/manage/tools/feature-workbench/_feature-state-workbench.spec.tsx"
|
||||||
```
|
```
|
||||||
|
|
||||||
PocketBase runs on port 8090 and Docusaurus on port 3003. Stopping the services preserves the PocketBase volume.
|
The workbench is deliberately development-only and is not linked from management navigation. It does not yet exercise
|
||||||
|
real integration branding, long translated labels, right-to-left text, high-contrast screenshots, touch interaction,
|
||||||
|
small viewport clipping, live network latency, retry transitions, or service-specific response schemas. Those remain
|
||||||
|
manual review items until screenshot and browser-automation coverage is added.
|
||||||
|
|
||||||
Open `http://127.0.0.1:8090/_/` and create the first PocketBase superuser. The Workshop UI is available at
|
### Check one native feature
|
||||||
`http://127.0.0.1:3003/workshop`.
|
|
||||||
|
|
||||||
Point Homarr at the local services with:
|
Run `pnpm check:feature <kind>` before submitting an integration or widget change. The command resolves the kind through
|
||||||
|
`integrationDefs`, `widgetKinds`, the widget manifest, creator registry, documentation slug maps, and capability
|
||||||
```dotenv
|
descriptor. When an integration and widget share a kind, such as `wud`, both sides are checked together.
|
||||||
HOMARR_WEBSITE_URL=http://127.0.0.1:3003
|
|
||||||
WORKSHOP_API_URL=http://127.0.0.1:8090
|
|
||||||
WORKSHOP_WEB_URL=http://127.0.0.1:3003/workshop
|
|
||||||
```
|
|
||||||
|
|
||||||
Restart `pnpm dev` after changing `.env`. GitHub OAuth is optional locally. See
|
|
||||||
[`apps/workshop/README.md`](https://github.com/homarr-labs/homarr/blob/HEAD/apps/workshop/README.md) for OAuth,
|
|
||||||
Workshop moderator promotion, logs, tests, backup, restore, stopping, and intentional volume reset.
|
|
||||||
|
|
||||||
### URL testing
|
|
||||||
|
|
||||||
Docusaurus reads `HOMARR_WEBSITE_URL` and `WORKSHOP_API_URL` when it starts or builds. Homarr also reads
|
|
||||||
`WORKSHOP_WEB_URL` when its server starts, so these values do not rely on `NEXT_PUBLIC_*` build variables. Test a
|
|
||||||
separate API origin before release:
|
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
HOMARR_WEBSITE_URL=http://127.0.0.1:3003 \
|
pnpm check:feature wud --plan
|
||||||
WORKSHOP_API_URL=http://127.0.0.1:8090 \
|
pnpm check:feature wud
|
||||||
WORKSHOP_WEB_URL=http://127.0.0.1:3003/workshop \
|
|
||||||
pnpm dev:docs
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
`--plan` (or `--dry-run`) prints the deterministic affected files and commands without executing them. The normal mode
|
||||||
|
runs feature contracts, nearby fixture and unit tests, affected package typechecks, and lint and formatting for only the
|
||||||
|
resolved files. Unknown kinds fail before any command runs. Live-service, container, and visual checks are printed as
|
||||||
|
optional and are never executed implicitly because they may require credentials, images, or a running development app.
|
||||||
|
|
||||||
### Useful commands
|
### Useful commands
|
||||||
|
|
||||||
- `pnpm dev` — Next.js on port 3000.
|
- `pnpm dev` — Next.js on port 3000.
|
||||||
@@ -112,17 +134,17 @@ pnpm dev:docs
|
|||||||
- `pnpm dev:cli -- rebuild <name>` — rebuild an image from its recorded checkout or pull request.
|
- `pnpm dev:cli -- rebuild <name>` — rebuild an image from its recorded checkout or pull request.
|
||||||
- `pnpm dev:cli:install` — optionally install the developer CLI as a `homarr` binary.
|
- `pnpm dev:cli:install` — optionally install the developer CLI as a `homarr` binary.
|
||||||
- `pnpm dev:docs` — Docusaurus only on port 3003.
|
- `pnpm dev:docs` — Docusaurus only on port 3003.
|
||||||
- `pnpm docker:workshop` — local PocketBase through Docker Compose.
|
|
||||||
- `pnpm docker:dev:up` — Redis development service in the background.
|
- `pnpm docker:dev:up` — Redis development service in the background.
|
||||||
- `pnpm cli` — Homarr operations CLI.
|
- `pnpm cli` — Homarr operations CLI.
|
||||||
- `pnpm db:migration:sqlite:run` — create or update a SQLite database.
|
- `pnpm db:migration:sqlite:run` — create or update a SQLite database.
|
||||||
- `pnpm db:seed` — seed the default database data explicitly.
|
- `pnpm db:seed` — seed the default database data explicitly.
|
||||||
- `pnpm db:studio` — inspect the database.
|
- `pnpm db:studio` — inspect the database.
|
||||||
- `pnpm format` / `pnpm format:fix` — check or apply oxfmt.
|
- `pnpm format` / `pnpm format:fix` — check or apply oxfmt.
|
||||||
|
- `pnpm generate:feature` — scaffold a native integration, widget, or paired feature.
|
||||||
|
- `pnpm check:feature-contracts` — validate native feature registries, docs, translations, support maps, and exports.
|
||||||
- `pnpm lint` / `pnpm lint:fix` — check or apply oxlint.
|
- `pnpm lint` / `pnpm lint:fix` — check or apply oxlint.
|
||||||
- `pnpm typecheck` — typecheck all workspaces.
|
- `pnpm typecheck` — typecheck all workspaces.
|
||||||
- `pnpm test` — unit and contract suites.
|
- `pnpm test` — unit and contract suites.
|
||||||
- `pnpm test:workshop` — disposable Workshop integration suite.
|
|
||||||
- `pnpm build` — production monorepo build.
|
- `pnpm build` — production monorepo build.
|
||||||
- `docker build -t homarr .` — build a production Docker image.
|
- `docker build -t homarr .` — build a production Docker image.
|
||||||
- `docker run -p 7575:7575 -e SECRET_ENCRYPTION_KEY='your_64_character_hex_string' homarr:<name>` — run it.
|
- `docker run -p 7575:7575 -e SECRET_ENCRYPTION_KEY='your_64_character_hex_string' homarr:<name>` — run it.
|
||||||
@@ -37,6 +37,9 @@ Using the `PUID` and `PGID` will require you to set the correct permissions on t
|
|||||||
| `WORKSHOP_API_URL` | PocketBase API used by Homarr and standalone documentation. | HTTP(S) URL | `HOMARR_WEBSITE_URL` |
|
| `WORKSHOP_API_URL` | PocketBase API used by Homarr and standalone documentation. | HTTP(S) URL | `HOMARR_WEBSITE_URL` |
|
||||||
| `WORKSHOP_WEB_URL` | Public Workshop page opened from Homarr. | HTTP(S) URL | `HOMARR_WEBSITE_URL/workshop` |
|
| `WORKSHOP_WEB_URL` | Public Workshop page opened from Homarr. | HTTP(S) URL | `HOMARR_WEBSITE_URL/workshop` |
|
||||||
|
|
||||||
|
Workshop service operators can find its server-only configuration in the
|
||||||
|
[Workshop operator guide](../../workshop/operator#environment-variables).
|
||||||
|
|
||||||
## Authentication
|
## Authentication
|
||||||
|
|
||||||
See [Single Sign-On](/docs/advanced/single-sign-on) for more informations.
|
See [Single Sign-On](/docs/advanced/single-sign-on) for more informations.
|
||||||
@@ -55,11 +58,12 @@ A random secret can be generated by using the following command: `openssl rand -
|
|||||||
|
|
||||||
## Docker
|
## Docker
|
||||||
|
|
||||||
| Environment Variable | Description | Possible values | Default |
|
| Environment Variable | Description | Possible values | Default |
|
||||||
| --------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------- | ------- |
|
| --------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------- | ------- |
|
||||||
| `DOCKER_HOSTNAMES` | Comma-separated list of hostnames to connect to | For example `localhost,docker.example.com` | - |
|
| `DOCKER_ENDPOINTS` | JSON array of named, capability-scoped Docker or Podman endpoints. Supports socket, explicitly insecure TCP, and TLS transports. See the [Docker and Podman integration guide](/docs/integrations/docker) | A JSON array of endpoint descriptors | - |
|
||||||
| `DOCKER_PORTS` | Comma-separated list of ports to connect to | For example `2375,2376` | - |
|
| `DOCKER_HOSTNAMES` | Legacy comma-separated list of plaintext TCP hostnames. Ignored when `DOCKER_ENDPOINTS` is set | For example `localhost,docker.example.com` | - |
|
||||||
| `DOCKER_SOCKET_PATHS` | Comma-separated list of mounted Docker-compatible socket paths. See the [Docker and Podman integration guide](/docs/integrations/docker) | For example `/var/run/docker.sock,/var/run/podman.sock` | - |
|
| `DOCKER_PORTS` | Legacy comma-separated list of plaintext TCP ports. Ignored when `DOCKER_ENDPOINTS` is set | For example `2375,2376` | - |
|
||||||
|
| `DOCKER_SOCKET_PATHS` | Legacy comma-separated list of mounted Docker-compatible socket paths. Ignored when `DOCKER_ENDPOINTS` is set | For example `/var/run/docker.sock,/var/run/podman.sock` | - |
|
||||||
|
|
||||||
## Database
|
## Database
|
||||||
|
|
||||||
@@ -109,12 +113,9 @@ External redis is currently not supported with Proxmox Community Scripts
|
|||||||
The advanced deployments environment variables should only be used if you know what you are doing.
|
The advanced deployments environment variables should only be used if you know what you are doing.
|
||||||
:::
|
:::
|
||||||
|
|
||||||
| Environment Variable | Description |
|
| Environment Variable | Description |
|
||||||
| ------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
| ------------------------ | --------------------------------------------------- |
|
||||||
| `DB_MIGRATIONS_DISABLED` | Disable db migrations. For example for helm charts. |
|
| `DB_MIGRATIONS_DISABLED` | Disable db migrations. For example for helm charts. |
|
||||||
| `WORKSHOP_PUBLIC_ORIGIN` | Origin used in PocketBase-generated links and email. It must be set explicitly in production and must match the externally reachable Workshop origin. |
|
|
||||||
| `PB_ALLOWED_ORIGINS` | Browser origins accepted by PocketBase. Use `*` for the central public community so arbitrary self-hosted Homarr instances can use the API and OAuth; private staging may use a comma-separated origin allowlist. |
|
|
||||||
|
|
||||||
All public URL variables reject non-HTTP protocols, embedded credentials, query strings, and fragments, and normalize
|
All public URL variables reject non-HTTP protocols, embedded credentials, query strings, and fragments, and normalize
|
||||||
trailing slashes when Homarr or Docusaurus starts. The Docusaurus-only `WORKSHOP_URL` name is accepted as a deprecated alias for
|
trailing slashes when Homarr or Docusaurus starts.
|
||||||
`WORKSHOP_API_URL` for one release. `WORKSHOP_API_URL` takes precedence.
|
|
||||||
@@ -6,32 +6,14 @@ tags:
|
|||||||
|
|
||||||
Homarr has the following keyboard shortcuts:
|
Homarr has the following keyboard shortcuts:
|
||||||
|
|
||||||
| Shortcut | Description |
|
| Shortcut | Description |
|
||||||
| ----------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- |
|
| ----------------------------------------------- | ------------------------------------------ |
|
||||||
| `MOD` + `K` | Opens the search bar |
|
| `MOD` + `K` | Opens the search bar |
|
||||||
| `MOD` + `J` | Toggles Dark Mode |
|
| `MOD` + `J` | Toggles Dark Mode |
|
||||||
| `MOD` + `E` | Toggles Edit Mode |
|
| `MOD` + `E` | Toggles Edit Mode |
|
||||||
| Hold `Shift` for 500 ms over a supported widget | Opens its temporary advanced view |
|
| Hold `Shift` for 500 ms over a supported widget | Opens its temporary advanced view |
|
||||||
| `Shift` + `Enter` on a supported widget | Opens its advanced view until it is closed |
|
| `Shift` + `Enter` on a supported widget | Opens its advanced view until it is closed |
|
||||||
| `Esc` | Stops keyboard tile editing, cancels an active pointer or touch move/resize, or closes an open advanced view or board menu |
|
| `Esc` | Closes an open advanced view or board menu |
|
||||||
|
|
||||||
## Board editing
|
|
||||||
|
|
||||||
`MOD` + `E` enters edit mode. Homarr keeps the current board visible while the editor prepares; movement and resizing become available when it is ready.
|
|
||||||
|
|
||||||
When a tile is focused in edit mode:
|
|
||||||
|
|
||||||
| Shortcut | Description |
|
|
||||||
| -------------------- | --------------------------------------------------------------------------- |
|
|
||||||
| `Enter` or `Space` | Starts or stops keyboard editing |
|
|
||||||
| Arrow keys | Moves the focused tile within its current canvas, rail, or Container |
|
|
||||||
| `Shift` + Arrow keys | Resizes from the tile's lower-right corner: Left/Up shrink; Right/Down grow |
|
|
||||||
| `Esc` | Stops keyboard editing without undoing its changes |
|
|
||||||
|
|
||||||
Keyboard moves and resizes apply immediately. To move an item between a canvas, rail, or Container, drag it there or use **Move / resize item** for precise numeric placement.
|
|
||||||
Commands at a grid boundary or at the tile's minimum size are ignored and announced instead of moving or shrinking the tile.
|
|
||||||
|
|
||||||
On touch screens, press and hold a tile before moving it; a quick tap does not start a drag. Resize handles accept direct touch input. During a pointer or touch move or resize, `Esc` cancels the interaction and restores the layout from before it started.
|
|
||||||
|
|
||||||
:::tip
|
:::tip
|
||||||
|
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 38 KiB After Width: | Height: | Size: 39 KiB |
@@ -85,8 +85,8 @@ To do this, enter the board settings:
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
Scroll to the **Custom CSS** section on the board settings page. It is part of the unified settings form; enter your CSS
|
Scroll down a bit and click on custom CSS.
|
||||||
there and save the board settings to apply it to that board.
|
Here you can enter your CSS code, which will be applied on the respective board page.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"label": "Community",
|
"label": "Community",
|
||||||
"position": 5,
|
"position": 6,
|
||||||
"collapsed": true,
|
"collapsed": true,
|
||||||
"link": {
|
"link": {
|
||||||
"type": "generated-index"
|
"type": "generated-index"
|
||||||
|
|||||||
@@ -6,24 +6,10 @@ tags:
|
|||||||
- Configuration
|
- Configuration
|
||||||
---
|
---
|
||||||
|
|
||||||
import imageStartFromScratchStepServerSettings from "./img/onboarding-from-scratch-step-server-settings.png";
|
import manageBoardHeaderEditMode from "./img/manage-board-header-edit-mode.png";
|
||||||
import imageStartFromScratchStepAdminUser from "./img/onboarding-from-scratch-step-admin-user.png";
|
import manageBoardHeaderAddItem from "./img/manage-board-header-add-item-menu.png";
|
||||||
import imageStartFromScratchStepExternalAdminGroup from "./img/onboarding-from-scratch-step-external-admin-group.png";
|
import manageBoardHeaderChooseItem from "./img/manage-board-header-choose-item.png";
|
||||||
import imageStartFromScratchStepFinish from "./img/onboarding-from-scratch-step-finish.png";
|
|
||||||
import manageBoardNoApp from "./img/manage-board-no-app.png";
|
import manageBoardNoApp from "./img/manage-board-no-app.png";
|
||||||
import currentKeyboardTileEditing from "../management/boards/img/keyboard-tile-editing.png";
|
|
||||||
import boardDesktopCurrent from "./img/onboarding-board-desktop-current.png";
|
|
||||||
import boardEditModeCurrent from "./img/onboarding-board-edit-mode-current.png";
|
|
||||||
import addContentMenuCurrent from "./img/onboarding-add-content-menu-current.png";
|
|
||||||
import chooseItemCurrent from "./img/onboarding-choose-item-current.png";
|
|
||||||
import editItemCurrent from "./img/onboarding-edit-item-current.png";
|
|
||||||
import boardsHomeMobileMenu from "./img/onboarding-boards-home-mobile-menu.png";
|
|
||||||
import moveResizeMenuCurrent from "./img/onboarding-move-resize-menu-current.png";
|
|
||||||
import currentBoardMobileView from "./img/onboarding-board-mobile-current.png";
|
|
||||||
import manageExportOldHomarr from "./img/old-homarr-export-data.png";
|
|
||||||
import manageImportOldHomarrDropzone from "./img/old-homarr-import-dropzone.png";
|
|
||||||
import manageImportOldHomarrChooseData from "./img/old-homarr-import-choose-imported-data.png";
|
|
||||||
import manageImportDecryptionToken from "./img/old-homarr-import-decryption-token.png";
|
|
||||||
|
|
||||||
:::tip
|
:::tip
|
||||||
|
|
||||||
@@ -35,118 +21,50 @@ Congratulations on installing Homarr. Now it's time to get yourself familiar wit
|
|||||||
|
|
||||||
## Onboarding
|
## Onboarding
|
||||||
|
|
||||||
The onboarding will show the first time you start Homarr.
|
Onboarding appears the first time Homarr starts. Its goal is to create a useful responsive board, not merely an
|
||||||
This process will help you with your first steps and adding some initial data, such as the administrator account.
|
administrator account. The setup uses one guided studio, so you can keep the safe defaults and finish quickly or review
|
||||||
|
every detected service before anything is added to the board.
|
||||||
|
|
||||||
:::note
|
:::note
|
||||||
|
|
||||||
If you see this screen repeatedly after you restart the Homarr container, your Docker mounting paths may be missing,
|
If you see this screen repeatedly after restarting the Homarr container, your Docker mounting paths may be missing,
|
||||||
incorrect or read-only. Read [our installation instructions](/docs/getting-started/installation/docker) again to fix this issue.
|
incorrect or read-only. Read [our installation instructions](/docs/getting-started/installation/docker) again to fix this issue.
|
||||||
|
|
||||||
:::
|
:::
|
||||||
|
|
||||||
You can either import a previous dashboard using the ZIP archive or start from scratch:
|
### Restore or start fresh
|
||||||
|
|
||||||

|
SQLite installations can restore a complete Homarr database backup from the welcome screen. This restores current
|
||||||
|
boards, people, apps, integrations, and settings. The pre-1.0 ZIP importer is no longer included.
|
||||||
|
|
||||||
You may refresh anytime and continue from a different device - the onboarding is saved immediately on the server for your convenience.
|
For a new installation, Homarr first creates either a credentials administrator or an administrator group matching your
|
||||||
|
LDAP/OIDC provider. The browser that starts setup claims the first-run session; refreshes are safe, while another browser
|
||||||
|
cannot change credentials or integrations during that setup.
|
||||||
|
|
||||||
### Starting from scratch
|
### Setup studio
|
||||||
|
|
||||||
Depending on your auth provider configuration you will either first see the admin user creation form or the external group creation form.
|
The studio keeps related choices together:
|
||||||
If the credentials provider was selected, you'll be prompted to create an admin user for Homarr.
|
|
||||||
This user cannot be deleted and has full control over Homarr and all of its boards.
|
|
||||||
You must choose a username and password (both can later be changed).
|
|
||||||
We enforce strict password requirements when you enter your password to protect your instance if you accidentally
|
|
||||||
expose it to the internet.
|
|
||||||
|
|
||||||
<img src={imageStartFromScratchStepAdminUser} alt={"Screenshot form to create admin user"} width={300} />
|
1. **Essentials** sets the default language, color scheme, analytics preference, and the usual host, IP address, domain, or reverse-proxy path used by your services. URL suggestions can use separate ports, subdomains, or one path per service.
|
||||||
|
2. **Discover** checks the actual database, Docker-compatible sockets, Kubernetes configuration, Workshop, and Assistant capabilities. Unavailable sources never block manual setup.
|
||||||
|
3. **Connect** shows detected integrations and apps first, identifying whether each app came from an explicit [`homarr.*` or Homepage Docker label](/docs/integrations/docker-labels) or image matching. Select several integrations and apps at once, review every URL, and use the service-specific link to open its API-key settings when one is available. If a container has no published port or URL label, add its HTTP or HTTPS address before importing it.
|
||||||
|
4. **Board** previews the Base layout, colors, widget radius, sidebars, selected apps, and widgets inferred from integrations or Docker labels. Choose 8 columns for a focused board, 10 for a balanced board, 12 for a wide board, or use the slider for a custom width up to 24 columns. Homarr still creates and reflows the protected Mobile layout automatically. A fast setup adds the integration-free Clock, Weather, and Bookmarks starter widgets.
|
||||||
|
5. **Extend** explains and optionally configures Homarr Assistant, the community Workshop, and the separate Homarr MCP endpoint.
|
||||||
|
6. **Review** tests the selected connections, then saves integrations, apps, widgets, settings, and the exact first board together. If any part fails, the database changes are rolled back and your form stays available to correct.
|
||||||
|
|
||||||
If you selected external providers (such as LDAP or OIDC), you'll be prompted to create an admin group.
|
Docker discovery reports each configured host separately. Results from reachable hosts remain selectable if another socket
|
||||||
This group will be used to synchronize users from your provider to Homarr.
|
is unavailable, which is useful for remote Docker, rootless Docker, Synology, and mixed deployments. On Kubernetes or
|
||||||
When a user logs in through the provider, any of their groups that match groups in Homarr will be assigned to the user.
|
bare-metal installations without a Docker socket, enter services manually and use the same integration catalog.
|
||||||
The name of the group must match exactly the name of the group in the provider.
|
|
||||||
|
|
||||||
<img
|
After setup, **Open my board** takes you directly to the configured board. The in-product tour then introduces edit mode,
|
||||||
src={imageStartFromScratchStepExternalAdminGroup}
|
responsive layouts, widgets, and search without delaying completion.
|
||||||
alt={"Screenshot form to create external admin group"}
|
|
||||||
width={300}
|
|
||||||
/>
|
|
||||||
|
|
||||||
Next, you can configure some basic settings for Homarr. We recommend to leave all settings at default for most users.
|
## Creating another board
|
||||||
Here you can also disable analytics. Please note that our analytics are completely anonymous and fully compliant with GDPR and PECR.
|
|
||||||
|
|
||||||
<img
|
|
||||||
src={imageStartFromScratchStepServerSettings}
|
|
||||||
alt={"Screenshot of analytics and indexing settings in the onboarding"}
|
|
||||||
width={300}
|
|
||||||
/>
|
|
||||||
|
|
||||||
### Setting up integrations
|
|
||||||
|
|
||||||
After configuring server settings, the onboarding guides you through setting up your integrations.
|
|
||||||
|
|
||||||
#### Docker service discovery
|
|
||||||
|
|
||||||
If Docker is available (socket mounted), Homarr automatically detects running containers and matches them to known integration types.
|
|
||||||
Matching integrations are pre-selected in the integration list, saving you from manually picking each one.
|
|
||||||
|
|
||||||
#### URL templating
|
|
||||||
|
|
||||||
You can define a base URL template to auto-fill integration URLs in bulk.
|
|
||||||
Two modes are supported:
|
|
||||||
|
|
||||||
- **Subdomain mode** - e.g. `{app}.example.com` where `{app}` is replaced with the integration name
|
|
||||||
- **Port mode** - e.g. `192.168.1.1:{port}` where `{port}` is replaced with the integration's default port
|
|
||||||
|
|
||||||
#### API key helper links
|
|
||||||
|
|
||||||
For integrations that require API keys (such as Sonarr, Radarr, SABnzbd, or Seerr), a helper link opens the relevant settings page in the target application so you can quickly copy your key.
|
|
||||||
|
|
||||||
#### Creating apps from Docker containers
|
|
||||||
|
|
||||||
You can optionally auto-create bookmark apps for all discovered Docker containers, making them immediately available on your board.
|
|
||||||
|
|
||||||
:::note
|
|
||||||
|
|
||||||
Release providers and Search.ch are configured directly in their widgets instead of the integrations page.
|
|
||||||
|
|
||||||
:::
|
|
||||||
|
|
||||||
After this step, you finished the onboarding.
|
|
||||||
The onboarding can no longer be started again.
|
|
||||||
From here you can click on one of the provided links to continue your journey.
|
|
||||||
We recommend you to continue with the section [creating your first board on this page](#creating-your-first-board).
|
|
||||||
|
|
||||||
<img src={imageStartFromScratchStepFinish} alt={"Screenshot of the finish onboarding process with links"} width={300} />
|
|
||||||
|
|
||||||
### Importing a ZIP from version before 1.0.0
|
|
||||||
|
|
||||||
This is recommended when you used Homarr before and want to re-import your data.
|
|
||||||
It is important that you first migrate correctly using [the list of breaking changes for 1.0](/blog/2024/09/23/version-1.0).
|
|
||||||
|
|
||||||
<img src={manageExportOldHomarr} alt="Export from old Homarr" style={{ maxWidth: 500 }} />
|
|
||||||
|
|
||||||
**How to export and import data**
|
|
||||||
|
|
||||||
1. Navigate to your old Homarr, open your management pages, open the tools submenu and open `Migrate to 1.0`.
|
|
||||||
2. Check the contents that you want to export. We recommend you to export all data.
|
|
||||||
3. Click on the export data button
|
|
||||||
4. Save the downloaded ZIP file on your device. If you selected "integrations" or "users", you also get an encryption / decryption key.
|
|
||||||
Copy it and keep it safe; you need it later in the import flow.
|
|
||||||
5. Go to your new Homarr 1.0 or later instance and start the onboarding. Choose `Import from Homarr before 1.0`.
|
|
||||||
6. Drag and drop your previously downloaded ZIP archive into the file upload: <br/><img src={manageImportOldHomarrDropzone} style={{ maxWidth: 500 }} />
|
|
||||||
7. Next, choose the data that you want to import and how to import it. Old Homarr screen sizes are imported as responsive layouts on the same board: the narrowest becomes **Mobile**, the widest becomes **Base**, and layouts between them become custom layouts. Homarr normalizes duplicate breakpoints automatically, so you can review the imported board in Board Settings and adjust the layouts there.<br/><img src={manageImportOldHomarrChooseData} style={{ maxWidth: 500 }} />
|
|
||||||
For example, legacy `sm`, `md`, and `lg` layouts at `0px`, `800px`, and `1400px` become Mobile, a custom layout, and Base. The imported board keeps each layout's positions, names, and column counts where possible so you can review the result before saving. If a board has one saved layout, Homarr keeps it as Base and generates Mobile from it; a board without saved layouts receives Mobile at `0px` with 3 columns and Base at `768px` with 10 columns.
|
|
||||||
8. If you previously exported integrations or users, you will be asked to decrypt the data safely using your obtained encryption token. Paste into the modal and confirm your action.<br/><img src={manageImportDecryptionToken} style={{ maxWidth: 500 }} />
|
|
||||||
9. Next, you can [follow the same setup as when starting from scratch](#starting-from-scratch). After you completed the onboarding, all of your data will be migrated and available.
|
|
||||||
|
|
||||||
## Creating your first board
|
|
||||||
|
|
||||||
In Homarr, you organize your apps and widgets on boards.
|
In Homarr, you organize your apps and widgets on boards.
|
||||||
Boards use fixed-size tiles so the same widget keeps the same proportions on every screen.
|
Boards use fixed-size tiles so the same widget keeps the same proportions on every screen.
|
||||||
Drag, resize, and section controls are available in edit mode.
|
Drag, resize, and section controls are available in edit mode.
|
||||||
Let's create your first board by navigating here: `Manage` > `Boards` > `New board`:
|
Onboarding already created the first board. To create another one, navigate to `Manage` > `Boards` > `New board`:
|
||||||

|

|
||||||
|
|
||||||
A board must always have a name and can either be public or private.
|
A board must always have a name and can either be public or private.
|
||||||
@@ -154,25 +72,9 @@ Public boards are also accessible for users, that are not logged in ([see access
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
Congratulations - you've just created your first board. You can see the boards you have access to on this page:
|
Congratulations - you've just created your first board. You can see boards, that you have access to, on this page:
|
||||||
|
|
||||||
<figure>
|

|
||||||
<img
|
|
||||||
src={boardsHomeMobileMenu}
|
|
||||||
alt="Boards management page showing a Home badge and separate desktop and mobile home-board menu entries"
|
|
||||||
style={{ maxWidth: "100%" }}
|
|
||||||
/>
|
|
||||||
<figcaption>The Boards page selects the board opened from Home separately for desktop and mobile.</figcaption>
|
|
||||||
</figure>
|
|
||||||
|
|
||||||
The board marked **Home** is the board opened from the desktop Home route. **Set as your mobile board** selects which board
|
|
||||||
opens on phones. This is separate from the **Mobile** layout: the home-board setting chooses a board, while **Mobile** and
|
|
||||||
**Base** are responsive layouts inside that board. A phone can therefore open a different home board and still use that
|
|
||||||
board's Mobile layout.
|
|
||||||
|
|
||||||
New boards start with **Mobile** and **Base** responsive layouts automatically, so you can edit the board for phones and
|
|
||||||
desktops without creating extra layouts first. Mobile starts at `0px` with 3 columns and Base at `768px` with 10 columns.
|
|
||||||
Each layout keeps its own tile positions and sizes.
|
|
||||||
|
|
||||||
## Add your first app to Homarr
|
## Add your first app to Homarr
|
||||||
|
|
||||||
@@ -196,63 +98,37 @@ After you created the app, you'll see in on the apps page:
|
|||||||
Let's add your freshly created app, from the previous step, to the board.
|
Let's add your freshly created app, from the previous step, to the board.
|
||||||
To do this, edit your previously created board by clicking on the big `Open board` button:
|
To do this, edit your previously created board by clicking on the big `Open board` button:
|
||||||
|
|
||||||
<figure>
|

|
||||||
<img src={boardDesktopCurrent} alt="Current Homarr board opened from the Boards page" style={{ maxWidth: "100%" }} />
|
|
||||||
<figcaption>Open a board to view its dashboard, then enter edit mode to arrange its content.</figcaption>
|
|
||||||
</figure>
|
|
||||||
|
|
||||||
Here you have the following options in the header:
|
Here you have the following options in the header:
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
- **Search**: Here you can search for data. You can search for integrations, boards, actions, sites and much more. Some actions may be context dependent (eg. will only show when certain widgets are on your page)
|
- **Search**: Here you can search for data. You can search for integrations, boards, actions, sites and much more. Some actions may be context dependent (eg. will only show when certain widgets are on your page)
|
||||||
- **Edit board**: Clicking this button will toggle edit mode. In this mode you can edit the contents of your board.
|
- **Edit mode**: Clicking this button will toggle the edit mode. In this mode you can edit the contents of your board.
|
||||||
- **Settings**: Clicking this button will redirect you to a settings page where you can adjust the board settings (page title, colors, ...).
|
- **Settings**: Clicking this button will redirect you to a settings page where you can adjust the board settings (page title, colors, ...).
|
||||||
- **Board switcher**: Use this button to open another board that you can access.
|
|
||||||
- **Profile**: This avatar will be visible on every page. Clicking it will show a menu with actions.
|
- **Profile**: This avatar will be visible on every page. Clicking it will show a menu with actions.
|
||||||
|
|
||||||
When entering the edit mode, you'll get some additional buttons to work with:
|
When entering the edit mode, you'll get some additional buttons to work with:
|
||||||
|
|
||||||
<figure>
|
<img src={manageBoardHeaderEditMode} alt={"Screenshot of buttons in the edit mode"} width={200} />
|
||||||
<img
|
|
||||||
src={boardEditModeCurrent}
|
|
||||||
alt="Current Homarr board editor with tile controls visible"
|
|
||||||
style={{ maxWidth: "100%" }}
|
|
||||||
/>
|
|
||||||
<figcaption>The current editor keeps the board visible while its editing controls are available.</figcaption>
|
|
||||||
</figure>
|
|
||||||
|
|
||||||
- **Add board content**: Click this button to create a new item, app, integration, or Container.
|
- **Add item**: Click this button to add new elements to your page.
|
||||||
- **Save board**: Click this button to save your changes and leave edit mode. If you leave with unsaved changes, Homarr asks whether to discard them.
|
- **Exit edit mode**: Click this button to save your changes and exit edit mode.
|
||||||
|
|
||||||
Outside edit mode, right-click a widget for its live status, refresh, settings, quick options, and supported actions.
|
Outside edit mode, right-click a widget for its live status, refresh, settings, quick options, and supported actions.
|
||||||
Hold `Shift` while hovering a widget that supports advanced view to expand it in place while the rest of the board
|
Hold `Shift` while hovering a widget that supports advanced view to expand it in place while the rest of the board
|
||||||
stays visible but dimmed. Release `Shift` to close it. You can also focus that widget and press `Shift` + `Enter` to
|
stays visible but dimmed. Release `Shift` to close it. You can also focus that widget and press `Shift` + `Enter` to
|
||||||
keep its advanced view open until you close it. Widgets without a distinct advanced experience adapt in place.
|
keep its advanced view open until you close it. Widgets without a distinct advanced experience adapt in place.
|
||||||
|
|
||||||
To continue, click **New item** in the add-content menu. New content is placed at the first available position on the main
|
To continue, click the option "New Item":
|
||||||
canvas; it is not inserted at a clicked empty cell or directly into a rail or Container:
|
|
||||||
|
|
||||||
<figure>
|
<img src={manageBoardHeaderAddItem} alt={"Screenshot of the add item menu"} width={200} />
|
||||||
<img
|
|
||||||
src={addContentMenuCurrent}
|
|
||||||
alt="Current add board content menu with item, app, integration, and Container actions"
|
|
||||||
style={{ maxWidth: "100%" }}
|
|
||||||
/>
|
|
||||||
<figcaption>The add-content menu provides the four supported ways to place new content on the board.</figcaption>
|
|
||||||
</figure>
|
|
||||||
|
|
||||||
Next, you can choose what item you'd like to add.
|
Next, you can choose what item you'd like to add.
|
||||||
We will discuss the other options in the following sections - for now choose "App" to continue.
|
We will discuss the other options in the following sections - for now choose "App" to continue.
|
||||||
|
|
||||||
<figure>
|
<img src={manageBoardHeaderChooseItem} alt={"Screenshot of choosing the app item in the modal"} width={300} />
|
||||||
<img
|
|
||||||
src={chooseItemCurrent}
|
|
||||||
alt="Current item picker showing the App card and other item types"
|
|
||||||
style={{ maxWidth: "100%" }}
|
|
||||||
/>
|
|
||||||
<figcaption>Choose the App item from the current picker to add an app tile.</figcaption>
|
|
||||||
</figure>
|
|
||||||
|
|
||||||
As soon as you chose the app, the modal will close and you'll get the following item on your board:
|
As soon as you chose the app, the modal will close and you'll get the following item on your board:
|
||||||
|
|
||||||
@@ -261,52 +137,30 @@ As soon as you chose the app, the modal will close and you'll get the following
|
|||||||
This is expected, because you haven't told Homarr what app it should show in this item.
|
This is expected, because you haven't told Homarr what app it should show in this item.
|
||||||
To configure this, click on the small 3 dots at the top of the item in the edit mode and choose "Edit item" in the menu.
|
To configure this, click on the small 3 dots at the top of the item in the edit mode and choose "Edit item" in the menu.
|
||||||
|
|
||||||
<figure>
|

|
||||||
<img
|
|
||||||
src={moveResizeMenuCurrent}
|
|
||||||
alt="Current board tile menu showing Edit item and Move or resize item"
|
|
||||||
style={{ maxWidth: "450px" }}
|
|
||||||
/>
|
|
||||||
<figcaption>The tile menu contains the item editor and the separate move-and-resize tools.</figcaption>
|
|
||||||
</figure>
|
|
||||||
|
|
||||||
In the modal you can edit the app that you want to display:
|
In the modal you can edit the app that you want to display:
|
||||||
|
|
||||||
<figure>
|

|
||||||
<img src={editItemCurrent} alt="Current Edit item modal for an App tile" style={{ maxWidth: "620px" }} />
|
|
||||||
<figcaption>Use the Edit item modal to choose the app and configure how its tile is displayed.</figcaption>
|
|
||||||
</figure>
|
|
||||||
|
|
||||||
As soon as you save your changes, the tile on the board will refresh and display your app.
|
As soon as you save your changes, the tile on the board will refresh and display your app.
|
||||||
Resize from any visible edge or corner handle. For a Container, activate its top-left grip before using its resize handles.
|
Use the resize handle at the bottom right to resize the tile.
|
||||||
Press and hold a handle, move the pointer, and release it when the tile has the size you want.
|
Press and hold the handle, move the pointer, and release it when the tile has the size you want.
|
||||||
|
|
||||||
To move a tile in edit mode, press and hold its inert content area, move it to the desired position, and release it.
|

|
||||||
|
|
||||||
|
To move a tile in edit mode, press and hold its content, move it to the desired position, and release it.
|
||||||
Widget content is disabled while editing so its controls do not intercept the drag; use the tile's settings button for edit actions.
|
Widget content is disabled while editing so its controls do not intercept the drag; use the tile's settings button for edit actions.
|
||||||
The tile snaps to the grid. A single compatible collision may swap the two items when both resulting placements fit;
|
The tile snaps to the grid. Equally-sized tiles swap when one is dropped into the other's slot, while other neighboring tiles move out of the way automatically.
|
||||||
otherwise the collision chain reflows neighboring tiles automatically.
|
|
||||||
|

|
||||||
|
|
||||||
Every `1 × 1` tile has a logical content size of `200 × 200` pixels.
|
Every `1 × 1` tile has a logical content size of `200 × 200` pixels.
|
||||||
Larger tiles use multiples of that fixed unit, with a consistent gap between cells.
|
Larger tiles use multiples of that fixed unit, with a consistent gap between cells.
|
||||||
Homarr scales the complete board uniformly, like zooming a page.
|
Homarr scales the complete board uniformly, like zooming a page.
|
||||||
The complete canvas always fits the available width without horizontal board scrolling. Below 100%, Homarr preserves the
|
It stops shrinking at 75% and lets you scroll horizontally instead of making text and controls too small.
|
||||||
widget's readable typography and control density instead of shrinking each widget independently.
|
|
||||||
It does not squeeze or reflow the content of individual widgets, so a widget keeps the same design and proportions across screen sizes.
|
It does not squeeze or reflow the content of individual widgets, so a widget keeps the same design and proportions across screen sizes.
|
||||||
|
|
||||||
On a narrow screen, Homarr uses the **Mobile layout** for the selected board and stacks the board content vertically while
|
|
||||||
preserving each widget's fixed logical proportions:
|
|
||||||
|
|
||||||
<figure>
|
|
||||||
<img
|
|
||||||
src={currentBoardMobileView}
|
|
||||||
alt="Homarr's Mobile layout in a 390-pixel-wide viewport, with tiles scaled to fit and stacked vertically"
|
|
||||||
style={{ maxWidth: "390px" }}
|
|
||||||
/>
|
|
||||||
<figcaption>
|
|
||||||
At phone width, the selected board uses its Mobile layout and fits the complete canvas to the viewport.
|
|
||||||
</figcaption>
|
|
||||||
</figure>
|
|
||||||
|
|
||||||
:::note
|
:::note
|
||||||
|
|
||||||
Viewing a board initially uses the lightweight, non-interactive layout.
|
Viewing a board initially uses the lightweight, non-interactive layout.
|
||||||
@@ -322,17 +176,16 @@ This helps you to explore the capabilities of Homarr before you build your board
|
|||||||
|
|
||||||
:::
|
:::
|
||||||
|
|
||||||
Keyboard users can focus a tile, press Enter or Space, then use arrow keys to move and Shift plus arrow keys to resize
|
Keyboard users can focus a tile, press Enter or Space, then use arrow keys to move and Shift plus arrow keys to resize.
|
||||||
within its current canvas, rail, or Container. Press Escape to stop keyboard editing. Touch dragging starts after a short
|
Press Escape to stop.
|
||||||
hold of about `200 ms`; resize handles accept direct touch input. During a pointer or touch move or resize, press Escape
|
For precise numeric controls or touch input, choose **Move / resize item** from the tile's edit menu.
|
||||||
to cancel and restore the previous layout. For cross-grid moves or precise numeric controls, choose **Move / resize item**
|
The dialog can also move the tile to another section or fixed sidebar:
|
||||||
from the tile's edit menu.
|
|
||||||
Keyboard commands at a grid boundary or minimum tile size are ignored and announced; they do not move or shrink the tile.
|
|
||||||
|
|
||||||
<img src={currentKeyboardTileEditing} alt="A board tile focused for keyboard editing" style={{ maxWidth: "100%" }} />
|

|
||||||
|
|
||||||
Open **Move / resize item** from the tile menu to move the tile to another section or rail and enter precise numeric
|
Be sure to save your changes by exiting edit mode!
|
||||||
coordinates and dimensions. After making changes, click **Save board** to persist them and leave edit mode.
|
|
||||||
|

|
||||||
|
|
||||||
## Adding your first integration
|
## Adding your first integration
|
||||||
|
|
||||||
@@ -367,14 +220,7 @@ Let's add your integration, that you have configured in the section above, as a
|
|||||||
First, navigate back to your board that you want to add it to.
|
First, navigate back to your board that you want to add it to.
|
||||||
Next, enter edit mode again and add another item to your board:
|
Next, enter edit mode again and add another item to your board:
|
||||||
|
|
||||||
<figure>
|

|
||||||
<img
|
|
||||||
src={addContentMenuCurrent}
|
|
||||||
alt="Current add board content menu with item, app, integration, and Container actions"
|
|
||||||
style={{ maxWidth: "100%" }}
|
|
||||||
/>
|
|
||||||
<figcaption>Use the same add-content menu to place an integration widget on the board.</figcaption>
|
|
||||||
</figure>
|
|
||||||
|
|
||||||
Instead of choosing an app, let's choose `System Health Monitoring` this time.
|
Instead of choosing an app, let's choose `System Health Monitoring` this time.
|
||||||
Click on "Add to board":
|
Click on "Add to board":
|
||||||
@@ -401,7 +247,9 @@ Editing a widget will trigger a data update and data will soon appear:
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
As with every change, click **Save board** to persist your board changes and leave edit mode.
|
As with every change, don't forget to save your changes using the exit edit mode button:
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
## Organizing items with Containers
|
## Organizing items with Containers
|
||||||
|
|
||||||
@@ -414,7 +262,7 @@ Each Container can configure:
|
|||||||
- Show or hide **Open all in new tabs**.
|
- Show or hide **Open all in new tabs**.
|
||||||
- Change its border color and custom CSS classes.
|
- Change its border color and custom CSS classes.
|
||||||
|
|
||||||
Open the add-content menu and choose **New container**.
|
Open the add-content menu and choose **New Container**.
|
||||||
In edit mode, move and resize it like any other item, then drag items into or out of it.
|
In edit mode, move and resize it like any other item, then drag items into or out of it.
|
||||||
Nested content stays within the Container's bounds.
|
Nested content stays within the Container's bounds.
|
||||||
While resizing, the solid outline follows the pointer continuously and the dashed grid preview shows the size that will be saved on release.
|
While resizing, the solid outline follows the pointer continuously and the dashed grid preview shows the size that will be saved on release.
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 561 KiB |
|
Before Width: | Height: | Size: 101 KiB After Width: | Height: | Size: 6.2 KiB |
|
Before Width: | Height: | Size: 9.5 KiB After Width: | Height: | Size: 3.2 KiB |
|
Before Width: | Height: | Size: 9.2 KiB After Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 97 KiB |
|
Before Width: | Height: | Size: 132 KiB |
|
Before Width: | Height: | Size: 115 KiB |
|
Before Width: | Height: | Size: 60 KiB |
|
Before Width: | Height: | Size: 34 KiB |
|
Before Width: | Height: | Size: 177 KiB |
|
Before Width: | Height: | Size: 68 KiB |
|
Before Width: | Height: | Size: 33 KiB |
@@ -0,0 +1,95 @@
|
|||||||
|
---
|
||||||
|
title: "Docker labels"
|
||||||
|
description: "Discover apps, integrations, and widgets from container labels during Homarr onboarding."
|
||||||
|
---
|
||||||
|
|
||||||
|
# Docker label discovery
|
||||||
|
|
||||||
|
During onboarding, Homarr scans running containers on every reachable
|
||||||
|
[Docker-compatible host](/docs/integrations/docker). Labels let you provide exact app metadata instead of relying on
|
||||||
|
image-name matching. You can review and deselect every result before Homarr creates anything.
|
||||||
|
|
||||||
|
A container with valid Homarr labels takes priority over image-based discovery. Containers without valid labels can
|
||||||
|
still be suggested from their image and published ports.
|
||||||
|
|
||||||
|
## Homarr labels
|
||||||
|
|
||||||
|
`homarr.name` and `homarr.href` are required for label discovery. All other labels are optional.
|
||||||
|
|
||||||
|
| Label | Purpose |
|
||||||
|
| -------------------- | -------------------------------------------------------------------------- |
|
||||||
|
| `homarr.name` | App or integration display name |
|
||||||
|
| `homarr.href` | Address opened by the app and used as the suggested integration address |
|
||||||
|
| `homarr.group` | Container section that receives the selected app and compatible widget |
|
||||||
|
| `homarr.icon` | App icon URL |
|
||||||
|
| `homarr.description` | App description |
|
||||||
|
| `homarr.ping` | Address used for app status checks |
|
||||||
|
| `homarr.id` | Stable source identifier; defaults to the Docker container ID |
|
||||||
|
| `homarr.board` | Intended board name; see [Board targeting](#board-targeting) |
|
||||||
|
| `homarr.integration` | Homarr integration kind, for example `sonarr` |
|
||||||
|
| `homarr.widget` | Homarr widget kind to add when it supports the selected integration |
|
||||||
|
| `homarr.hide` | Excludes the container when this label is present, regardless of its value |
|
||||||
|
|
||||||
|
Unknown integration and widget kinds are ignored. Do not put API keys, passwords, or other secrets in labels. Enter
|
||||||
|
credentials in onboarding, where Homarr stores them using its normal encrypted integration-secret flow.
|
||||||
|
|
||||||
|
## Compose example
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
services:
|
||||||
|
sonarr:
|
||||||
|
image: lscr.io/linuxserver/sonarr:latest
|
||||||
|
labels:
|
||||||
|
homarr.name: "Sonarr"
|
||||||
|
homarr.href: "http://server.local:8989"
|
||||||
|
homarr.group: "Media"
|
||||||
|
homarr.icon: "https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/svg/sonarr.svg"
|
||||||
|
homarr.description: "TV library"
|
||||||
|
homarr.ping: "http://server.local:8989"
|
||||||
|
homarr.integration: "sonarr"
|
||||||
|
homarr.widget: "calendar"
|
||||||
|
```
|
||||||
|
|
||||||
|
Use an address that is reachable where it is needed. A Docker service name can work for server-side integration
|
||||||
|
requests, while an app link opened in a browser usually needs a LAN hostname, IP address, or reverse-proxy address.
|
||||||
|
Onboarding accepts these self-hosted address formats directly and only requires the field to be non-empty.
|
||||||
|
|
||||||
|
## Homepage label fallback
|
||||||
|
|
||||||
|
When `homarr.name` is absent, onboarding also understands these Homepage labels:
|
||||||
|
|
||||||
|
- `homepage.name`
|
||||||
|
- `homepage.href`
|
||||||
|
- `homepage.group`
|
||||||
|
- `homepage.icon`
|
||||||
|
- `homepage.description`
|
||||||
|
|
||||||
|
`homepage.name` and `homepage.href` are required for the fallback. Homarr does not combine partial Homarr metadata with
|
||||||
|
Homepage metadata: once `homarr.name` is present, use `homarr.*` labels for the remaining fields too.
|
||||||
|
|
||||||
|
## What onboarding creates
|
||||||
|
|
||||||
|
In **Connect**, label-discovered apps and integrations appear before image-based suggestions. You can import multiple
|
||||||
|
services in one pass and edit every suggested address. For image-matched apps, Homarr uses the detected service type
|
||||||
|
when building host, subdomain, or reverse-proxy path suggestions.
|
||||||
|
|
||||||
|
When setup completes, Homarr rechecks the selected container sources and then:
|
||||||
|
|
||||||
|
- creates an app with its name, address, icon, description, and ping address;
|
||||||
|
- creates the requested integration and links its app after you provide required credentials;
|
||||||
|
- places grouped apps in a board container named by `homarr.group`;
|
||||||
|
- places ungrouped apps in the main board area;
|
||||||
|
- adds `homarr.widget` only when the widget kind is valid and compatible with the selected integration;
|
||||||
|
- keeps image-based discovery available for unlabeled containers.
|
||||||
|
|
||||||
|
If a selected container disappears, targets another board, or requests an incompatible widget, setup finishes with a
|
||||||
|
warning instead of creating an invalid board item.
|
||||||
|
|
||||||
|
## Board targeting
|
||||||
|
|
||||||
|
On a fresh installation with one seeded `dashboard` board, one unique selected `homarr.board` value can name that first
|
||||||
|
board. Otherwise, the label must match the board selected in onboarding. Services labeled for another board are skipped
|
||||||
|
and reported in the completion warning.
|
||||||
|
|
||||||
|
Onboarding configures one board at a time. Run normal board management after setup if you want to distribute services
|
||||||
|
across several boards.
|
||||||
@@ -122,9 +122,77 @@ services:
|
|||||||
DOCKER_SOCKET_PATHS: /var/run/docker.sock,/var/run/podman.sock
|
DOCKER_SOCKET_PATHS: /var/run/docker.sock,/var/run/podman.sock
|
||||||
```
|
```
|
||||||
|
|
||||||
|
For named endpoints, transport security, or least-privilege actions, prefer `DOCKER_ENDPOINTS`. It is a JSON array where every endpoint declares its identity, transport, and capabilities:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
services:
|
||||||
|
homarr:
|
||||||
|
volumes:
|
||||||
|
- /var/run/docker.sock:/var/run/docker.sock
|
||||||
|
- ./docker-ca.pem:/run/secrets/docker-ca.pem:ro
|
||||||
|
environment:
|
||||||
|
DOCKER_ENDPOINTS: >-
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"id": "local",
|
||||||
|
"name": "Local Docker",
|
||||||
|
"kind": "docker",
|
||||||
|
"transport": { "type": "socket", "path": "/var/run/docker.sock" },
|
||||||
|
"capabilities": ["inventory", "logs", "lifecycle", "remove"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "remote-read-only",
|
||||||
|
"name": "Production inventory",
|
||||||
|
"kind": "docker",
|
||||||
|
"transport": {
|
||||||
|
"type": "tls",
|
||||||
|
"host": "docker.example.com",
|
||||||
|
"port": 2376,
|
||||||
|
"caPath": "/run/secrets/docker-ca.pem"
|
||||||
|
},
|
||||||
|
"capabilities": ["inventory", "logs"]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
The stable `id` keeps containers from different endpoints distinct. `name` is shown in the interface, and `kind` can be `docker` or `podman`. Every endpoint must include the `inventory` capability; optionally add `logs`, `lifecycle`, and `remove`. Homarr hides or disables actions the endpoint does not allow and also enforces the same capabilities on the server.
|
||||||
|
|
||||||
|
Supported transports are:
|
||||||
|
|
||||||
|
- `socket`: an absolute in-container `path`
|
||||||
|
- `tls`: `host`, `port`, and an absolute `caPath`; add both `certPath` and `keyPath` for mutual TLS
|
||||||
|
- `tcp`: `host`, `port`, and the explicit acknowledgement `allowInsecure: true`
|
||||||
|
|
||||||
|
:::warning[Plaintext TCP]
|
||||||
|
Plaintext Docker TCP can grant unauthenticated control of the Docker host. Prefer a local socket, a least-privilege socket proxy, or TLS. The structured configuration refuses TCP unless `allowInsecure` is explicitly set to `true`.
|
||||||
|
:::
|
||||||
|
|
||||||
|
When `DOCKER_ENDPOINTS` is set, it takes precedence over the legacy `DOCKER_SOCKET_PATHS`, `DOCKER_HOSTNAMES`, and `DOCKER_PORTS` variables.
|
||||||
|
|
||||||
### Managing your Docker containers within Homarr
|
### Managing your Docker containers within Homarr
|
||||||
|
|
||||||
Homarr allows you to interact with Docker containers running on your system.
|
Homarr allows you to interact with Docker containers running on your system.
|
||||||
|
The **Service setup** section compares the visible containers with your existing Homarr apps and integrations. It keeps every service distinct by Docker endpoint and container ID, including multiple containers that use the same integration type.
|
||||||
|
|
||||||
|
Homarr can show a service as:
|
||||||
|
|
||||||
|
- **Ready to connect** when its image or name matches a supported integration
|
||||||
|
- **New service** when it can be added as an app but no integration is recognized
|
||||||
|
- **Already represented** or **Linked** when an app or integration already matches
|
||||||
|
- **Address changed** when a service appears to match an integration but its reachable address has changed
|
||||||
|
|
||||||
|
Suggested addresses are ranked and explain where they came from. A published address or Docker endpoint host is normally usable from a browser; a container-name address is server-only and requires Homarr to share the container network. Wildcard addresses such as `0.0.0.0` are never offered as browser destinations. You can edit every suggestion before continuing.
|
||||||
|
|
||||||
|
:::info[Review before changing]
|
||||||
|
Service discovery is read-only. Homarr never creates or changes an app or integration automatically; use the action on an individual suggestion to review and confirm its setup.
|
||||||
|
:::
|
||||||
|
|
||||||
|
Use the inbox filters to focus on services that need attention or those already represented in Homarr. Refresh runs discovery again. Dismissed suggestions are stored in the current browser using their endpoint-qualified service identity and can be restored from the same panel. If multiple existing items could match, Homarr marks the result as ambiguous and does not choose one automatically.
|
||||||
|
|
||||||
|
The health badges are an evidence-based projection across Docker, integration configuration, app representation, and persisted widget links. Authentication, API request success, and widget query execution are labeled **Not observed** because Homarr does not currently retain trustworthy last-run results for these layers. Use the suggested integration test or board action to diagnose them live; **Not observed** is never presented as healthy.
|
||||||
|
|
||||||
|
If one Docker endpoint is unavailable, Homarr reports that endpoint while continuing to show services from healthy endpoints. An unavailable endpoint is not treated as an empty Docker installation.
|
||||||
|
|
||||||
Each container row has an action menu with the following options:
|
Each container row has an action menu with the following options:
|
||||||
|
|
||||||
- **View logs** - opens a dedicated logs page with a live terminal
|
- **View logs** - opens a dedicated logs page with a live terminal
|
||||||
@@ -160,11 +228,13 @@ They are then available in the app list and can be used as normally added apps.
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
### Configuration
|
### Container labels
|
||||||
|
|
||||||
Currently Homarr supports one label for configuration of the containers:
|
`homarr.hide` excludes a container from the Docker Containers widget, tools page, and onboarding discovery whenever the
|
||||||
|
label is present.
|
||||||
|
|
||||||
- **homarr.hide:** If set to any value, the container will be hidden from the Docker Containers widget and tools page.
|
During first-run onboarding, Homarr can also discover apps, integrations, groups, and compatible widgets from
|
||||||
|
`homarr.*` labels, with Homepage labels as a fallback. See the complete [Docker label reference](/docs/integrations/docker-labels).
|
||||||
|
|
||||||
### Security
|
### Security
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,8 @@ import { kubernetesIntegration } from ".";
|
|||||||
|
|
||||||
Homarr provides a user-friendly Kubernetes dashboard that offers an overview of your cluster’s resources in a clear and structured interface. It allows users to view key Kubernetes objects, including `Pods`, `Services`, `Ingresses`, `Nodes`, `ConfigMaps`, `Secrets`, `Namespaces`, and `Volumes`, as well as basic metrics when the Kubernetes Metrics Server is enabled.
|
Homarr provides a user-friendly Kubernetes dashboard that offers an overview of your cluster’s resources in a clear and structured interface. It allows users to view key Kubernetes objects, including `Pods`, `Services`, `Ingresses`, `Nodes`, `ConfigMaps`, `Secrets`, `Namespaces`, and `Volumes`, as well as basic metrics when the Kubernetes Metrics Server is enabled.
|
||||||
|
|
||||||
|
Docker service discovery does not convert Kubernetes resources into Homarr apps or integrations. Kubernetes remains a separate, read-only operational view, so a cluster resource is never changed or linked automatically.
|
||||||
|
|
||||||
:::warning[Read only]
|
:::warning[Read only]
|
||||||
This integration is read-only, meaning Homarr does not modify or manage cluster resources but serves as an informational tool to enhance visibility into your Kubernetes environment.
|
This integration is read-only, meaning Homarr does not modify or manage cluster resources but serves as an informational tool to enhance visibility into your Kubernetes environment.
|
||||||
:::
|
:::
|
||||||
@@ -25,7 +27,7 @@ This integration is read-only, meaning Homarr does not modify or manage cluster
|
|||||||
Before deploying Homarr in Kubernetes, ensure the following prerequisites are met:
|
Before deploying Homarr in Kubernetes, ensure the following prerequisites are met:
|
||||||
|
|
||||||
- Kubernetes (Version >= 1.24.0)
|
- Kubernetes (Version >= 1.24.0)
|
||||||
- Metrics Server ([Install from here](https://github.com/kubernetes-sigs/metrics-server))
|
- Metrics Server ([install from here](https://github.com/kubernetes-sigs/metrics-server)) is optional. Without it, Homarr still shows cluster inventory, node status, and reserved capacity, and identifies live CPU and memory usage as unavailable.
|
||||||
- RBAC Enabled (Required for Homarr Helm chart)
|
- RBAC Enabled (Required for Homarr Helm chart)
|
||||||
|
|
||||||
### Configuring RBAC in Helm Chart
|
### Configuring RBAC in Helm Chart
|
||||||
@@ -45,6 +47,25 @@ Enabling RBAC in the Helm chart creates the necessary Kubernetes Role-Based Acce
|
|||||||
- ClusterRole & ClusterRoleBinding: Extends the same permissions cluster-wide for additional flexibility.
|
- ClusterRole & ClusterRoleBinding: Extends the same permissions cluster-wide for additional flexibility.
|
||||||
:::
|
:::
|
||||||
|
|
||||||
|
### Multiple Kubernetes contexts
|
||||||
|
|
||||||
|
When Homarr runs outside a cluster, set `KUBECONFIG` explicitly so Homarr loads the contexts from the referenced kubeconfig file or files. Mount the kubeconfig read-only and set the standard `KUBECONFIG` environment variable to its path inside the Homarr container:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
services:
|
||||||
|
homarr:
|
||||||
|
volumes:
|
||||||
|
- ./kubeconfig:/app/config/kubeconfig:ro
|
||||||
|
environment:
|
||||||
|
KUBECONFIG: /app/config/kubeconfig
|
||||||
|
```
|
||||||
|
|
||||||
|
The Kubernetes management pages include a context selector. The selected context is stored in the page URL, so each React Query cache entry and every API request remains context-specific. Resources with the same namespace and name in two contexts therefore remain separate.
|
||||||
|
|
||||||
|
Context status is checked independently. If one context is unavailable, the selector still lists healthy contexts. A context is shown as **Metrics unavailable** when its Kubernetes API is reachable but Metrics Server is not; inventory remains available without live CPU and memory usage.
|
||||||
|
|
||||||
|
When Homarr runs inside Kubernetes without `KUBECONFIG`, it keeps using the in-cluster service account as the single default context.
|
||||||
|
|
||||||
### Homarr Dashboard Overview
|
### Homarr Dashboard Overview
|
||||||
|
|
||||||
Once deployed, Homarr provides a dashboard displaying Kubernetes metrics and resource information. The main page includes:
|
Once deployed, Homarr provides a dashboard displaying Kubernetes metrics and resource information. The main page includes:
|
||||||
|
|||||||
@@ -86,6 +86,30 @@ Board layout responses identify each layout with a `mobile`, `base`, or `custom`
|
|||||||
|
|
||||||
Use the interactive API reference to inspect the exact request body for each endpoint under the `boards` and `settings` tags.
|
Use the interactive API reference to inspect the exact request body for each endpoint under the `boards` and `settings` tags.
|
||||||
|
|
||||||
|
## Docker action payload migration
|
||||||
|
|
||||||
|
Docker lifecycle and removal actions now identify each container with both its Docker endpoint and container ID. This is a
|
||||||
|
breaking change for tRPC and MCP clients that previously sent an `ids` array to the start, stop, restart, or remove action.
|
||||||
|
|
||||||
|
Replace the old payload:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{ "ids": ["container-id"] }
|
||||||
|
```
|
||||||
|
|
||||||
|
with endpoint-qualified targets:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"targets": [{ "endpointId": "local", "id": "container-id" }]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Read `endpointId` and `id` from `docker.getContainers` (MCP tool `docker_getContainers`) immediately before the action.
|
||||||
|
Pass those pairs unchanged to `docker.startAll`, `docker.stopAll`, `docker.restartAll`, or `docker.removeAll`; their MCP tool
|
||||||
|
names use underscores, such as `docker_restartAll`. Endpoint qualification prevents identical container IDs on different
|
||||||
|
Docker or Podman endpoints from targeting the wrong service.
|
||||||
|
|
||||||
## Partial integration failures
|
## Partial integration failures
|
||||||
|
|
||||||
Multi-integration widget queries keep data from integrations that remain available. Calendar and media-server results include
|
Multi-integration widget queries keep data from integrations that remain available. Calendar and media-server results include
|
||||||
@@ -93,10 +117,6 @@ an optional `error` on a failed integration; media-request responses expose a `f
|
|||||||
requests endpoint returns its items in `requests`. When every selected integration fails, the query returns an error instead
|
requests endpoint returns its items in `requests`. When every selected integration fails, the query returns an error instead
|
||||||
of a partial response.
|
of a partial response.
|
||||||
|
|
||||||
Other widgets use the same settlement pattern with endpoint-specific shapes: a failed integration may appear as a named
|
|
||||||
fallback row, in a failure array, or be omitted while healthy results remain. Widget pages should identify the shape they
|
|
||||||
render rather than assuming every query exposes an `error` field.
|
|
||||||
|
|
||||||
### Saving dashboard layouts
|
### Saving dashboard layouts
|
||||||
|
|
||||||
The dashboard editor saves item positions and sections as one board update.
|
The dashboard editor saves item positions and sections as one board update.
|
||||||
|
|||||||
@@ -51,6 +51,6 @@ Note that the ping URL only accepts `http://` and `https://` URLs — custom URI
|
|||||||
|
|
||||||
## List of apps
|
## List of apps
|
||||||
|
|
||||||
On the apps management page you find all apps that exist in your Homarr instance. You can edit and delete them.
|
On the apps management page you find all apps that exist in your Homarr instance. Search by name or URL, open an app directly, or use its row actions to edit and delete it. A filtered search can be cleared without leaving the page.
|
||||||
|
|
||||||

|
Any signed-in user can view this list. Creating, editing, and deleting apps requires the corresponding app permission; board permissions are not required.
|
||||||
@@ -1,362 +1,68 @@
|
|||||||
---
|
---
|
||||||
|
description: Configure and use Homarr Assistant.
|
||||||
tags:
|
tags:
|
||||||
- Assistant
|
- Assistant
|
||||||
- AI
|
- AI
|
||||||
- Administration
|
- Administration
|
||||||
- Security
|
|
||||||
---
|
---
|
||||||
|
|
||||||
import assistantConfigImage from "./img/assistant-config.png";
|
|
||||||
import assistantWidgetImage from "./img/assistant-widget.png";
|
|
||||||
|
|
||||||
# Assistant
|
# Assistant
|
||||||
|
|
||||||
Administrators can configure the instance-wide AI assistant from **Management → Assistant**.
|
Homarr Assistant can answer questions and manage Homarr for you. It uses the signed-in user's permissions and asks for
|
||||||
It is available to signed-in users from the user menu, with `Shift + A`, and from the
|
approval before making changes.
|
||||||
`Cmd/Ctrl + K` command menu. **Ask Homarr Assistant** is always available as a local result in the default
|
|
||||||
search. Selecting it with an existing query sends that query in the background; selecting it without a
|
|
||||||
query turns the command-menu search field into a prompt composer. Press
|
|
||||||
`Enter` to send the prompt in the background without opening the conversation. The search field receives
|
|
||||||
focus whenever the command menu opens, including when it is opened by an assistant tool. Sending from the
|
|
||||||
command menu preserves any draft in the expanded conversation. The local result is temporarily disabled while
|
|
||||||
the assistant is responding or waiting for an approval.
|
|
||||||
|
|
||||||
Availability follows the setup state. Signed-out users do not get an assistant action in the user menu or from
|

|
||||||
`Shift + A`; the always-visible command-menu result is disabled and says **Sign in**. If the provider connection or
|
|
||||||
model is configured but **Enable Assistant** is off, the user-menu and `Shift + A` entry points do not open the
|
|
||||||
assistant, while `Cmd/Ctrl + K` keeps its result visible but disabled with an explanation that an administrator must
|
|
||||||
configure and enable it. Saving a working connection, model, and enabled state makes all three entry points
|
|
||||||
available again.
|
|
||||||
|
|
||||||
While a response is running, a compact activity bar appears at the bottom of the page and the user-menu
|
## Set it up
|
||||||
avatar shows a thinking indicator. The activity bar can be opened to follow the response. Completed
|
|
||||||
responses add an unread count to the user menu until they are opened or dismissed. The expanded
|
|
||||||
conversation has a minimize action that returns it to the activity bar without interrupting a response.
|
|
||||||
Its adjacent close action hides the panel without leaving an activity bar behind. Both window actions use
|
|
||||||
subtle buttons with an icon, tooltip, and accessible label.
|
|
||||||
The transcript follows streamed output while it is already at the bottom, including fast responses. Scrolling
|
|
||||||
up releases that follow state until **Scroll to latest** is selected or the user returns to the bottom.
|
|
||||||
|
|
||||||
`Shift + A` opens the compact conversation panel directly. The shortcut is ignored while typing in text
|
Open **Management → Assistant**.
|
||||||
fields, selectors, and editable content.
|
|
||||||
|
|
||||||
The **Assistant** board widget embeds the same persisted conversation and full interaction surface directly
|

|
||||||
on a dashboard. By default it follows the current conversation. Widget settings can instead pin a specific
|
|
||||||
conversation; the conversation picker stays hidden until **Pinned conversation** is selected.
|
|
||||||
If the pinned conversation was deleted or cannot be opened, the widget shows an **Open conversation** recovery action
|
|
||||||
and retry state instead of silently losing the widget content or falling back to another thread. **Open conversation**
|
|
||||||
retries the same pinned thread after a failed switch.
|
|
||||||
|
|
||||||
<img
|
1. Select a provider and check its API URL.
|
||||||
src={assistantWidgetImage}
|
2. Enter an API key when required, then save the connection.
|
||||||
alt="Assistant widget embedded on a dashboard with its conversation header, automatic approvals control, model selector, and composer"
|
3. Refresh the model list and select a model.
|
||||||
style={{ maxWidth: "100%" }}
|
4. Enable the assistant and save.
|
||||||
/>
|
|
||||||
|
|
||||||
The current preview capture shows the board-embedded surface, including its conversation header, automatic-approval
|
Choose a provider preset or use **Custom endpoint** with an OpenAI-compatible Chat Completions API. The
|
||||||
control, model and thinking controls, and composer. These controls operate on the same persisted thread as the
|
[Homarr provider](../workshop/homarr-provider) is the default and needs no administrator API key. The Homarr team pays
|
||||||
floating assistant while keeping this surface's draft and focus independent.
|
for a limited number of Assistant uses for each user every day; users sign in to the Community Workshop to use them.
|
||||||
|
|
||||||
The Shift+A panel is non-modal: opening it focuses its composer, but it does not capture focus from the board.
|
:::info Local model servers
|
||||||
Users can continue typing in an Assistant widget or interacting with other dashboard controls while the panel
|
|
||||||
is open. Every visible assistant surface keeps its own draft, attachment list, selection, and focus while sharing
|
|
||||||
the same persisted conversation. Switching conversations restores the draft that belongs to that surface and
|
|
||||||
conversation instead of copying text into another widget or the floating panel.
|
|
||||||
|
|
||||||
When the assistant is unavailable, its command-menu result remains visible but disabled and explains that
|
Inside a container, `localhost` means the Homarr container. Use the model server's container name, local DNS name, or
|
||||||
an administrator must configure and enable it.
|
host gateway address.
|
||||||
|
|
||||||
The assistant uses the assistant-ui runtime for **AI SDK v7**. Homarr tracks the newest mutually compatible
|
|
||||||
package set permitted by its supply-chain release-age policy. Persisted message rows can still report the upstream
|
|
||||||
codec name `ai-sdk/v6`; assistant-ui's current v7 adapter deliberately retains that identifier for its compatible
|
|
||||||
UI-message wire format. It does not mean the application is running AI SDK v6.
|
|
||||||
|
|
||||||
## Configure a model provider
|
|
||||||
|
|
||||||
Homarr includes presets for OpenRouter, OpenAI, Anthropic Claude, Google Gemini, xAI, Groq, Mistral AI,
|
|
||||||
DeepSeek, Together AI, Ollama, and LM Studio. Provider icons make the presets easy to identify. A custom
|
|
||||||
preset connects any other service that implements the OpenAI Chat Completions API.
|
|
||||||
|
|
||||||
The provider list also shows **Homarr — Coming soon** as a disabled option.
|
|
||||||
|
|
||||||
The management page presents setup as three compact sections: provider and endpoint, credentials, then
|
|
||||||
model and availability. A status summary at the top shows whether the connection is ready, whether a key
|
|
||||||
is protected, and which model is selected. Redundant active-state badges are omitted when the setup is ready.
|
|
||||||
|
|
||||||
<img
|
|
||||||
src={assistantConfigImage}
|
|
||||||
alt="Assistant configuration page showing provider, credentials, model, and availability sections"
|
|
||||||
style={{ maxWidth: "100%" }}
|
|
||||||
/>
|
|
||||||
|
|
||||||
The screenshot shows the configuration surface with no provider key entered; the assistant remains disabled until a
|
|
||||||
working provider, model, and enabled state are saved.
|
|
||||||
|
|
||||||
1. Choose a provider preset or **Custom endpoint**, then confirm the API base URL. It usually ends in `/v1`.
|
|
||||||
2. Add an API key if the service requires bearer authentication. Additional authentication or routing
|
|
||||||
headers are available in the collapsed advanced section.
|
|
||||||
3. Save the provider connection.
|
|
||||||
4. Refresh the model list and select a discovered model. Homarr displays the friendly model name but
|
|
||||||
stores and sends the provider's exact model ID. Context-window sizes use compact labels such as `1M`.
|
|
||||||
5. Enable the assistant and save the configuration.
|
|
||||||
|
|
||||||
Changing the provider or base URL immediately resets the unsaved credential/header draft, selected model, and
|
|
||||||
enabled state, and puts the model section into a **save connection first** state. Saving that destination change also
|
|
||||||
clears stored credentials for the previous destination. Changing the discovery path resets the selected model and
|
|
||||||
enabled state; save the new path before relying on its discovery results. For an unsaved provider or base-URL change,
|
|
||||||
the model controls, **Refresh models**, web-search switch, enable switch, and **Save assistant** remain unavailable.
|
|
||||||
After the connection is saved, refresh the model list and select a model; if discovery is blank or returns no models,
|
|
||||||
the manual model-ID field is the supported fallback. Only then enable the assistant and save the configuration.
|
|
||||||
|
|
||||||
The model discovery path defaults to `/models` and is appended to the API base URL. Leave the custom path blank when
|
|
||||||
the service does not expose a usable discovery endpoint. A manual model ID can still be used when discovery is
|
|
||||||
unavailable or returns no models.
|
|
||||||
|
|
||||||
API keys and additional header values are encrypted in the Homarr database. They are decrypted only on
|
|
||||||
the server for discovery and model requests, and they are never returned to the browser. Changing the
|
|
||||||
provider or base URL, then saving the connection, clears existing credentials. This prevents credentials for one
|
|
||||||
service from being sent to another endpoint. Additional headers are write-only; saving them replaces the complete
|
|
||||||
stored header set. Use the
|
|
||||||
explicit clear/remove flow when you want to remove previously saved headers.
|
|
||||||
|
|
||||||
When a key is already stored, the page shows its protected state instead of an ambiguous empty password
|
|
||||||
field. Removing the API key requires explicit confirmation. Save that removal before entering and saving a
|
|
||||||
different key.
|
|
||||||
|
|
||||||
:::info Container networking
|
|
||||||
|
|
||||||
For a containerized Homarr installation, `localhost` refers to the Homarr container. Use a resolvable
|
|
||||||
container name, internal DNS name, or host gateway address to reach Ollama, LM Studio, or another local
|
|
||||||
model server.
|
|
||||||
|
|
||||||
:::
|
:::
|
||||||
|
|
||||||
The configured endpoint must support streaming Chat Completions and structured tool calls for the full
|
## Use it
|
||||||
assistant experience. Model discovery alone does not guarantee tool support, except when OpenRouter
|
|
||||||
explicitly advertises the model's `tools` capability.
|
|
||||||
|
|
||||||
OpenRouter web search is an opt-in option in the model section. It registers OpenRouter's model-callable
|
- Select **Assistant** in the user menu or press `Shift + A`.
|
||||||
[`openrouter:web_search` server tool](https://openrouter.ai/docs/guides/features/server-tools/web-search)
|
- Ask from `Cmd/Ctrl + K`.
|
||||||
alongside Homarr's tools, so OpenRouter performs each search without
|
- Add the [Assistant widget](../widgets/assistant) to a board.
|
||||||
exposing the stored credential to the browser. The model decides when live research is needed and can use the
|
|
||||||
grounded results and source links in responses or dashboard notes. Homarr limits each assistant request to
|
|
||||||
three searches with five results per search. OpenRouter charges web-search usage separately from model tokens.
|
|
||||||
Completed responses show a compact web-search activity card when OpenRouter reports search usage. OpenRouter
|
|
||||||
does not expose these server-side searches as ordinary client-executed tool calls, so Homarr shows the reported
|
|
||||||
search count and the safe title and URL from each returned `url_citation` annotation instead. Citation excerpts
|
|
||||||
stay in the provider response and are not persisted in the activity card.
|
|
||||||
|
|
||||||
The option is also available for custom endpoints that forward OpenRouter's server-tools request format. This
|
The assistant can work with boards, apps, integrations, widgets, Custom Widgets, and connected services. Use `@` to
|
||||||
supports OpenRouter proxies, including the future Homarr Router provider. Leave it disabled for ordinary
|
add Homarr items as context, `/` for shortcuts, and the paperclip for supported files.
|
||||||
OpenAI-compatible endpoints because the `openrouter:*` tool type is not part of the standard OpenAI API.
|
|
||||||
|
|
||||||
The Claude preset uses Anthropic's OpenAI SDK compatibility layer. Anthropic describes that layer as
|
Each request includes the user's name, current page and board, home board, server time, browser time zone, and a small
|
||||||
suited to testing and comparison rather than as its full native API; unsupported OpenAI fields may be
|
summary of accessible Homarr resources. Live status is fetched only when needed.
|
||||||
ignored. Streaming responses and tool calls are supported, which are the capabilities Homarr Assistant
|
|
||||||
uses. Choose OpenRouter or another provider when you prefer a provider-neutral production endpoint.
|
|
||||||
|
|
||||||
## Conversations and tools
|
## Permissions and privacy
|
||||||
|
|
||||||
Conversations and messages are stored per user in the Homarr database. The assistant stays out of the
|
- Read-only actions can run automatically. Changes require approval.
|
||||||
page layout until it is opened. Users can start, revisit, and delete conversations from the
|
- Homarr permissions apply to every tool call and mentioned item.
|
||||||
conversation menu in the floating panel.
|
- API keys and custom headers are encrypted and never returned to the browser.
|
||||||
|
- Conversations are stored per user and can be exported or deleted.
|
||||||
|
|
||||||
Messages support copy, edit-and-resend, response regeneration and branch navigation, Markdown export,
|
Prompts, attachments, tool definitions, and tool results are sent to the selected model provider. Review that
|
||||||
and helpful/not-helpful feedback. The conversation menu also provides a compact export action beside delete for
|
provider's privacy policy before enabling the assistant.
|
||||||
each conversation. Its debugging-oriented Markdown includes every stored user, assistant, reasoning, tool, error,
|
|
||||||
branch-parent, and server-metadata record while redacting secret-looking fields and embedded attachment data.
|
|
||||||
The per-response export uses the same tool-aware format instead of assistant-ui's text-only copy representation.
|
|
||||||
Selecting text in a message exposes a quote action that carries the selected passage into the next prompt.
|
|
||||||
Files returned by a compatible model can be downloaded directly from the message.
|
|
||||||
Assistant responses render GitHub-flavored Markdown, including headings, links, lists, task lists, tables,
|
|
||||||
quotes, inline code, and fenced code blocks. Line breaks are preserved, and Homarr repairs common streamed
|
|
||||||
responses where a provider returns escaped line breaks or places a bold-label list on one line.
|
|
||||||
Completed fenced code blocks use language-aware syntax highlighting; a streaming block stays plain until its
|
|
||||||
content is stable. Safe same-origin links are prefetched and use client-side navigation, so opening a returned
|
|
||||||
preview, editor, board, or other Homarr item does not unload the assistant. External links keep their normal
|
|
||||||
external-browser behavior.
|
|
||||||
Fenced `mermaid` blocks render as diagrams in the current color scheme using Mermaid's strict security mode;
|
|
||||||
invalid diagrams fall back to their source instead of breaking the response.
|
|
||||||
When Homarr's icon search returns an image URL, visual result tables render that actual icon in a compact
|
|
||||||
image column instead of substituting an emoji. Assistant-provided Markdown images accept safe relative,
|
|
||||||
HTTP, and HTTPS sources and load without forwarding the Homarr page as the referrer. Image message parts
|
|
||||||
render through assistant-ui's image primitive in a bounded responsive preview with an accessible loading state,
|
|
||||||
a filename caption when available, and an in-place retry when the source fails.
|
|
||||||
Images up to 1 MB and text, Markdown, CSV, HTML, XML, or JSON documents up to 350 KB can be attached by
|
|
||||||
using the paperclip, dropping files onto the composer, or pasting an image with `Cmd/Ctrl + V`. Attachment
|
|
||||||
previews stay local to the composer where they were added and show upload state, file type, and a removable image
|
|
||||||
thumbnail or document tile. A request can contain up to five attachments.
|
|
||||||
Image understanding depends on the selected model; document text is extracted locally by Homarr and sent
|
|
||||||
as part of the prompt.
|
|
||||||
|
|
||||||
Type `@` in the composer to add permission-checked context. The nested menu contains apps, integrations,
|
## Troubleshooting
|
||||||
boards, widgets, and tools available to the current user. Homarr validates every referenced ID again on
|
|
||||||
the server before adding it to the model context. Selected references appear as compact, typed pills in the
|
|
||||||
composer and sent message, while preserving assistant-ui's underlying directive syntax for the model. When the
|
|
||||||
assistant cites one of those references in its own response, Homarr renders the same typed pill and uses the
|
|
||||||
stored app or integration icon when one is available. Type `/`
|
|
||||||
for common prompt shortcuts. Both menus support keyboard navigation and keep the active result visible while
|
|
||||||
moving through long lists. The selector below the composer combines searchable, provider-grouped models with
|
|
||||||
their description, context size and image-input capability, plus the thinking-level control. Model selection is
|
|
||||||
saved to the current conversation when selected. For a persisted thread, changing the model updates that thread's
|
|
||||||
preference without changing the administrator's configured default; switching threads restores each thread's saved
|
|
||||||
model, while a new thread starts from the configured default until the user changes it. Thinking mode can be left on
|
|
||||||
**Auto**, disabled, or set
|
|
||||||
from minimal through high; explicit levels are sent using the AI SDK's provider-neutral reasoning setting and
|
|
||||||
still depend on support from the chosen model and endpoint. Reasoning text is shown live when the provider streams
|
|
||||||
it through assistant-ui's grouped-parts and chain-of-thought primitives. The compact **Thinking** trace groups
|
|
||||||
adjacent reasoning with ordinary tool calls, shows each tool's status, duration and safe human-readable target,
|
|
||||||
and expands raw input, output and result previews only on request. Approval and question tools remain full-width
|
|
||||||
outside the trace. The disclosure renders Markdown, can be opened or closed without interrupting the response,
|
|
||||||
and keeps the user's collapsed state when another message starts. A compact dot matrix distinguishes an initial
|
|
||||||
thinking pass from response streaming and settles into waiting, success, or error states in the minimized activity
|
|
||||||
bar. The state always keeps its text label, and the animation is disabled when the operating system requests
|
|
||||||
reduced motion.
|
|
||||||
|
|
||||||
A circular context ring beside the model selector gives a quick glance at cumulative conversation usage without
|
- **No models found:** check the base URL, model discovery path, and API key. You can enter a model ID manually.
|
||||||
expanding the composer toolbar. Its accessible label includes cumulative tokens and cost when available, while
|
- **Assistant is unavailable:** enable it and save the configuration.
|
||||||
its popover keeps the latest complete context reading as a new response starts and lists every request
|
- **Tool calls stop:** select a model that supports streaming and tool calls.
|
||||||
turn with its model, provider, input, output, cached-input and reasoning tokens, context use, duration, speed,
|
- **Local endpoint is unreachable:** check container networking and the server's listen address.
|
||||||
agent steps, routing details, and cost when reported. Before usage is available, the control remains a compact
|
|
||||||
ring instead of showing a redundant missing-data label. Closing and reopening the popover reads persisted
|
|
||||||
conversation metadata instead of resetting the display to zero. A larger ring inside the popover breaks the latest
|
|
||||||
reported context into used, remaining and total capacity plus input, cached-input, output and reasoning tokens.
|
|
||||||
|
|
||||||
Each assistant response places a small provider logo in the same stable action toolbar as copy, export,
|
See [MCP](./mcp) for external AI clients and [Custom Widget agent authoring](./custom-widgets/agent-authoring) for the
|
||||||
feedback, and regenerate. Hovering the logo shows the provider, exact model, timing, throughput, and cost without
|
widget authoring workflow.
|
||||||
adding another metadata row to the transcript. Branch navigation occupies its own adjacent group, so switching
|
|
||||||
between response versions never pushes the response actions off-screen.
|
|
||||||
|
|
||||||
OpenRouter responses request inline usage and routing metadata. Opening detailed turn data also loads the
|
|
||||||
server-side generation record for its model steps and briefly polls while OpenRouter finishes processing it.
|
|
||||||
The details separate Homarr's end-to-end timing from OpenRouter's provider latency, generation time, and provider
|
|
||||||
throughput, and can include normalized and native token counts, moderation latency, cache discount, fallback count,
|
|
||||||
service tier, data region, BYOK status, routed provider, generation identifier, exact cost, and upstream inference
|
|
||||||
cost. Provider credentials remain server-side; the browser can request only generation identifiers already stored
|
|
||||||
on a conversation owned by the signed-in user and signed by the Homarr server for that user and conversation.
|
|
||||||
Successful generation lookups are cached briefly so polling and multi-step requests do not repeatedly query
|
|
||||||
OpenRouter for the same record.
|
|
||||||
When a provider omits cost but model discovery includes prompt and completion pricing, Homarr labels the
|
|
||||||
calculated value as estimated. Missing provider data is shown as not reported rather than inferred.
|
|
||||||
|
|
||||||
The assistant can use the same internal tool definitions as the [Homarr MCP server](./mcp).
|
|
||||||
Each tool call runs as the signed-in user, so normal Homarr permission checks still apply. Read-only
|
|
||||||
procedures can run during the agent loop. Mutating procedures require native approval unless automatic approvals are
|
|
||||||
enabled for the conversation. Neutral choices and questions still wait for the user. The approval appears as a large
|
|
||||||
**Approve and run** or **Deny** action;
|
|
||||||
the assistant does not require a second typed confirmation first. Tool cards expose their status, timing,
|
|
||||||
validated input, result, and error state without flooding the conversation with raw JSON by default.
|
|
||||||
Common collection and widget results are summarized inline as compact responsive cards, while the full
|
|
||||||
structured result remains available in the tool card details. Icon searches show the returned image variants,
|
|
||||||
file formats, and repositories instead of the size of the complete icon catalog. Their trace uses a readable
|
|
||||||
activity such as **Looking for “homarr” icons** instead of exposing the internal MCP procedure name.
|
|
||||||
|
|
||||||
Large tool-driven requests can use up to 32 agent steps and a larger response budget within one request, so
|
|
||||||
multi-item dashboard changes normally finish without requiring a follow-up “Continue” message. OpenRouter calls
|
|
||||||
Homarr tools sequentially to prevent routed models from interleaving or truncating parallel JSON arguments, while
|
|
||||||
every mutation still follows its native approval policy, including conversation-scoped automatic approvals. A safely
|
|
||||||
recoverable truncated icon-search object is repaired
|
|
||||||
before validation; incomplete search strings and all mutation inputs are never guessed.
|
|
||||||
Homarr also normalizes internal tool results to the model's JSON-compatible message format before continuing an
|
|
||||||
agent loop. Rich server values such as dates cannot invalidate the next model step, and an interrupted tool call
|
|
||||||
without a result is omitted when the conversation resumes instead of making the entire prompt fail.
|
|
||||||
|
|
||||||
The assistant can create a formatted dashboard note by adding a **Notebook** widget. Ask it for a note with
|
|
||||||
headings, lists, tasks, links, emphasis, tables, or images; it generates compatible rich-text content, shows
|
|
||||||
the native widget configuration form and standard mutation approval, then places the widget in the next
|
|
||||||
available dashboard position. The generated content is retained even though the Notebook content field is
|
|
||||||
normally hidden from widget settings.
|
|
||||||
|
|
||||||
Automatic placement checks every responsive layout and treats both widgets and complete container footprints
|
|
||||||
as occupied. New assistant-created items use the first free position in the main canvas instead of overlapping
|
|
||||||
existing content or being placed in a gutter.
|
|
||||||
|
|
||||||
Every assistant-created dashboard widget now passes through Homarr's native widget editor before it is added.
|
|
||||||
The form fills widget defaults, validates widget-specific options, and only offers compatible integrations that
|
|
||||||
the current user can use. Required integrations cannot be left empty, single-integration widgets cannot receive
|
|
||||||
multiple integrations, and the reviewed values are passed unchanged into the final approval-gated mutation.
|
|
||||||
|
|
||||||
Custom-widget tools let an administrator list, inspect, create, and update definitions. The custom-widget
|
|
||||||
form's **Design with AI** action sends a focused request into the current conversation, where the assistant
|
|
||||||
can propose the matching mutation and use the same approval controls. Existing stored secret values are
|
|
||||||
reported only as configured/not configured and are preserved on update unless replacements are explicitly
|
|
||||||
provided. For Custom Widget requests, Homarr lazily adds the complete installed skill, all bundled schema,
|
|
||||||
runtime and security references, and the current JSON Schema to the trusted authoring context. This avoids an
|
|
||||||
extra provider round trip for the large `customWidget_getSkill` and `customWidget_schema` results. If the model
|
|
||||||
discovers the Custom Widget workflow mid-response, Homarr promotes the same resources before its next step and
|
|
||||||
removes the now-redundant resource calls from provider history. Multiline JSX uses `templateLines` to avoid fragile
|
|
||||||
streamed JSON escaping. Custom Widget authoring tools are mandatory: the assistant validates the complete candidate,
|
|
||||||
creates a preview from that exact version, executes every returned preview query, checks the actual HTTP status and
|
|
||||||
response shape, and repeats the entire validation and preview sequence after any material JSX, request, source, option,
|
|
||||||
or binding change. It only reports a widget as validated, working, created, or placed when the corresponding tool result
|
|
||||||
proves that checkpoint. Large widgets are saved from the exact final tested preview session, so the approved create step
|
|
||||||
does not stream the complete JSX a second time. When the request already names a board, that board is carried into the
|
|
||||||
create result and placement continues without asking the user to select it again. Preview and saved-definition results
|
|
||||||
include safe Homarr paths that open in the assistant without a page reload. When placement is still a choice, the
|
|
||||||
assistant uses the structured question UI instead of ending with a prose question.
|
|
||||||
|
|
||||||
The authoring phase limits broad component-document retrieval and then moves into validation with the smallest useful
|
|
||||||
reference set. Supplied samples and successful preview responses are treated as binding contracts: the assistant is
|
|
||||||
instructed to render the requested fields, guard optional nested data, preserve every returned item, expose freshness
|
|
||||||
when timestamps are available, and provide a refresh path for recoverable empty or error states.
|
|
||||||
|
|
||||||
The shield control in the conversation header can enable automatic approvals for the current conversation; they are
|
|
||||||
off by default.
|
|
||||||
While enabled, Homarr accepts every affirmative approval step as it arrives: protected mutations are approved,
|
|
||||||
presented app details and board changes are used, and structured questions with an explicitly categorized
|
|
||||||
**Confirm** answer choose that answer. Neutral choices such as selecting a board still wait for input because
|
|
||||||
they do not have a safe affirmative default. Automatic approvals turn off when you switch conversations, and
|
|
||||||
the shared approval tracker prevents the same call from being handled twice when both a board widget and the
|
|
||||||
floating assistant are visible.
|
|
||||||
|
|
||||||
When the assistant genuinely needs missing information or a choice, it can pause with a structured
|
|
||||||
question. Each proposed answer is visibly categorized as **Confirm**, **Decline**, or **Option**, so the effect
|
|
||||||
of automatic approval is unambiguous. **Other** is shown only when the tool allows it (`allowOther` is not `false`);
|
|
||||||
selecting it opens a freeform response and is always a manual alternative, not an automatic approval choice. While a
|
|
||||||
question is unanswered, its controls stay in a dedicated area immediately
|
|
||||||
above the composer instead of requiring the user to find the tool call in the transcript. The question temporarily
|
|
||||||
uses the available conversation body, with its own scrolling when necessary, rather than squeezing a long option
|
|
||||||
list into a short dock beside part of the transcript. The answered choice then remains in the conversation history.
|
|
||||||
Submitting the answer resumes the same agent run automatically. The minimized activity bar shows the
|
|
||||||
question or approval that needs attention and opens directly back to the request. While an answer, app
|
|
||||||
form, or mutation approval is pending, the composer preserves its draft but does not replace the pending
|
|
||||||
tool call with a new message. If the provider stops before an interactive tool supplies complete arguments,
|
|
||||||
Homarr replaces the loading state with an explicit error and confirms that no change was made.
|
|
||||||
|
|
||||||
App creation uses Homarr's native app form inside the conversation. The form reuses the local icon picker,
|
|
||||||
including automatic matching and searches through the `icon.findIcons` procedure, before the final
|
|
||||||
`app.create` approval is requested. App fields are filled only after the complete tool input has arrived, so
|
|
||||||
streaming partial arguments cannot replace the proposed values with empty fields. The model is instructed not
|
|
||||||
to invent external icon CDN URLs.
|
|
||||||
|
|
||||||
Board appearance changes use a similar review flow. The assistant first reads the board's current settings,
|
|
||||||
including its complete custom stylesheet, and then opens an editable form with Custom CSS, Appearance,
|
|
||||||
Background, and General tabs. The form highlights how many fields were proposed, preserves settings the
|
|
||||||
assistant did not change, and returns only values that differ from the current board. If nothing differs, the review
|
|
||||||
cancels without creating a mutation or approval. Custom CSS can be
|
|
||||||
copied or restored before continuing, and Homarr warns when it contains an imported stylesheet or remote
|
|
||||||
resource URL. Continuing from the form opens the normal mutation approval before anything is saved.
|
|
||||||
|
|
||||||
The board-settings tool covers General, Background, Appearance, Custom CSS, and app-status settings. It does not edit
|
|
||||||
responsive layouts, board access control, or Danger zone actions; those remain outside this review scope.
|
|
||||||
|
|
||||||
Ask for changes such as “make the cards denser on my Home board,” “add a mobile CSS rule without removing
|
|
||||||
my existing styles,” or “change the board colors and disable app status checks.” The current user must have
|
|
||||||
modify permission on the selected board. The empty conversation includes an **Improve a dashboard** starter,
|
|
||||||
and `/style` prepares the same guided workflow from the composer.
|
|
||||||
|
|
||||||
Homarr also exposes a small set of browser-only actions to the assistant. These actions can navigate to
|
|
||||||
safe internal routes, refresh the current view, and open Homarr interfaces such as the command menu and media request search.
|
|
||||||
They never receive provider credentials and cannot navigate to arbitrary external URLs.
|
|
||||||
|
|
||||||
After an approved mutation completes, Homarr automatically refetches active page and dashboard data so
|
|
||||||
board items, settings, custom CSS, apps, and other visible results update without a full browser reload.
|
|
||||||
The refresh action in the conversation header performs the same safe refetch manually. It keeps the
|
|
||||||
conversation open while refreshing both client queries and server-rendered route data.
|
|
||||||
|
|
||||||
:::warning
|
|
||||||
|
|
||||||
Assistant prompts and selected tool results are sent to the configured model endpoint. Review that
|
|
||||||
service's privacy and retention terms before enabling this feature for an instance.
|
|
||||||
|
|
||||||
:::
|
|
||||||
@@ -22,6 +22,8 @@ Navigate to `Management` → `Tools` → `Backup`. You must have **admin** permi
|
|||||||
|
|
||||||
## Exporting a Backup
|
## Exporting a Backup
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
Click the **Export** button in the export card. You'll be prompted to type `I understand` to confirm. Once confirmed, a ZIP file downloads containing:
|
Click the **Export** button in the export card. You'll be prompted to type `I understand` to confirm. Once confirmed, a ZIP file downloads containing:
|
||||||
|
|
||||||
| File | Description |
|
| File | Description |
|
||||||
@@ -33,6 +35,8 @@ The backup contains the complete database. It includes Custom Widgets and all ot
|
|||||||
|
|
||||||
## Restoring a Backup
|
## Restoring a Backup
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
### 1. Upload
|
### 1. Upload
|
||||||
|
|
||||||
Drag and drop or select a `.zip` backup file. The import card validates that the file contains a valid `db.sqlite` and metadata.
|
Drag and drop or select a `.zip` backup file. The import card validates that the file contains a valid `db.sqlite` and metadata.
|
||||||
@@ -49,6 +53,9 @@ Before restoring, Homarr uses **sql.js WASM** to analyze the backup directly in
|
|||||||
|
|
||||||
Type `I understand` to acknowledge that restoring will replace your current database. This cannot be undone.
|
Type `I understand` to acknowledge that restoring will replace your current database. This cannot be undone.
|
||||||
|
|
||||||
|
During first-run onboarding, the database is still empty, so the restore preview goes directly to **Restore Database**
|
||||||
|
without the extra typed confirmation. After Homarr restarts, onboarding opens the restored default home board.
|
||||||
|
|
||||||
### 4. Restore
|
### 4. Restore
|
||||||
|
|
||||||
The backup ZIP is sent to the server, validated, and applied. After a successful restore:
|
The backup ZIP is sent to the server, validated, and applied. After a successful restore:
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 101 KiB |
|
Before Width: | Height: | Size: 102 KiB |
|
Before Width: | Height: | Size: 95 KiB |
|
Before Width: | Height: | Size: 101 KiB |
|
Before Width: | Height: | Size: 160 KiB |
|
Before Width: | Height: | Size: 256 KiB After Width: | Height: | Size: 36 KiB |
@@ -11,18 +11,17 @@ tags:
|
|||||||
|
|
||||||
import iconColorImage from "./img/icon-color.png";
|
import iconColorImage from "./img/icon-color.png";
|
||||||
import itemRadiusImage from "./img/item-radius.png";
|
import itemRadiusImage from "./img/item-radius.png";
|
||||||
import layoutSettingsImage from "./img/layout-settings.png";
|
import layoutLargeImage from "./img/layout-large.png";
|
||||||
import layoutSettingsCustomRailsImage from "./img/layout-settings-custom-rails.png";
|
import layoutMediumImage from "./img/layout-medium.png";
|
||||||
import boardViewModeImage from "./img/board-view-mode.png";
|
import layoutSmallImage from "./img/layout-small.png";
|
||||||
import boardEditModeImage from "./img/board-edit-mode.png";
|
|
||||||
import addBoardContentMenuImage from "./img/add-board-content-menu.png";
|
|
||||||
import keyboardTileEditingImage from "./img/keyboard-tile-editing.png";
|
|
||||||
|
|
||||||
Each dashboard is called a "board".
|
Each dashboard is called a "board".
|
||||||
You can create as many boards as you want.
|
You can create as many boards as you want.
|
||||||
Boards can be restricted to user groups.
|
Boards can be restricted to user groups.
|
||||||
A user may also have a "home board" which they will see at the root path (e.g. my-homarr.com or my-homarr.com/boards).
|
A user may also have a "home board" which they will see at the root path (e.g. my-homarr.com or my-homarr.com/board).
|
||||||
Other boards can be viewed by direct links (e.g. my-homarr.com/boards/smart-home) or via the management pages.
|
Other boards can be viewed by direct links (e.g. my-homarr.com/board/smart-home) or via the management pages.
|
||||||
|
The management page includes a compact structural preview of each board's Base layout so you can recognize it before
|
||||||
|
opening it. Containers include their visible widgets and app icons instead of appearing empty.
|
||||||
|
|
||||||
Names of boards must be unique because this will be used in the URL to load the desired board.
|
Names of boards must be unique because this will be used in the URL to load the desired board.
|
||||||
|
|
||||||
@@ -95,23 +94,9 @@ Homarr will fall back to the Homarr logo if nothing is set.
|
|||||||
|
|
||||||
In this section you can configure the different responsive layouts. Homarr selects the layout with the highest breakpoint that is not wider than the current screen, then scales its complete fixed-size canvas uniformly.
|
In this section you can configure the different responsive layouts. Homarr selects the layout with the highest breakpoint that is not wider than the current screen, then scales its complete fixed-size canvas uniformly.
|
||||||
|
|
||||||
<img
|

|
||||||
src={layoutSettingsImage}
|
|
||||||
alt="Board settings showing protected Mobile and Base responsive layouts with rail controls"
|
|
||||||
style={{ maxWidth: "100%" }}
|
|
||||||
/>
|
|
||||||
|
|
||||||
The layout cards show the representative geometry used for planning. This current example also shows a custom layout
|
Every board has two protected layouts:
|
||||||
with both fixed rails enabled; the rails reserve columns and the remaining canvas reflows automatically.
|
|
||||||
|
|
||||||
<img
|
|
||||||
src={layoutSettingsCustomRailsImage}
|
|
||||||
alt="Board layout settings with a custom layout and both fixed rails enabled"
|
|
||||||
style={{ maxWidth: "100%" }}
|
|
||||||
/>
|
|
||||||
|
|
||||||
Every board has two protected layouts. Creating a board adds **Mobile** at `0px` with three columns and **Base** at
|
|
||||||
`768px` with the column count you choose. Both layouts can be edited, but neither can be removed.
|
|
||||||
|
|
||||||
Every `1 × 1` tile has a `200 × 200` logical-pixel content area.
|
Every `1 × 1` tile has a `200 × 200` logical-pixel content area.
|
||||||
The `24` logical-pixel gap between tiles is separate from that size.
|
The `24` logical-pixel gap between tiles is separate from that size.
|
||||||
@@ -124,17 +109,9 @@ The complete canvas always fits the available width and never adds horizontal bo
|
|||||||
- **Mobile** starts at `0px` and uses three columns on new boards.
|
- **Mobile** starts at `0px` and uses three columns on new boards.
|
||||||
- **Base** is the widest layout and starts at `768px` on new boards.
|
- **Base** is the widest layout and starts at `768px` on new boards.
|
||||||
|
|
||||||
Mobile and Base can be renamed and their column counts and rails can be changed. You can add removable custom layouts
|
Mobile and Base can be renamed and their column counts can be changed, but they cannot be removed. Mobile has no fixed rails; rail configuration is available only on Base and custom layouts. You can add removable custom layouts between their breakpoints.
|
||||||
between their breakpoints.
|
|
||||||
|
|
||||||
Each layout stores independent positions and sizes. Moving or resizing a widget while editing Mobile does not move it in
|
Each layout stores independent positions and sizes. Moving or resizing a widget while editing Mobile does not move it in Base or any custom layout. New custom layouts are generated from Base and scaled to their selected column count.
|
||||||
Base or any custom layout. New custom layouts start from Base's current column count and rail widths; Homarr chooses a
|
|
||||||
free breakpoint between Mobile and Base, and you can then change the breakpoint, columns, and rails.
|
|
||||||
|
|
||||||
Older or incomplete boards are repaired automatically. A board with no layouts receives Mobile at `0px` with three
|
|
||||||
columns and Base at `768px` with ten columns. A board with one layout keeps it as Base and receives a generated Mobile
|
|
||||||
layout. With multiple layouts, the narrowest becomes Mobile, the widest becomes Base, and intermediate layouts remain
|
|
||||||
custom. Duplicate or out-of-order breakpoints are normalized without discarding saved positions.
|
|
||||||
|
|
||||||
Use **Reset from Base** on Mobile or a custom layout to replace all of its positions and sizes with a newly generated version of Base. The layout's name, breakpoint, and column count are kept.
|
Use **Reset from Base** on Mobile or a custom layout to replace all of its positions and sizes with a newly generated version of Base. The layout's name, breakpoint, and column count are kept.
|
||||||
|
|
||||||
@@ -153,14 +130,13 @@ The total number of columns in the layout. Changing it projects the saved positi
|
|||||||
|
|
||||||
#### Fixed rails
|
#### Fixed rails
|
||||||
|
|
||||||
Each responsive layout can enable a fixed left rail, a fixed right rail, or both.
|
Base and custom responsive layouts can enable a fixed left rail, a fixed right rail, or both. Mobile has no fixed rails.
|
||||||
Set a rail width to zero to disable it for that layout.
|
Set a rail width to zero to disable it for that layout.
|
||||||
Choose a width from one to three columns with the three-step slider.
|
Choose a width from one to three columns with the three-step slider.
|
||||||
The preview shows how much space remains for the main canvas.
|
The preview shows how much space remains for the main canvas.
|
||||||
|
|
||||||
Rail columns are reserved from the layout's total column count.
|
Rail columns are reserved from the layout's total column count.
|
||||||
For example, a 12-column layout with a two-column left rail leaves ten columns for the canvas.
|
For example, a 12-column layout with a two-column left rail leaves ten columns for the canvas.
|
||||||
The combined rail widths cannot consume the final main-canvas column.
|
|
||||||
Enabling or widening a rail reflows canvas items into the remaining columns.
|
Enabling or widening a rail reflows canvas items into the remaining columns.
|
||||||
Disabling a rail moves its contents back into the next available canvas positions.
|
Disabling a rail moves its contents back into the next available canvas positions.
|
||||||
|
|
||||||
@@ -169,73 +145,48 @@ Apps, widgets, and Containers inside them still use the same fixed `200 × 200`
|
|||||||
|
|
||||||
#### Breakpoint
|
#### Breakpoint
|
||||||
|
|
||||||
The minimum screen width where the layout is used; a layout is eligible at its breakpoint and above. Mobile is fixed at
|
The minimum screen width where the layout is used. Mobile is fixed at `0px`. Custom breakpoints must be unique and sit between Mobile and Base. Base must remain the highest breakpoint.
|
||||||
`0px`. Custom breakpoints must be unique and sit between Mobile and Base. Base must remain the highest breakpoint.
|
|
||||||
When the initial viewport is not available, Homarr uses its remembered viewport information, client hints, or User-Agent
|
|
||||||
fallback to select a layout.
|
|
||||||
|
|
||||||
#### View and edit modes
|
#### View and edit modes
|
||||||
|
|
||||||
View mode renders a static board without executing the drag-and-drop editor.
|
View mode renders a static board without executing the drag-and-drop editor.
|
||||||
After the board is interactive, Homarr prepares the editor in the background for users who can modify it.
|
After the board is interactive, Homarr prepares the editor in the background for users who can modify it.
|
||||||
Entering edit mode keeps the static board visible until that preparation finishes, then enables collision-aware movement and resizing.
|
Entering edit mode keeps the static board visible until that preparation finishes, then enables collision-aware movement and resizing without changing the board geometry.
|
||||||
Collapsed Containers are expanded while editing so their contents and controls are reachable.
|
Widget content is inert in edit mode, so dragging anywhere on the content moves the tile instead of activating the widget; its settings button remains visible in the compact header above the tile.
|
||||||
|
Dropping a tile into another tile's exact slot swaps their positions when both resulting placements fit without overlapping other content.
|
||||||
<img
|
For other collisions, or when a tile grows into occupied space, nearby tiles are compacted out of the way.
|
||||||
src={boardViewModeImage}
|
|
||||||
alt="A Homarr board in view mode with the dashboard canvas and static widgets visible"
|
|
||||||
style={{ maxWidth: "100%" }}
|
|
||||||
/>
|
|
||||||
|
|
||||||
Widget content is inert in edit mode, so dragging from the inert widget area moves the tile instead of activating the widget;
|
|
||||||
settings and other controls remain usable in the compact header above the tile.
|
|
||||||
A single compatible collision can swap two items when both resulting placements fit, including different-sized or lateral moves.
|
|
||||||
For other collisions, or when a tile grows into occupied space, nearby tiles are compacted out of the way and collision chains reflow.
|
|
||||||
The visible corner controls provide a 44-pixel resize target, and edge controls appear on hover for horizontal or vertical resizing.
|
The visible corner controls provide a 44-pixel resize target, and edge controls appear on hover for horizontal or vertical resizing.
|
||||||
Resize handles stop at the tile's minimum allowed size while the pointer is still moving.
|
Resize handles stop at the tile's minimum allowed size while the pointer is still moving.
|
||||||
Use the pencil button in the board header to enter edit mode; click it again to save. If you leave the page with unsaved
|
Exit edit mode to save the resulting positions.
|
||||||
changes, Homarr asks whether to discard them. If the editor cannot load, the board remains in view mode.
|
|
||||||
|
|
||||||
<img
|
While edit mode is active, **Add board content** opens the same Universal Create surface as the global header action and
|
||||||
src={boardEditModeImage}
|
Spotlight. It can add a widget, app, integration, Container, board, Workshop item, or Custom Widget when the
|
||||||
alt="Board in edit mode with the board header controls and editable dashboard tiles visible"
|
current user and context allow it. Widget setup offers the main canvas, enabled rails, and existing Containers as
|
||||||
style={{ maxWidth: "100%" }}
|
destinations before the widget is created, so the common flow does not require a second move step.
|
||||||
/>
|
|
||||||
|
|
||||||
While edit mode is active, **Add board content** creates a new item, app, integration, or Container on the main canvas.
|
The widget editor also lists its selected integrations. Users with full access can choose **Edit connection** to test,
|
||||||
New content uses the first available position; clicking an empty cell does not place it there, and items cannot be added
|
diagnose, and repair an integration without leaving the board. A successful repair refreshes the affected widget; the
|
||||||
directly into a rail or Container from this menu.
|
saved integration changes apply everywhere that connection is used.
|
||||||
|
|
||||||
<img
|
Pointer users can drag anywhere on a widget tile. Containers use the grab button at their top-left corner.
|
||||||
src={addBoardContentMenuImage}
|
Resize tiles from any edge or corner handle.
|
||||||
alt="Board edit mode add-content menu showing New item, Add an app, New integration, and New container"
|
On a touch screen, press and hold the tile before moving it; resize handles support direct touch input.
|
||||||
style={{ maxWidth: "100%" }}
|
|
||||||
/>
|
|
||||||
|
|
||||||
Pointer users can drag from the inert widget area; interactive controls are excluded. Containers use the grab button at their top-left corner.
|
|
||||||
Widgets can be resized from any edge or corner handle. Activate a Container's chrome with its top-left grip before using
|
|
||||||
its resize handles.
|
|
||||||
On a touch screen, press and hold a tile for about `200 ms` before moving it; a quick tap does not start a drag. Resize
|
|
||||||
handles support direct touch input.
|
|
||||||
Keyboard users can focus a tile, press Enter or Space to start editing, use the arrow keys to move it, and use Shift plus the arrow keys to resize it.
|
Keyboard users can focus a tile, press Enter or Space to start editing, use the arrow keys to move it, and use Shift plus the arrow keys to resize it.
|
||||||
Press Enter, Space, or Escape to stop keyboard editing.
|
Press Enter, Space, or Escape to stop keyboard editing.
|
||||||
Keyboard moves and resizes apply immediately within the current canvas, rail, or Container; they cannot move an item
|
Keyboard moves and resizes apply immediately; Escape stops keyboard editing without undoing those changes.
|
||||||
between grids. Use pointer drag or **Move / resize item** for that.
|
|
||||||
Escape stops keyboard editing without undoing those changes.
|
|
||||||
During a pointer or touch interaction, Escape cancels the move or resize and restores the layout from before that interaction.
|
During a pointer or touch interaction, Escape cancels the move or resize and restores the layout from before that interaction.
|
||||||
Invalid, outside, or otherwise forbidden drops are cancelled in the same way.
|
|
||||||
The **Move / resize item** action in the edit menu remains available for precise numeric input.
|
The **Move / resize item** action in the edit menu remains available for precise numeric input.
|
||||||
|
|
||||||
<img src={keyboardTileEditingImage} alt="A focused board tile in keyboard editing mode" style={{ maxWidth: "100%" }} />
|
|
||||||
|
|
||||||
#### Preview
|
#### Preview
|
||||||
|
|
||||||
Layout Settings shows a lightweight structural preview for every layout, including saved spans, Containers, widget labels, and app icons.
|
Layout Settings shows a lightweight structural preview for every layout, including saved spans, Containers, widget labels, and app icons. The canvas width represents the screen range where that layout is active.
|
||||||
It uses a representative viewport width to project the saved geometry; it does not execute widget queries or represent every
|
|
||||||
pixel of the screen range where the layout is active.
|
|
||||||
|
|
||||||
Choose **Edit layout** to open the real board editor at that representative width on desktop. Save returns to Layout Settings. Cancel discards the local changes. On phones and tablets, the normal board editor continues to use the layout selected by the device width.
|
Choose **Edit layout** to open the real board editor at that representative width on desktop. Save returns to Layout Settings. Cancel discards the local changes. On phones and tablets, the normal board editor continues to use the layout selected by the device width.
|
||||||
|
|
||||||
|
<img src={layoutSmallImage} height={256} />
|
||||||
|
<img src={layoutMediumImage} height={256} />
|
||||||
|
<img src={layoutLargeImage} height={256} />
|
||||||
|
|
||||||
### Containers and rails
|
### Containers and rails
|
||||||
|
|
||||||
Containers can hold apps, widgets, and nested Containers.
|
Containers can hold apps, widgets, and nested Containers.
|
||||||
@@ -307,10 +258,9 @@ Change the radius of your items and Containers.
|
|||||||
This is the field where you can enter custom CSS.
|
This is the field where you can enter custom CSS.
|
||||||
The styling will only be applied on the respective board page.
|
The styling will only be applied on the respective board page.
|
||||||
|
|
||||||
When Homarr Assistant is enabled, users with modify permission can also ask it to edit the board's General, Background,
|
When Homarr Assistant is enabled, users with modify permission can also ask it to edit the board's Custom
|
||||||
Appearance, Custom CSS, and app-status settings. The assistant reads the current stylesheet first and presents an
|
CSS and other visual or behavior settings. The assistant reads the current stylesheet first and presents an
|
||||||
editable review form before requesting approval to save the change. It does not edit responsive layouts, access control,
|
editable review form before requesting approval to save the change.
|
||||||
or Danger zone actions.
|
|
||||||
|
|
||||||
[See this guide on how to work with custom CSS](/docs/advanced/styling/).
|
[See this guide on how to work with custom CSS](/docs/advanced/styling/).
|
||||||
|
|
||||||
@@ -327,12 +277,12 @@ Widgets expose their routine controls without requiring edit mode:
|
|||||||
- Hold `Shift` while hovering a widget that supports advanced view to expand it in place while the other widgets
|
- Hold `Shift` while hovering a widget that supports advanced view to expand it in place while the other widgets
|
||||||
remain visible but dimmed. Release `Shift` to close it. Focus that widget and press `Shift` + `Enter` to keep the view
|
remain visible but dimmed. Release `Shift` to close it. Focus that widget and press `Shift` + `Enter` to keep the view
|
||||||
open until you close it. On touch devices, open it from the widget menu. Other widgets adapt in place instead.
|
open until you close it. On touch devices, open it from the widget menu. Other widgets adapt in place instead.
|
||||||
- When signed in, outside edit mode, and with **Enable right click on widgets** enabled, right-click a widget to inspect
|
- Right-click a widget to inspect its live query status, refresh its data, change quick options, open settings, or run
|
||||||
its live query status, refresh its data, change quick options, open settings, or run supported actions. App tiles do
|
supported actions. Available controls follow your board and integration permissions.
|
||||||
not use this widget menu, and available controls follow your board and integration permissions.
|
- If you can modify the board, right-click or touch and hold an empty grid cell to add an item there. Focus a board
|
||||||
|
section and press `Shift` + `F10` for the keyboard equivalent.
|
||||||
|
|
||||||
The widget context menu follows the **Enable right click on widgets** preference in your user settings. On touch devices,
|
Widget and empty-space context menus follow the **Enable right click on widgets** preference in your user settings.
|
||||||
use the widget menu where your browser exposes it.
|
|
||||||
|
|
||||||
### Access control
|
### Access control
|
||||||
|
|
||||||
@@ -391,8 +341,7 @@ Duplicating a board will not copy the users and groups that have access to the b
|
|||||||
nor the integrations the user does not have access to.
|
nor the integrations the user does not have access to.
|
||||||
:::
|
:::
|
||||||
|
|
||||||
Duplicating a board will create a new board with the same settings, all responsive layouts, and independent positions as the original board.
|
Duplicating a board will create a new board with the same settings and layout as the original board.
|
||||||
Duplicating a board that contains Custom Widgets also requires an administrator.
|
|
||||||
You can duplicate a board by clicking on the three dots in the list of boards and selecting "Duplicate board".
|
You can duplicate a board by clicking on the three dots in the list of boards and selecting "Duplicate board".
|
||||||
|
|
||||||

|

|
||||||
@@ -450,13 +399,5 @@ For the global home board you can only select boards that are public.
|
|||||||
|
|
||||||
### Mobile home board
|
### Mobile home board
|
||||||
|
|
||||||
The mobile home board controls which board opens for devices that Homarr detects as mobile from the User-Agent header.
|
Same as the home board, you can also set a mobile home board.
|
||||||
This is separate from a board's **Mobile layout**, which controls the layout selected inside that board.
|
It will be used for devices that are detected as mobile devices. (Using User-Agent header)
|
||||||
You can set a mobile home board for yourself in your user preferences, for a user or group through management, or for the
|
|
||||||
whole server with **Global mobile board** under `Management` > `Settings` > `Boards`.
|
|
||||||
|
|
||||||
For signed-in users, Homarr checks the user's mobile home board, then the user's desktop home board, then the mobile and
|
|
||||||
desktop defaults for the lowest-position matching group, followed by the mobile and desktop defaults for the `Everyone`
|
|
||||||
group, and finally the server-wide mobile and desktop defaults. Anonymous visitors use the server-wide mobile default and
|
|
||||||
then the server-wide desktop default. Server-wide fallback boards must be public. See the
|
|
||||||
[global board defaults](/docs/management/settings#boards) for the complete precedence and the required public-board rule.
|
|
||||||
@@ -67,23 +67,17 @@ These interfaces do not return an archive URL or archive hash.
|
|||||||
|
|
||||||
1. Load `customWidget_getSkill`, then get the prompt and live schema.
|
1. Load `customWidget_getSkill`, then get the prompt and live schema.
|
||||||
2. Call `customWidget_getComponentCatalog`, followed by `customWidget_getComponent` for only the relevant installed
|
2. Call `customWidget_getComponentCatalog`, followed by `customWidget_getComponent` for only the relevant installed
|
||||||
components and `customWidget_getExample` when one catalog example matches the interaction pattern. Fetch at most
|
components and `customWidget_getExample` when one catalog example matches the interaction pattern. If shared props
|
||||||
eight component documents before the first validation (or four after a complete example already matches). If shared
|
are needed, collect their catalog names and call `customWidget_getSharedProps` once for that set.
|
||||||
props are needed, collect their catalog names and call `customWidget_getSharedProps` once for that set.
|
|
||||||
3. Read the external API documentation.
|
3. Read the external API documentation.
|
||||||
4. Build one definition, using `templateLines` for multiline JSX tool input.
|
4. Build one definition, using `templateLines` for multiline JSX tool input.
|
||||||
5. Validate the definition without saving it and repair every reported issue.
|
5. Validate the definition without saving it and repair every reported issue.
|
||||||
6. Create a preview session.
|
6. Create a preview session.
|
||||||
7. Run `customWidget_previewQuery` for every query returned by the preview and inspect its actual status and data shape. Use
|
7. Run `customWidget_previewQuery` for every query returned by the preview and inspect its actual status and data shape.
|
||||||
`{}` for load queries; manual queries require exactly the returned primitive `parameterNames`.
|
|
||||||
8. Test relevant actions in simulation mode.
|
8. Test relevant actions in simulation mode.
|
||||||
9. Open the returned preview path with browser tools.
|
9. Open the returned preview path with browser tools.
|
||||||
10. Inspect the redacted journal and revise the local candidate until validation, data, and rendering all work. Keep the
|
10. Inspect the redacted journal and revise the local candidate until validation, data, and rendering all work.
|
||||||
exact tested preview candidate locally. Any definition, template, or source change requires a new validation and preview;
|
11. Create the widget, including any source URLs and credentials the user already supplied.
|
||||||
earlier query evidence belongs to the previous preview revision.
|
|
||||||
11. Create the widget from that final tested preview with `customWidget_createFromPreview`. The preview session already carries
|
|
||||||
the source URLs and encrypted credentials supplied during preview; the create call accepts only its session ID plus an
|
|
||||||
optional target board and persists that tested preview.
|
|
||||||
12. Open its returned management path, and use a structured question when the user must choose whether to place it on a board.
|
12. Open its returned management path, and use a structured question when the user must choose whether to place it on a board.
|
||||||
13. Otherwise, ask the user to configure the saved definition with the ten-minute Homarr source-setup URL.
|
13. Otherwise, ask the user to configure the saved definition with the ten-minute Homarr source-setup URL.
|
||||||
14. Create a final preview with the saved definition ID so Homarr loads its stored credentials, then test it again.
|
14. Create a final preview with the saved definition ID so Homarr loads its stored credentials, then test it again.
|
||||||
@@ -131,20 +125,33 @@ To exercise the real Homarr Assistant lifecycle instead of accepting a returned
|
|||||||
OPENROUTER_API_KEY=... pnpm --filter @homarr/custom-widgets test:assistant-ai
|
OPENROUTER_API_KEY=... pnpm --filter @homarr/custom-widgets test:assistant-ai
|
||||||
```
|
```
|
||||||
|
|
||||||
|
The same suites can target the Homarr provider with a Workshop PocketBase token instead of an OpenRouter key:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
AI_PROVIDER_BASE_URL=https://homarr.dev/api/ai/v1 \
|
||||||
|
AI_PROVIDER_API_KEY=<workshop-token> \
|
||||||
|
AI_PROVIDER_MODEL=homarr/model \
|
||||||
|
pnpm --filter @homarr/custom-widgets test:assistant-ai
|
||||||
|
```
|
||||||
|
|
||||||
|
`AI_PROVIDER_JUDGE_MODEL` can select a separate judge when the configured endpoint offers one. The Homarr provider
|
||||||
|
offers exactly one model, so generation and review both use `homarr/model`.
|
||||||
|
|
||||||
The assistant test exposes the same lazy skill, live schema, component catalog, targeted component references,
|
The assistant test exposes the same lazy skill, live schema, component catalog, targeted component references,
|
||||||
validation, preview-query, and create-from-preview tools as the product. It refuses to save a definition that was not
|
validation, preview-query, and create-from-preview tools as the product. It refuses to save a definition that was not
|
||||||
validated exactly or whose preview queries were not all tested. Multi-request fixtures return a different payload for
|
validated exactly or whose preview queries were not all tested. Multi-request fixtures return a different payload for
|
||||||
each documented path and require manual-query parameters. Use `--case=pokedex`, `--case=coinmarketcap-keyless`,
|
each documented path and require manual-query parameters. Use `--case=pokedex`, `--case=coinmarketcap-keyless`,
|
||||||
`--case=bored-activity`, or `--case=agify-name` for a focused run.
|
`--case=bored-activity`, or `--case=agify-name` for a focused run.
|
||||||
|
|
||||||
Both suites default generation and harsh review to OpenRouter's `~deepseek/deepseek-v4-flash-latest` route. They save
|
Both suites use the configured provider models for generation and harsh review. They save tool traces, validated
|
||||||
tool traces, validated manifests, raw reviews, and detailed category scores under
|
manifests, raw reviews, and detailed category scores under
|
||||||
`packages/custom-widgets/.ai-evaluations/`. These live tests are maintainer-invoked rather than CI-required because
|
`packages/custom-widgets/.ai-evaluations/`. These live tests are maintainer-invoked rather than CI-required because
|
||||||
they consume a configured provider account and exercise a nondeterministic model. The repository's ordinary tests
|
they consume a configured provider account and exercise a nondeterministic model. The repository's ordinary tests
|
||||||
cover the lifecycle enforcement, fixture routing, score calculation, and failure behavior without network access.
|
cover the lifecycle enforcement, fixture routing, score calculation, and failure behavior without network access.
|
||||||
|
|
||||||
Each scenario stops as soon as it passes and has a hard limit of ten generation attempts. Override the models or
|
Each scenario stops as soon as it passes and has a hard limit of ten generation attempts. Override the endpoint,
|
||||||
per-scenario limit with `OPENROUTER_GENERATOR_MODEL`, `OPENROUTER_JUDGE_MODEL`, and
|
models, or per-scenario limit with `AI_PROVIDER_BASE_URL`, `AI_PROVIDER_API_KEY`, `AI_PROVIDER_MODEL`,
|
||||||
|
`AI_PROVIDER_JUDGE_MODEL`, and
|
||||||
`CUSTOM_WIDGET_AI_MAX_LOOPS`. Generated artifacts are local and ignored by Git; promote a reviewed, validated result
|
`CUSTOM_WIDGET_AI_MAX_LOOPS`. Generated artifacts are local and ignored by Git; promote a reviewed, validated result
|
||||||
into the bundled-widget source deliberately.
|
into the bundled-widget source deliberately.
|
||||||
|
|
||||||
|
|||||||
@@ -1,37 +1,8 @@
|
|||||||
# Create a Custom Widget
|
# Create a Custom Widget
|
||||||
|
|
||||||
import { CanonicalCustomWidgetExample } from "@site/src/components/custom-widget-code";
|
import { CanonicalCustomWidgetExample } from "@site/src/components/custom-widget-code";
|
||||||
import workbenchImage from "./img/workbench.png";
|
|
||||||
import workbenchMobileImage from "./img/workbench-mobile.png";
|
|
||||||
import workbenchValidationImage from "./img/workbench-validation.png";
|
|
||||||
|
|
||||||
The workbench exposes **General**, **API sources**, **Requests**, **Options**, **JSX**, and **Preview** sections. Advanced JSON is
|
The workbench is visual-first: configure the default API connection, add request cards, add option rows, then write JSX. Additional sources and raw manifest JSON remain under Advanced. Code and preview sit side by side on desktop and use tabs on mobile.
|
||||||
available in the manifest and request/option editors. Code and preview sit side by side on desktop; on smaller screens the
|
|
||||||
**Configure**/**Preview** switch shows one pane at a time and the section navigation scrolls horizontally. Preview sizes display
|
|
||||||
as **S/M/L** (Compact/Standard/Wide), and fixtures are **Live**, **Loading**, **Empty**, or **Error**.
|
|
||||||
For multiline JSX, prefer `templateLines` in agent or MCP input and keep the final tested preview as the source of truth before saving.
|
|
||||||
|
|
||||||
<img
|
|
||||||
src={workbenchImage}
|
|
||||||
alt="Custom Widget workbench with configuration sections and a live preview"
|
|
||||||
style={{ maxWidth: "100%" }}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<img
|
|
||||||
src={workbenchMobileImage}
|
|
||||||
alt="Mobile Custom Widget workbench with Configure and Preview switch and horizontally scrollable section navigation"
|
|
||||||
style={{ maxWidth: "100%" }}
|
|
||||||
/>
|
|
||||||
|
|
||||||
The workbench keeps the configuration and preview together so you can inspect validation diagnostics, the redacted request
|
|
||||||
journal, fixture data, and preview size before saving. Invalid fields stay marked in the form while the preview explains why it
|
|
||||||
needs attention.
|
|
||||||
|
|
||||||
<img
|
|
||||||
src={workbenchValidationImage}
|
|
||||||
alt="Custom Widget workbench showing a Base URL validation error with Test, preview, and Create actions disabled"
|
|
||||||
style={{ maxWidth: "100%" }}
|
|
||||||
/>
|
|
||||||
|
|
||||||
## Manual workflow
|
## Manual workflow
|
||||||
|
|
||||||
@@ -50,9 +21,7 @@ needs attention.
|
|||||||
|
|
||||||
<CanonicalCustomWidgetExample id="widget-options" label="Widget options" example="options" height="360px" />
|
<CanonicalCustomWidgetExample id="widget-options" label="Widget options" example="options" height="360px" />
|
||||||
|
|
||||||
Every option has a default. Supported controls include text, textarea, number, switch, select, multi-select, slider, date, time, color, icon, URL, duration, time zone, and JSON. Dynamic choices use `choicesFrom: { request, itemsPath?, valuePath, labelPath }`; the request must be a load query without invocation parameters, and you cannot provide both static `choices` and `choicesFrom`.
|
Every option has a default. Supported controls include text, textarea, number, switch, select, multi-select, slider, date, time, color, icon, URL, duration, time zone, and JSON. Dynamic choices use `choicesFrom` with a query ID and value/label paths.
|
||||||
|
|
||||||
Preview actions are simulated by default and recorded in the journal without contacting the service. Enable **Run actions against the configured API** only when you intend a real mutation; live actions still require configured confirmation.
|
|
||||||
|
|
||||||
## ChatGPT or Claude
|
## ChatGPT or Claude
|
||||||
|
|
||||||
@@ -62,8 +31,7 @@ The model must return one fenced `json` block containing the complete widget, in
|
|||||||
field. Copy that single block and select **Paste**. Homarr fills the visual builders and the JSX editor
|
field. Copy that single block and select **Paste**. Homarr fills the visual builders and the JSX editor
|
||||||
without any placeholder replacement or second paste.
|
without any placeholder replacement or second paste.
|
||||||
|
|
||||||
Homarr shows all actionable schema or JSX errors inline. Enter credentials separately. The copied prompt does not include the
|
Homarr shows all actionable schema or JSX errors inline. Enter credentials separately. The prompt deliberately
|
||||||
latest preview response; use **Preview** > **Data** to inspect it and mention important response fields in your request. The prompt deliberately
|
|
||||||
recommends a focused Mantine component set, visual hierarchy, responsive layout, theme compatibility, and loading,
|
recommends a focused Mantine component set, visual hierarchy, responsive layout, theme compatibility, and loading,
|
||||||
empty, failure, and success states.
|
empty, failure, and success states.
|
||||||
|
|
||||||
|
|||||||
@@ -7,21 +7,7 @@ Templates are JSX expressions interpreted inside a widget-local safety and rende
|
|||||||
- `options.name` — saved widget configuration
|
- `options.name` — saved widget configuration
|
||||||
- `inputs.name` — temporary values from declarative `bind`
|
- `inputs.name` — temporary values from declarative `bind`
|
||||||
|
|
||||||
The v2 manifest requires a `default` source and supports up to eight sources, 64 requests, and 64 options. Source IDs are
|
|
||||||
case-insensitively unique. Each request allows up to 32 static headers and 32 invalidation targets; a widget can contain
|
|
||||||
up to 24 secrets, each up to 8,192 characters, and templates are limited to 50,000 characters. Validation reports the
|
|
||||||
exact field when a limit is exceeded.
|
|
||||||
|
|
||||||
Authoring input accepts either `template` or `templateLines`, not both. `templateLines` accepts 1–2,000 lines, each up to
|
|
||||||
10,000 characters; after joining lines with newlines, the complete template must still fit the 50,000-character limit.
|
|
||||||
|
|
||||||
The safe interpreter also bounds JSX evaluation: AST depth 64, 25,000 operations, 4,000 collection items, 10,000 rendered
|
|
||||||
nodes, and 200,000 characters in one string or rendered value. API responses are bounded separately before they reach the
|
|
||||||
template.
|
|
||||||
|
|
||||||
Use normal Mantine layouts, typography, feedback, dates, and charts. Official compound names such as `Card.Section`, `Tabs.List`, and `Radio.Group` are supported. Ordinary safe props pass through; a dangerous capability produces an explicit error.
|
Use normal Mantine layouts, typography, feedback, dates, and charts. Official compound names such as `Card.Section`, `Tabs.List`, and `Radio.Group` are supported. Ordinary safe props pass through; a dangerous capability produces an explicit error.
|
||||||
Unsafe URLs, callback props, and unapproved style properties are stripped. Response data is deep-sanitized and budgeted
|
|
||||||
before it reaches `data`, so treat it as untrusted input even when the source is private.
|
|
||||||
|
|
||||||
## Temporary inputs
|
## Temporary inputs
|
||||||
|
|
||||||
@@ -29,7 +15,7 @@ before it reaches `data`, so treat it as untrusted input even when the source is
|
|||||||
<Stack>
|
<Stack>
|
||||||
<TextInput bind="search" defaultValue="" label="Search" />
|
<TextInput bind="search" defaultValue="" label="Search" />
|
||||||
<SubFetch requestId="search" params={{ query: inputs.search }}>
|
<SubFetch requestId="search" params={{ query: inputs.search }}>
|
||||||
{(results, meta) => (
|
{(results) => (
|
||||||
<Stack>
|
<Stack>
|
||||||
{(results ?? []).map((item) => (
|
{(results ?? []).map((item) => (
|
||||||
<Text key={item.id}>{item.name}</Text>
|
<Text key={item.id}>{item.name}</Text>
|
||||||
@@ -46,23 +32,14 @@ Bound values live only in React memory while the widget is mounted. They are not
|
|||||||
|
|
||||||
Use expressions, conditionals, optional chaining, arrays, objects, template strings, safe standard helpers, and expression callbacks for `map`, `filter`, `sort`, and trusted runtime slots. Callback blocks, authored `const`, IIFEs, authored recursion, arbitrary functions, imports, hooks, refs, raw events, browser requests, `eval`, and bigint are blocked.
|
Use expressions, conditionals, optional chaining, arrays, objects, template strings, safe standard helpers, and expression callbacks for `map`, `filter`, `sort`, and trusted runtime slots. Callback blocks, authored `const`, IIFEs, authored recursion, arbitrary functions, imports, hooks, refs, raw events, browser requests, `eval`, and bigint are blocked.
|
||||||
|
|
||||||
Bounded regex literals are supported for string matching, splitting, search, and replacement. Regex literals are limited to
|
Bounded regex literals are supported for string matching, splitting, search, and replacement. Patterns with lookbehind, backreferences, nested quantifiers, excessive length, or unsupported flags are rejected.
|
||||||
128 characters and flags `gimsu`; lookarounds, backreferences, repeated alternatives/groups, unsupported flags, and more
|
|
||||||
than one variable quantifier are rejected.
|
|
||||||
|
|
||||||
## Runtime components
|
## Runtime components
|
||||||
|
|
||||||
- `SubFetch` runs a named query. Automatic queries run when the widget loads; set `trigger="manual"` to defer one and pass
|
- `SubFetch` runs a manual query with its `params`. Set `triggerContent` to a card or image to make that content the accessible click and keyboard trigger instead of showing the default load button.
|
||||||
primitive `params` for its invocation references. With `triggerContent`, any content node (commonly a card or image) becomes
|
- `ActionButton` and `ToggleSwitch` run actions.
|
||||||
the accessible click and keyboard trigger instead of showing the default load button.
|
- `RefreshButton` renders a compact, accessible icon control that refreshes load queries for authenticated viewers. It
|
||||||
- `SubFetch` with `trigger="manual"` keeps its result local to that instance; it does not populate the shared
|
is disabled for anonymous public-board viewers because refreshing invalidates shared server cache state.
|
||||||
`data.requestId` or `status.requestId` roots. The child callback receives `(result, meta)`, while loading, errors, and
|
|
||||||
retry are handled by `SubFetch`. Provide both `triggerContent` and `triggerAriaLabel` when custom content launches it.
|
|
||||||
- `ActionButton` and `ToggleSwitch` run actions only when the widget is mounted outside edit mode. A toggle needs both
|
|
||||||
enabled and disabled request parameters and rolls back its visual state if the action fails.
|
|
||||||
- `RefreshButton` renders a compact, accessible icon control that invalidates the client's load-query cache so active load
|
|
||||||
queries can refetch; it does not execute a request itself. It is disabled when the widget has no active item or preview
|
|
||||||
session, or while the board is in edit mode.
|
|
||||||
- `Icon`/`TablerIcon` resolves installed safe icons.
|
- `Icon`/`TablerIcon` resolves installed safe icons.
|
||||||
|
|
||||||
Always include responsive loading, empty, error, and success states. Runtime failures remain inside the widget tile.
|
Always include responsive loading, empty, error, and success states. Runtime failures remain inside the widget tile.
|
||||||
|
Before Width: | Height: | Size: 58 KiB |
|
Before Width: | Height: | Size: 78 KiB |
|
Before Width: | Height: | Size: 90 KiB |
@@ -42,14 +42,9 @@ interface HomarrCustomWidgetV2 {
|
|||||||
|
|
||||||
### Design with AI
|
### Design with AI
|
||||||
|
|
||||||
The **Design with AI** action is available while creating or editing a custom widget. Describe what the widget should show and,
|
The **Design with AI** action is available while creating or editing a custom widget. Describe what the widget should show and, when [Homarr Assistant](../assistant) is enabled, send the request directly from the form. The assistant receives the widget schema, current non-secret configuration, and latest test response, then proposes the matching create or update tool for your approval.
|
||||||
when [Homarr Assistant](../assistant) is enabled, send the request directly from the form. The generated prompt includes the
|
|
||||||
widget schema and current non-secret configuration, but not the latest preview response. It proposes the matching create or
|
|
||||||
update tool for your approval.
|
|
||||||
|
|
||||||
Use the preview's **Data** tab to inspect the endpoint's real response shape and mention important fields in your request; the
|
Run **Test** first when possible so the prompt includes the endpoint's real response shape. Saved secrets are never added to the prompt. **Copy to clipboard** remains available when the Assistant is disabled or when you prefer another AI service.
|
||||||
copied prompt does not automatically include the latest preview response. Saved secrets are never added to the prompt. **Copy to
|
|
||||||
clipboard** remains available when the Assistant is disabled or when you prefer another AI service.
|
|
||||||
|
|
||||||
<CustomWidgetCodeExample
|
<CustomWidgetCodeExample
|
||||||
id="complete-widget-manifest"
|
id="complete-widget-manifest"
|
||||||
@@ -67,9 +62,9 @@ preview, publish, install, configure, or write secrets, including through HTTP a
|
|||||||
only lists Custom Widget MCP tools, prompts, and resources when its owner is an administrator.
|
only lists Custom Widget MCP tools, prompts, and resources when its owner is an administrator.
|
||||||
|
|
||||||
Adding or configuring a Custom Widget placement requires both administrator access and permission to modify that
|
Adding or configuring a Custom Widget placement requires both administrator access and permission to modify that
|
||||||
board. Duplicating a board that contains Custom Widgets also requires an administrator. A non-administrator with
|
board. A non-administrator with board-modify access can move, resize, change presentation settings, or remove an
|
||||||
board-modify access can move, resize, change presentation settings, or remove an existing placement, but cannot add one,
|
existing placement, but cannot add one, change its definition, refresh interval, or Custom Widget options. Duplicating
|
||||||
change its definition, refresh interval, or Custom Widget options.
|
a board that contains Custom Widgets also requires an administrator.
|
||||||
|
|
||||||
Once an administrator has placed a widget, ordinary board permissions apply to rendering and requests. Authorized
|
Once an administrator has placed a widget, ordinary board permissions apply to rendering and requests. Authorized
|
||||||
non-administrators can use it on private boards, and queries can render for anonymous viewers on public boards.
|
non-administrators can use it on private boards, and queries can render for anonymous viewers on public boards.
|
||||||
@@ -104,8 +99,10 @@ logs, or exports.
|
|||||||
For administrators adding widgets while editing a board, the Custom Widgets section includes **Import from
|
For administrators adding widgets while editing a board, the Custom Widgets section includes **Import from
|
||||||
Workshop**. Non-administrators do not see the Custom Widget picker or Workshop actions. Selecting **Install widget**
|
Workshop**. Non-administrators do not see the Custom Widget picker or Workshop actions. Selecting **Install widget**
|
||||||
opens a two-step modal flow: first review the Workshop entry and its complete source in the read-only editor, then
|
opens a two-step modal flow: first review the Workshop entry and its complete source in the read-only editor, then
|
||||||
confirm API sources and credentials. After import, the new definition appears in the picker. Its tile waits for the board
|
confirm API sources and credentials. The steps keep the same dimensions and the previous step remains available when
|
||||||
to be saved before server requests run.
|
you go back. After import, the new definition appears in the picker. Its tile
|
||||||
|
waits for the board to be saved before server requests run and loads automatically after a successful save; no page
|
||||||
|
reload is required.
|
||||||
|
|
||||||
## Import and Workshop
|
## Import and Workshop
|
||||||
|
|
||||||
@@ -134,7 +131,6 @@ replace the v1 backup.
|
|||||||
|
|
||||||
## Bundled examples
|
## Bundled examples
|
||||||
|
|
||||||
Homarr seeds five disabled examples without credentials and never overwrites an edited seed. They use the same public
|
Homarr seeds five disabled examples without credentials and never overwrites an edited seed. They use the same public contract. The Tautulli example is the highest-scoring widget preserved from Homarr's AI authoring evaluation:
|
||||||
contract. Tautulli Activity is one of the bundled examples preserved from Homarr's AI authoring evaluation:
|
|
||||||
|
|
||||||
<BundledCustomWidgetGallery />
|
<BundledCustomWidgetGallery />
|
||||||
@@ -1,11 +1,6 @@
|
|||||||
# Configure requests and security
|
# Configure requests and security
|
||||||
|
|
||||||
Most widgets use a single source named `default`; the manifest must contain it. Extra keyed sources are available for widgets
|
Most widgets use a single source named `default`. Extra keyed sources are available under Advanced for widgets that combine APIs. Authentication is `none`, `bearer`, `basic`, an API-key header, or an API-key query parameter. Credentials belong to the widget but remain outside its manifest.
|
||||||
that combine APIs. Source IDs are case-insensitively unique. Base URLs must use HTTP(S), contain no embedded credentials,
|
|
||||||
query string, or fragment, and sources can be `public`, `private`, or `loopback`. Authentication is `none`, `bearer`,
|
|
||||||
`basic`, an API-key header, or an API-key query parameter. Credentials belong to the widget but remain outside its manifest.
|
|
||||||
Source origins are fixed by the definition and source-setup flow; widget options and invocation parameters cannot redirect a
|
|
||||||
request to a different origin.
|
|
||||||
|
|
||||||
## Named requests
|
## Named requests
|
||||||
|
|
||||||
@@ -40,28 +35,19 @@ Bind values directly where they are used:
|
|||||||
|
|
||||||
`{option:name}` and `$option` read saved widget options. `{param:name}` and `$param` read invocation-time `params`. Load queries cannot use invocation parameters. Homarr infers the exact parameter names and primitive values from these references, rejecting missing or extra invocation params at the request boundary.
|
`{option:name}` and `$option` read saved widget options. `{param:name}` and `$param` read invocation-time `params`. Load queries cannot use invocation parameters. Homarr infers the exact parameter names and primitive values from these references, rejecting missing or extra invocation params at the request boundary.
|
||||||
|
|
||||||
Path placeholders and query values must resolve to text, numbers, or booleans. `$option` and `$param` references may appear
|
Paths and query-string values must resolve to text, numbers, or booleans. JSON bodies can also use structured `json` and `multiSelect` option values, for example `{ "entity_ids": { "$option": "entities" } }`.
|
||||||
recursively in JSON bodies; invocation parameters remain primitive, and load queries cannot use `$param`. JSON bodies can
|
|
||||||
also use structured `json` and `multiSelect` option values, for example `{ "entity_ids": { "$option": "entities" } }`.
|
|
||||||
|
|
||||||
## Protection
|
## Protection
|
||||||
|
|
||||||
Every request uses Homarr's existing server executor: same-origin source enforcement, network scope, DNS and redirect validation, SSRF protection, board permissions, rate and request limits, body and response limits, timeouts, and encrypted credential injection. Static headers cannot override credentials, cookies, routing, proxy, forwarding, or hop-by-hop headers.
|
Every request uses Homarr's existing server executor: same-origin source enforcement, network scope, DNS and redirect validation, SSRF protection, board permissions, rate and request limits, body and response limits, timeouts, and encrypted credential injection. Static headers cannot override credentials, cookies, routing, proxy, forwarding, or hop-by-hop headers.
|
||||||
|
|
||||||
The executor caps request bodies at 10 KiB and response bodies at 1 MiB. Parsed JSON is limited to depth 32 and 50,000 nodes;
|
|
||||||
each network hop has a ten-second timeout, queries follow at most three same-origin redirects, actions do not follow redirects,
|
|
||||||
and the total request deadline is 45 seconds.
|
|
||||||
|
|
||||||
The limiter allows four concurrent requests per user/item and eight per definition. Per minute, a user/item can make up to 60
|
|
||||||
queries, 10 actions, or 3 DELETE actions; a definition can receive up to 240, 40, or 12 of those request categories.
|
|
||||||
|
|
||||||
Queries default to view permission and actions to modify. DELETE always requires full permission and confirmation. Actions are never cached, retried, or run on load.
|
Queries default to view permission and actions to modify. DELETE always requires full permission and confirmation. Actions are never cached, retried, or run on load.
|
||||||
|
|
||||||
Management and runtime are intentionally separate. A Homarr administrator with board-modify permission places and
|
Management and runtime are intentionally separate. A Homarr administrator with board-modify permission places and
|
||||||
configures the widget. After placement, query and action authorization follows the request's board permission. Public
|
configures the widget. After placement, query and action authorization follows the request's board permission. Public
|
||||||
boards may execute queries for anonymous viewers, but mutations stay authenticated. This includes shared-cache
|
boards may execute queries for anonymous viewers, but mutations stay authenticated. This includes shared-cache
|
||||||
invalidation: `RefreshButton` is disabled only without an active item or preview session, or in edit mode, while ordinary
|
invalidation: `RefreshButton` is disabled for anonymous viewers, while ordinary scheduled query rendering remains
|
||||||
scheduled query rendering remains available to anonymous viewers.
|
available.
|
||||||
|
|
||||||
Responses use bounded, versioned shared-Redis cache keys. Action invalidation advances the shared version so every
|
Responses use bounded, versioned shared-Redis cache keys. Action invalidation advances the shared version so every
|
||||||
Homarr replica stops serving the previous response without scanning or deleting a key prefix.
|
Homarr replica stops serving the previous response without scanning or deleting a key prefix.
|
||||||
@@ -41,8 +41,7 @@ The workbench marks the invalid field while you type. An invalid URL does not re
|
|||||||
|
|
||||||
An invalid definition disables widget preview and Save/Create. The Data, Options, Actions, and Diagnostics tabs remain available so you can correct it.
|
An invalid definition disables widget preview and Save/Create. The Data, Options, Actions, and Diagnostics tabs remain available so you can correct it.
|
||||||
|
|
||||||
The Diagnostics tab shows current schema and JSX errors, accessibility checks, and (after a preview) the redacted request
|
The Diagnostics tab shows the current schema errors.
|
||||||
journal. It does not expose credentials or raw secret values.
|
|
||||||
|
|
||||||
## Workshop unavailable
|
## Workshop unavailable
|
||||||
|
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 164 KiB |
|
Before Width: | Height: | Size: 55 KiB |
@@ -13,9 +13,9 @@ Check [the available integrations](/docs/category/integrations) for further info
|
|||||||
|
|
||||||
## Create an integration
|
## Create an integration
|
||||||
|
|
||||||
To create an integration, you can choose the supported application from the dropdown at the top right:
|
To create an integration, choose **New integration** and select the supported application from the searchable grid. The grid groups related services visually and shows which widgets each integration supports.
|
||||||
|
|
||||||

|
The integrations management page uses a searchable list. Each row shows the integration type and URL, with the actions you have permission to use.
|
||||||
|
|
||||||
Next, you'll need to fill out the required fields to configure the integration:
|
Next, you'll need to fill out the required fields to configure the integration:
|
||||||
|
|
||||||
@@ -59,6 +59,22 @@ It is not allowed to create an integration without passing the test.
|
|||||||
This is to ensure that you minimize the amount of broken applications on your Homarr instance.
|
This is to ensure that you minimize the amount of broken applications on your Homarr instance.
|
||||||
The test and create button will perform a network request to the application and authenticate if required.
|
The test and create button will perform a network request to the application and authenticate if required.
|
||||||
|
|
||||||
|
When you connect a service from a board, Homarr keeps you in the same setup flow. After the connection succeeds, it
|
||||||
|
confirms whether an application shortcut was linked and offers the widgets that support the new integration. Selecting a
|
||||||
|
widget returns to its settings with the new integration already selected.
|
||||||
|
|
||||||
|
Users with full access can also test and update a selected integration from **Edit widget → Edit integration** on a
|
||||||
|
board. Failed tests keep the editor open and show the same connection diagnostics as the management page. Successful
|
||||||
|
changes apply to every app and widget that uses the integration.
|
||||||
|
|
||||||
|
When app creation is not permitted, the setup form offers linking an existing accessible app instead of attempting to
|
||||||
|
create one.
|
||||||
|
|
||||||
|
When the connection unlocks useful widgets that are not on the current board yet, the confirmation also shows up to
|
||||||
|
three explainable recommendations. A recommendation is based only on the services you can use and the widget kinds
|
||||||
|
already present on that board. You can open the existing widget picker prefiltered to the recommendation, or dismiss
|
||||||
|
recommendations for that service on that board.
|
||||||
|
|
||||||
## Managing permissions
|
## Managing permissions
|
||||||
|
|
||||||
On the edit page of an integration, you can manage which users / groups can
|
On the edit page of an integration, you can manage which users / groups can
|
||||||
|
|||||||
@@ -23,9 +23,9 @@ approval before running mutating procedures.
|
|||||||
|
|
||||||
## Getting Started
|
## Getting Started
|
||||||
|
|
||||||
The MCP endpoint lives under the **API** page at `Management` → `Tools` → `API` → **AI / MCP** tab.
|
The MCP endpoint lives under the **API** page at `Management` → `Tools` → `API` → **MCP** tab.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
### 1. Create an API Key
|
### 1. Create an API Key
|
||||||
|
|
||||||
|
|||||||
@@ -8,8 +8,7 @@ tags:
|
|||||||
# Search Engines
|
# Search Engines
|
||||||
|
|
||||||
Using the search engines, terms can be quickly searched simply by opening the search bar at the top or using the keyboard shortcut `CTRL + K`.
|
Using the search engines, terms can be quickly searched simply by opening the search bar at the top or using the keyboard shortcut `CTRL + K`.
|
||||||
|
The management page provides a searchable list with the shortcut, URL template, source, and available row actions for each engine.
|
||||||

|
|
||||||
|
|
||||||
You can add any search engine that has a search URL that accepts a search term as a parameter.
|
You can add any search engine that has a search URL that accepts a search term as a parameter.
|
||||||
|
|
||||||
|
|||||||
@@ -1,169 +0,0 @@
|
|||||||
---
|
|
||||||
tags:
|
|
||||||
- Workshop
|
|
||||||
- Custom Widgets
|
|
||||||
- Custom CSS
|
|
||||||
---
|
|
||||||
|
|
||||||
# Community Workshop
|
|
||||||
|
|
||||||
:::warning Experimental feature
|
|
||||||
|
|
||||||
This feature is experimental and will probably change. If you encounter bugs, need more capabilities, or find something confusing, tell us in the [official discussion thread](https://github.com/homarr-labs/homarr/discussions/categories/custom-widgets). Your feedback directly shapes what comes next. Happy hacking!
|
|
||||||
|
|
||||||
:::
|
|
||||||
|
|
||||||
The [Community Workshop](pathname:///workshop) is where Homarr users share and discover
|
|
||||||
**custom CSS themes** and **custom widgets**. You can browse submissions, upvote the ones
|
|
||||||
you like, report abuse, and install entries directly into your own Homarr instance.
|
|
||||||
|
|
||||||
The central `homarr.dev` Workshop is a public community. Browsing it on the website is public. Browsing, installing,
|
|
||||||
publishing, or importing Workshop content **inside a Homarr instance is restricted to Homarr administrators**.
|
|
||||||
|
|
||||||
:::warning
|
|
||||||
|
|
||||||
The Workshop contains community-made content. Moderation is not a security boundary, and PocketBase does not interpret
|
|
||||||
or validate submission content. Always review widget capabilities, network origins, actions, and CSS before installing.
|
|
||||||
Homarr's installation-time validator is definitive and can reject content that the public service accepted earlier.
|
|
||||||
Back up your instance before installing untrusted content.
|
|
||||||
|
|
||||||
:::
|
|
||||||
|
|
||||||
## Browsing and voting
|
|
||||||
|
|
||||||
- Filter by **Widgets** or **CSS**, show or hide outdated entries, and sort by popularity, creation date, recent updates, or discussion activity.
|
|
||||||
- Sign in with **GitHub** to upvote/downvote, submit your own creations, or report a submission.
|
|
||||||
- Each submission shows its title, description, linked GitHub author, revision, optional screenshots, comments, and full content. Widget pages also summarize API sources, actions, options, network access, and required credentials before installation.
|
|
||||||
- A new submission receives one real upvote owned by its author. Votes remain unique per user and submission.
|
|
||||||
- Open report counts are public on submission cards so visitors can make an informed installation decision. The submission author and Workshop moderators can read each report category and explanation; reporter identities remain moderator-only.
|
|
||||||
- Signed-in moderators see a **Moderation** button in the Workshop header. The moderation queue is sorted by open report count and lets moderators inspect every report, dismiss it, or delete the submission. Reports do not automatically remove a submission.
|
|
||||||
- The manual **Outdated** badge warns visitors that a submission may need an update.
|
|
||||||
|
|
||||||
## Comments
|
|
||||||
|
|
||||||
Comments are publicly readable and appear in chronological conversation bubbles with the author's avatar and GitHub profile. Signed-in users can post; authors can edit or delete their own comments, and Workshop moderators can delete any comment. Failed posts keep the text you typed. When SMTP and `WORKSHOP_PUBLIC_ORIGIN` are configured, the submission author receives one email for a comment from another user. Self-comments, edits, and deletions do not send mail.
|
|
||||||
|
|
||||||
## Submitting
|
|
||||||
|
|
||||||
1. Sign in with GitHub.
|
|
||||||
2. Click **Share yours** and choose the type:
|
|
||||||
- **Custom widget** — paste the JSON exported from **Manage → Custom Widgets → Export**.
|
|
||||||
It must match the `homarr-custom-widget-v2` schema (validated before submission).
|
|
||||||
- **Custom CSS** — paste your stylesheet (max 16384 characters).
|
|
||||||
3. Review the widget JSON or CSS in the syntax-aware editor, then add a title, description, optional screenshots, and changelog.
|
|
||||||
4. Submit the entry.
|
|
||||||
|
|
||||||
Custom widget JSON is normalized to readable multi-line formatting when it is published, and the Workshop detail page
|
|
||||||
also formats older compact submissions before displaying them.
|
|
||||||
|
|
||||||
Community members can report submissions as outdated or no longer working, malicious, spam, copyright-infringing,
|
|
||||||
inappropriate, or another concern. An outdated report does not automatically mark or remove the submission.
|
|
||||||
|
|
||||||
Submissions are published immediately. Reported entries are reviewed and may be removed.
|
|
||||||
Authors can edit a submission later to publish a new revision. The edit form can keep or remove existing screenshots and add new PNG, JPG, or WebP images without changing the Workshop URL.
|
|
||||||
|
|
||||||
When SMTP and `WORKSHOP_PUBLIC_ORIGIN` are configured, every current Workshop moderator receives an email when a report is submitted. If a moderator deletes the reported submission, its author receives a separate removal email. Author self-deletion does not send a moderation email.
|
|
||||||
|
|
||||||
:::info Separate roles
|
|
||||||
|
|
||||||
A Workshop moderator is a user with PocketBase's internal `isAdmin` field. This role moderates the central community
|
|
||||||
and is unrelated to a Homarr instance administrator.
|
|
||||||
|
|
||||||
:::
|
|
||||||
|
|
||||||
## Submission guidelines
|
|
||||||
|
|
||||||
Submissions must be useful to Homarr users and safe to install. Do not submit content that is
|
|
||||||
malicious, deceptive, illegal, hateful, sexually explicit, gore, gambling-focused, spam, or content
|
|
||||||
that primarily promotes unrelated products or services.
|
|
||||||
|
|
||||||
## Installing into Homarr
|
|
||||||
|
|
||||||
You can install workshop entries without leaving Homarr:
|
|
||||||
|
|
||||||
- **Custom widgets (Homarr administrators only)** — go to **Manage → Custom Widgets**, or use **Import from Workshop** in the
|
|
||||||
board widget picker. Choose **Install widget**, review the complete source and capabilities, then confirm API sources and any local secrets in the second modal step.
|
|
||||||
- **Custom CSS from Workshop (Homarr administrators only)** — open a board's **Settings → Custom CSS**, click **Import from Workshop**, choose a theme, review its full CSS in the second same-size modal step, and click **Import CSS** once. The board setting is still saved separately.
|
|
||||||
|
|
||||||
Alternatively, open a submission in the Workshop and use **Download widget JSON** or **Copy CSS**. The submission page shows the matching manual installation steps before the source code.
|
|
||||||
|
|
||||||
Custom Widget imports detect required bearer, basic, header, or query credentials. You can enter them during import or explicitly defer them; secret values are never stored in Workshop content. Missing credentials remain visible on the local Custom Widget afterward.
|
|
||||||
|
|
||||||
## Workshop deployment
|
|
||||||
|
|
||||||
Workshop is powered by [PocketBase](https://pocketbase.io). The production image compiles the current Docusaurus site and serves it together with the API from one origin. The deployment lives in `apps/workshop/` with a Dockerfile, Compose configuration, version-controlled migrations, hooks, a smoke test, and ACT-local workflow instructions.
|
|
||||||
|
|
||||||
Submission links include Open Graph and X/Twitter metadata for the submission title, description, and type. The first uploaded screenshot is used as the social preview image; submissions without screenshots use the Homarr logo.
|
|
||||||
|
|
||||||
Run `pnpm docker:workshop` for PocketBase on port 8090, then run
|
|
||||||
`WORKSHOP_API_URL=http://127.0.0.1:8090 pnpm dev:docs` for Docusaurus on port 3003. `pnpm docker:docs` builds the
|
|
||||||
combined production layout. Normal start and stop commands retain data; `down --volumes` is an intentional,
|
|
||||||
irreversible development reset.
|
|
||||||
|
|
||||||
GitHub needs only the central callback `https://<workshop-host>/api/oauth2-redirect`. Keep PocketBase origins unrestricted
|
|
||||||
unless every self-hosted Homarr caller is explicitly listed. Configure both `GITHUB_CLIENT_ID` and
|
|
||||||
`GITHUB_CLIENT_SECRET`; supplying only one is a startup error. Set `WORKSHOP_PUBLIC_ORIGIN` in production so generated
|
|
||||||
links and email use the public host. Workshop stores only the OAuth provider username in `users.name`, and
|
|
||||||
users cannot rename it. Map **OAuth2 username** to `name`; leave OAuth2 id, full name, and avatar mappings
|
|
||||||
empty. Profile and avatar URLs are derived from `https://github.com/<username>` and
|
|
||||||
`https://github.com/<username>.png`, so PocketBase does not store duplicate profile metadata or avatar files. Configure
|
|
||||||
SMTP for comment, report, and removal notices.
|
|
||||||
|
|
||||||
The public URL contract is:
|
|
||||||
|
|
||||||
| Variable | Purpose | Default |
|
|
||||||
| ------------------------ | ------------------------------------------------- | ----------------------------- |
|
|
||||||
| `HOMARR_WEBSITE_URL` | Documentation/site base used by Homarr links | `https://homarr.dev` |
|
|
||||||
| `WORKSHOP_API_URL` | PocketBase API used by Homarr and standalone docs | `HOMARR_WEBSITE_URL` |
|
|
||||||
| `WORKSHOP_WEB_URL` | Public Workshop page linked from Homarr | `HOMARR_WEBSITE_URL/workshop` |
|
|
||||||
| `WORKSHOP_PUBLIC_ORIGIN` | PocketBase-generated links and email | Required in production |
|
|
||||||
| `PB_ALLOWED_ORIGINS` | PocketBase browser origins | `*` for the central community |
|
|
||||||
|
|
||||||
The deprecated docs-only `WORKSHOP_URL` alias remains for one release; `WORKSHOP_API_URL` takes precedence. The
|
|
||||||
combined Workshop image writes these public URLs into its browser runtime configuration whenever the container starts;
|
|
||||||
the Docker build arguments remain fallbacks. Restart the container after changing these values, without rebuilding it.
|
|
||||||
|
|
||||||
### Staging and demo deployment
|
|
||||||
|
|
||||||
Use `apps/workshop/docker-compose.staging.yml` with the published `ghcr.io/homarr-labs/workshop:v2` image for a v2
|
|
||||||
preview. Copy `apps/workshop/.env.staging.example` to `.env.staging`; its default public contract is:
|
|
||||||
|
|
||||||
```dotenv
|
|
||||||
HOMARR_WEBSITE_URL=https://v2.preview.homarr.dev
|
|
||||||
WORKSHOP_API_URL=https://v2.preview.homarr.dev
|
|
||||||
WORKSHOP_WEB_URL=https://v2.preview.homarr.dev/workshop
|
|
||||||
WORKSHOP_PUBLIC_ORIGIN=https://v2.preview.homarr.dev
|
|
||||||
PB_ALLOWED_ORIGINS=*
|
|
||||||
```
|
|
||||||
|
|
||||||
Start or update it from the repository root:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
docker compose --env-file apps/workshop/.env.staging \
|
|
||||||
-f apps/workshop/docker-compose.staging.yml pull
|
|
||||||
docker compose --env-file apps/workshop/.env.staging \
|
|
||||||
-f apps/workshop/docker-compose.staging.yml up --detach
|
|
||||||
curl --fail http://127.0.0.1:8090/api/health
|
|
||||||
```
|
|
||||||
|
|
||||||
The service binds to `127.0.0.1:8090`. Terminate TLS at a reverse proxy and forward the **entire hostname**, including
|
|
||||||
`/api`, `/_/`, and `/workshop-runtime-config.js`; forwarding only `/workshop` breaks PocketBase and runtime URL loading.
|
|
||||||
This combined image serves both the documentation site and PocketBase, so use a dedicated Workshop hostname if the
|
|
||||||
chosen hostname already serves Homarr itself. In that case, replace the hostname in all four URL values and keep
|
|
||||||
`/workshop` only on `WORKSHOP_WEB_URL`.
|
|
||||||
|
|
||||||
The Compose volume preserves PocketBase data across pulls and container recreation. The mutable `v2` tag is suitable
|
|
||||||
for previews; use the `sha-<commit>` tag for promotion. For the public central Workshop, `PB_ALLOWED_ORIGINS=*` allows
|
|
||||||
self-hosted Homarr origins to use the API and OAuth. A private demo may use a comma-separated origin allowlist instead.
|
|
||||||
GitHub OAuth requires both credentials and the callback
|
|
||||||
`https://v2.preview.homarr.dev/api/oauth2-redirect`. Restart after changing environment values, then verify the health
|
|
||||||
endpoint, `/workshop`, a public listing request, GitHub sign-in, and an installation from the Homarr preview.
|
|
||||||
|
|
||||||
Back up application and PocketBase data before deployment. Publish the combined image by immutable digest, test the
|
|
||||||
exact digest in staging, rehearse application rollback and PocketBase restore, then promote that same digest.
|
|
||||||
|
|
||||||
## Client architecture
|
|
||||||
|
|
||||||
Workshop access is centralized in `@homarr/workshop/backend`. It exports the typed `WorkshopBackend`, its typed PocketBase instance, stable TanStack Query option factories, and the `useWorkshop…` query and mutation hooks used by Homarr. The documentation site uses the same backend rather than maintaining a second API contract.
|
|
||||||
|
|
||||||
Listing fields derived by the `workshop_listings` view—such as submission type, score, and counts—are normalized by the shared client. Healthy deployments keep filtering, sorting, and pagination in PocketBase. If a persistent development volume still has an older view that rejects those fields, the client retries without them and applies the same operations locally; it can also fall back to the base submissions collection. Production deployments should nevertheless apply the current migration so the view exposes the complete metadata.
|
|
||||||
@@ -17,6 +17,8 @@ import { anchorIntegration } from "@site/docs/integrations/anchor";
|
|||||||
|
|
||||||
The Anchor Note widget shows a selected note from your Anchor integration. If your note permissions allow it, you can also edit the note title and content directly in Homarr.
|
The Anchor Note widget shows a selected note from your Anchor integration. If your note permissions allow it, you can also edit the note title and content directly in Homarr.
|
||||||
|
|
||||||
|
Advanced view always shows the note title and update time alongside the complete formatted document, permission, creation date, and pinned or archived state. Compact title and update-time switches do not hide that information in advanced view.
|
||||||
|
|
||||||
### Screenshots
|
### Screenshots
|
||||||
|
|
||||||
import anchorNoteWidgetScreenshot from "./img/widget.png";
|
import anchorNoteWidgetScreenshot from "./img/widget.png";
|
||||||
|
|||||||
@@ -28,8 +28,7 @@ import piHoleApp from "./img/pi-hole-ping-icon.png";
|
|||||||
|
|
||||||
### Interactions
|
### Interactions
|
||||||
|
|
||||||
App tiles stay compact and open their configured destination directly. They do not use the shared widget context menu;
|
App tiles stay compact and open their configured destination directly. Right-click a tile to inspect its status or change its settings when the board and your preferences allow it.
|
||||||
configure the app and its status check from the tile's edit actions.
|
|
||||||
|
|
||||||
### Adding the widget
|
### Adding the widget
|
||||||
|
|
||||||
|
|||||||
@@ -14,9 +14,7 @@ import { archiveTeamWarriorWidget } from ".";
|
|||||||
|
|
||||||
<WidgetHeader widget={archiveTeamWarriorWidget} categories={["Archiving", "Monitoring"]} />
|
<WidgetHeader widget={archiveTeamWarriorWidget} categories={["Archiving", "Monitoring"]} />
|
||||||
|
|
||||||
Use this widget to see what your ArchiveTeam Warrior is preserving without leaving Homarr. The compact view prioritizes the
|
Use this widget to see what your ArchiveTeam Warrior is preserving without leaving Homarr. The compact view keeps the current project, runner state, job counts, bandwidth, and optional broadcast message visible. Advanced view adds the complete active-job list, job start times, project and bandwidth-session identifiers, session transfer totals, exact update time, and the full broadcast message whenever one is available. A failed refresh keeps the last snapshot visible with a stale-data warning.
|
||||||
selected project and Warrior status; shorter tiles can hide secondary counts, bandwidth, or the broadcast message. Advanced
|
|
||||||
view adds the runner status, exact update time, and a scrollable list of reported work items.
|
|
||||||
|
|
||||||
### Supported integration
|
### Supported integration
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ import { AddingWidget } from "@site/src/components/widgets/adding";
|
|||||||
import { WidgetConfig } from "@site/src/components/widgets/configuration";
|
import { WidgetConfig } from "@site/src/components/widgets/configuration";
|
||||||
import { WidgetHeader } from "@site/src/components/widgets/header";
|
import { WidgetHeader } from "@site/src/components/widgets/header";
|
||||||
import { assistantWidget } from ".";
|
import { assistantWidget } from ".";
|
||||||
import assistantWidgetImage from "../../management/img/assistant-widget.png";
|
|
||||||
|
|
||||||
<WidgetHeader widget={assistantWidget} categories={["Productivity"]} />
|
<WidgetHeader widget={assistantWidget} categories={["Productivity"]} />
|
||||||
|
|
||||||
@@ -17,18 +16,7 @@ board. Messages, conversations, tool calls, approvals, files, mentions, model co
|
|||||||
usage details, and response actions remain synchronized with the app-wide assistant.
|
usage details, and response actions remain synchronized with the app-wide assistant.
|
||||||
|
|
||||||
The assistant must be enabled by an administrator in **Management → Assistant**. Signed-out users and users
|
The assistant must be enabled by an administrator in **Management → Assistant**. Signed-out users and users
|
||||||
on an instance without an enabled model see an unavailable state instead of a broken composer. Signed-out users see
|
on an instance without an enabled model see an unavailable state instead of a broken composer.
|
||||||
**Sign in**; a configured provider without a saved model or with **Enable Assistant** off remains unavailable until
|
|
||||||
the administrator saves a working connection, selects a model, and enables the assistant.
|
|
||||||
|
|
||||||
<img
|
|
||||||
src={assistantWidgetImage}
|
|
||||||
alt="Assistant widget embedded on a dashboard with its conversation header, automatic approvals control, model selector, and composer"
|
|
||||||
style={{ maxWidth: "100%" }}
|
|
||||||
/>
|
|
||||||
|
|
||||||
The current preview capture labels the board-embedded surface: its header exposes conversation history, refresh,
|
|
||||||
automatic approvals, and new-conversation controls, while the footer exposes the model, thinking mode, and composer.
|
|
||||||
|
|
||||||
### Adding the widget
|
### Adding the widget
|
||||||
|
|
||||||
@@ -48,9 +36,7 @@ in that layout to keep the complete conversation inline.
|
|||||||
the command menu. This is the default and keeps every assistant entry point synchronized.
|
the command menu. This is the default and keeps every assistant entry point synchronized.
|
||||||
|
|
||||||
**Pinned conversation** reveals a searchable conversation selector. A pinned widget never changes the
|
**Pinned conversation** reveals a searchable conversation selector. A pinned widget never changes the
|
||||||
active conversation silently: select **Open conversation** inside the widget before continuing that thread. If the pinned
|
active conversation silently: select **Open conversation** inside the widget before continuing that thread.
|
||||||
thread was deleted or cannot be opened, the widget keeps the pinned selection, shows the same recovery action and a
|
|
||||||
retry state, and retries that thread when **Open conversation** is selected again.
|
|
||||||
|
|
||||||
### Conversation features
|
### Conversation features
|
||||||
|
|
||||||
@@ -64,16 +50,10 @@ retry state, and retries that thread when **Open conversation** is selected agai
|
|||||||
- Edit user messages and copy, regenerate, branch, quote, export, or rate responses.
|
- Edit user messages and copy, regenerate, branch, quote, export, or rate responses.
|
||||||
- Inspect syntax-highlighted Markdown, sources, generated files, tool results, streaming chain-of-thought,
|
- Inspect syntax-highlighted Markdown, sources, generated files, tool results, streaming chain-of-thought,
|
||||||
cumulative conversation usage, per-turn token and context use, timing, speed, provider routing, and cost.
|
cumulative conversation usage, per-turn token and context use, timing, speed, provider routing, and cost.
|
||||||
- Change the model and reasoning effort for the active conversation. A model choice is saved per persisted thread,
|
- Change the model and reasoning effort for the active conversation.
|
||||||
does not change the administrator's default, and is restored when that thread is selected again; a new thread
|
|
||||||
starts from the configured default.
|
|
||||||
- Refresh the current board from the conversation header. Approved mutations also refresh visible board data automatically.
|
- Refresh the current board from the conversation header. Approved mutations also refresh visible board data automatically.
|
||||||
|
|
||||||
The expanded assistant and board widget use the same persisted thread runtime. A response continues in the
|
The expanded assistant and board widget use the same persisted thread runtime. A response continues in the
|
||||||
background when the widget leaves the viewport or the expanded panel is minimized. Each visible surface keeps an
|
background when the widget leaves the viewport or the expanded panel is minimized. Each visible surface keeps an
|
||||||
independent draft, attachments, selection, and focus, so typing in a board widget cannot move or overwrite the
|
independent draft, attachments, selection, and focus, so typing in a board widget cannot move or overwrite the
|
||||||
floating panel composer.
|
floating panel composer.
|
||||||
|
|
||||||
Automatic approvals are off by default, reset when switching conversations, and never select a neutral choice. A
|
|
||||||
structured question shows **Other** only when the tool allows it (`allowOther` is not `false`); selecting **Other**
|
|
||||||
opens a manual freeform response even when automatic approvals are enabled.
|
|
||||||
@@ -36,7 +36,9 @@ import widgetOverview from "./img/widget-overview.png";
|
|||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<WidgetInteractionGuide advancedView={false} />
|
Advanced view shows every missing-subtitle and health summary regardless of compact visibility options, together with the already-fetched Sonarr and Radarr SignalR states and announcement count.
|
||||||
|
|
||||||
|
<WidgetInteractionGuide advancedView />
|
||||||
|
|
||||||
### Adding the widget
|
### Adding the widget
|
||||||
|
|
||||||
|
|||||||
@@ -4,11 +4,12 @@ description: "Card grid view of all Beszel-monitored systems with real-time metr
|
|||||||
hide_title: true
|
hide_title: true
|
||||||
---
|
---
|
||||||
|
|
||||||
|
import { WidgetInteractionGuide } from "@site/src/components/widgets/interactions";
|
||||||
|
|
||||||
import { WidgetHeader } from "@site/src/components/widgets/header";
|
import { WidgetHeader } from "@site/src/components/widgets/header";
|
||||||
import { AddingWidget } from "@site/src/components/widgets/adding";
|
import { AddingWidget } from "@site/src/components/widgets/adding";
|
||||||
import { WidgetConfig } from "@site/src/components/widgets/configuration";
|
import { WidgetConfig } from "@site/src/components/widgets/configuration";
|
||||||
import { WidgetIntegrations } from "@site/src/components/widgets/integrations";
|
import { WidgetIntegrations } from "@site/src/components/widgets/integrations";
|
||||||
import { WidgetInteractionGuide } from "@site/src/components/widgets/interactions";
|
|
||||||
import { beszelSystemGridWidget } from ".";
|
import { beszelSystemGridWidget } from ".";
|
||||||
import { beszelIntegration } from "@site/docs/integrations/beszel";
|
import { beszelIntegration } from "@site/docs/integrations/beszel";
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ import beszelSystemStats from "./img/beszel-system-stats.png";
|
|||||||
|
|
||||||
<WidgetHeader widget={beszelSystemStatsWidget} categories={["System Monitoring", "Charts"]} />
|
<WidgetHeader widget={beszelSystemStatsWidget} categories={["System Monitoring", "Charts"]} />
|
||||||
|
|
||||||
This widget displays time-series charts for a selected Beszel system, including CPU, memory, disk, network, and Docker container metrics. The Disk Usage chart combines the root disk and every extra filesystem reported by Beszel. Use the widget controls to switch between the realtime Live view and historical periods ranging from 1 hour to 30 days. Live view keeps a one-minute window and pauses while the browser tab is hidden. If the live stream drops, the widget now shows the connection failure state immediately and can switch back to historical data.
|
This widget displays time-series charts for a selected Beszel system, including CPU, memory, disk, network, and Docker container metrics. The Disk Usage chart combines the root disk and every extra filesystem reported by Beszel. Hover over or focus the widget controls to switch between the realtime Live view and historical periods ranging from 1 hour to 30 days. Live view keeps a one-minute window and pauses while the browser tab is hidden. If the live stream drops, the widget now shows the connection failure state immediately and can switch back to historical data.
|
||||||
|
|
||||||
### Screenshots
|
### Screenshots
|
||||||
|
|
||||||
|
|||||||
@@ -4,11 +4,12 @@ description: "Table view of all Beszel-monitored systems with sortable columns a
|
|||||||
hide_title: true
|
hide_title: true
|
||||||
---
|
---
|
||||||
|
|
||||||
|
import { WidgetInteractionGuide } from "@site/src/components/widgets/interactions";
|
||||||
|
|
||||||
import { WidgetHeader } from "@site/src/components/widgets/header";
|
import { WidgetHeader } from "@site/src/components/widgets/header";
|
||||||
import { AddingWidget } from "@site/src/components/widgets/adding";
|
import { AddingWidget } from "@site/src/components/widgets/adding";
|
||||||
import { WidgetConfig } from "@site/src/components/widgets/configuration";
|
import { WidgetConfig } from "@site/src/components/widgets/configuration";
|
||||||
import { WidgetIntegrations } from "@site/src/components/widgets/integrations";
|
import { WidgetIntegrations } from "@site/src/components/widgets/integrations";
|
||||||
import { WidgetInteractionGuide } from "@site/src/components/widgets/interactions";
|
|
||||||
import { beszelSystemTableWidget } from ".";
|
import { beszelSystemTableWidget } from ".";
|
||||||
import { beszelIntegration } from "@site/docs/integrations/beszel";
|
import { beszelIntegration } from "@site/docs/integrations/beszel";
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import { bookmarksWidget } from ".";
|
|||||||
The bookmarks widget allows you to display multiple app links in a single widget.
|
The bookmarks widget allows you to display multiple app links in a single widget.
|
||||||
You can add links to your favorite applications, websites, or any other resources you want quick access to.
|
You can add links to your favorite applications, websites, or any other resources you want quick access to.
|
||||||
Its normal view adapts each configured layout to the available width and height: lower-priority hostnames are hidden before names or icons, and larger collections scroll instead of crushing cards.
|
Its normal view adapts each configured layout to the available width and height: lower-priority hostnames are hidden before names or icons, and larger collections scroll instead of crushing cards.
|
||||||
|
Advanced view shows every bookmark as a roomy card with its full title, hostname, icon, and complete description regardless of the compact layout and visibility choices.
|
||||||
|
|
||||||
### Screenshots
|
### Screenshots
|
||||||
|
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 45 KiB |
|
Before Width: | Height: | Size: 17 KiB |
@@ -31,12 +31,16 @@ the same data is requested through Homarr's MCP or Assistant tools.
|
|||||||
|
|
||||||
### Screenshots
|
### Screenshots
|
||||||
|
|
||||||
import currentView from "./img/current-view.png";
|
import popover from "./img/popover.png";
|
||||||
import advancedView from "./img/advanced-view.png";
|
import withIntegrations from "./img/with-integrations.png";
|
||||||
|
import withoutIntegrations from "./img/without-integrations.png";
|
||||||
|
|
||||||
<div className="flex flex-col gap-1">
|
<div className="flex gap-1">
|
||||||
<img src={currentView} alt="Calendar month view with marked events" width={513} height={303} />
|
<img src={withIntegrations} alt="calendar with-integrations big-size" width={256 + 4} height={256 + 4} />
|
||||||
<img src={advancedView} alt="Calendar advanced view with grouped events" width={800} height={484} />
|
<div className="flex flex-col gap-1">
|
||||||
|
<img src={popover} alt="calendar popover-details the-mandalorian" width={128 * 3} height={128} />
|
||||||
|
<img src={withoutIntegrations} alt="calendar without-integrations small-size" width={256} height={128} />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
### Supported Integrations
|
### Supported Integrations
|
||||||
@@ -70,7 +74,7 @@ import advancedView from "./img/advanced-view.png";
|
|||||||
### Interactions
|
### Interactions
|
||||||
|
|
||||||
- Hover over a marked date to preview its events in a popover.
|
- Hover over a marked date to preview its events in a popover.
|
||||||
- The advanced view replaces the month grid with a grouped event list. Use its previous and next controls to change months.
|
- The advanced view replaces the month grid with a grouped event list, keeps every event attributed to its source integration, and expands titles, locations, and descriptions. Use its previous and next controls to change months.
|
||||||
- If one selected integration is unavailable, its warning indicator remains visible while events from healthy integrations continue to load.
|
- If one selected integration is unavailable, its warning indicator remains visible while events from healthy integrations continue to load.
|
||||||
|
|
||||||
<WidgetInteractionGuide />
|
<WidgetInteractionGuide />
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ import tokyoClock from "./img/tokyo-12-hour.png";
|
|||||||
<img src={tokyoClock} alt="clock format-12-hours timezone-tokyo" width={256} height={128} />
|
<img src={tokyoClock} alt="clock format-12-hours timezone-tokyo" width={256} height={128} />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<WidgetInteractionGuide />
|
<WidgetInteractionGuide advancedView={false} />
|
||||||
|
|
||||||
### Adding the widget
|
### Adding the widget
|
||||||
|
|
||||||
|
|||||||
@@ -27,7 +27,11 @@ The Coolify widget displays a compact overview of your Coolify instance. It can
|
|||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<WidgetInteractionGuide advancedView={false} />
|
Advanced view opens the Servers, Applications, and Services sections regardless of their compact visibility switches. It identifies each Coolify integration, shows server `is_reachable` and `is_usable` values, and lists applications nested in services when the API provides them. Healthy integrations remain visible if another source fails, with the failed source identified by a warning.
|
||||||
|
|
||||||
|
IP addresses remain masked in advanced view until you explicitly use the eye control. Public resource, Coolify dashboard, and log links retain the widget's safe new-tab handling.
|
||||||
|
|
||||||
|
<WidgetInteractionGuide advancedView />
|
||||||
|
|
||||||
### Adding the widget
|
### Adding the widget
|
||||||
|
|
||||||
|
|||||||
@@ -32,8 +32,7 @@ Credentials remain on the server.
|
|||||||
|
|
||||||
:::note
|
:::note
|
||||||
Custom API widgets must first be created in **Management → Custom Widgets** before they appear in the widget picker.
|
Custom API widgets must first be created in **Management → Custom Widgets** before they appear in the widget picker.
|
||||||
Action buttons require the request's minimum board permission, which is `modify` by default. Anonymous viewers cannot run
|
Action buttons can only be executed by administrators.
|
||||||
mutations. DELETE additionally requires full permission and confirmation.
|
|
||||||
:::
|
:::
|
||||||
|
|
||||||
### Permissions and actions
|
### Permissions and actions
|
||||||
|
|||||||
@@ -20,9 +20,9 @@ import { technitiumDnsIntegration } from "@site/docs/integrations/technitium-dns
|
|||||||
|
|
||||||
<WidgetHeader widget={dnsHoleControlsWidget} categories={["DNS Hole"]} />
|
<WidgetHeader widget={dnsHoleControlsWidget} categories={["DNS Hole"]} />
|
||||||
|
|
||||||
This widget lets permitted users enable, disable, or temporarily pause one or more DNS services. It shares the summary query
|
When several DNS integrations are selected, Homarr keeps healthy controls available if one source fails and shows a warning identifying the unavailable integration.
|
||||||
and cache with DNS Hole Summary. Cards and controls adapt to the widget's width and height. Sources that fail to load are
|
|
||||||
omitted from the returned summaries; bulk actions keep successful results visible and report the number of failures.
|
This widget lets permitted users enable, disable, or temporarily pause one or more DNS services. It shares the summary query and cache with DNS Hole Summary. Every selected source stays available in the normal scrollable view, while cards and controls adapt to the widget's width and height.
|
||||||
|
|
||||||
### Screenshots
|
### Screenshots
|
||||||
|
|
||||||
|
|||||||
@@ -17,6 +17,8 @@ import { dnsHoleSummaryWidget } from ".";
|
|||||||
|
|
||||||
<WidgetHeader widget={dnsHoleSummaryWidget} categories={["DNS Hole"]} />
|
<WidgetHeader widget={dnsHoleSummaryWidget} categories={["DNS Hole"]} />
|
||||||
|
|
||||||
|
When several DNS integrations are selected, Homarr keeps healthy sources visible if one source fails and shows a warning identifying the unavailable integration.
|
||||||
|
|
||||||
This widget combines statistics from every selected DNS service, including total queries, blocked queries, and blocklist size. Its data is cached under the same DNS query family as DNS Hole Controls, so placing both widgets on a board does not create a second integration request. When the widget has enough room, it adds a scrollable status row naming each selected source.
|
This widget combines statistics from every selected DNS service, including total queries, blocked queries, and blocklist size. Its data is cached under the same DNS query family as DNS Hole Controls, so placing both widgets on a board does not create a second integration request. When the widget has enough room, it adds a scrollable status row naming each selected source.
|
||||||
|
|
||||||
### Screenshots
|
### Screenshots
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 39 KiB |
@@ -8,7 +8,6 @@ import { WidgetHeader } from "@site/src/components/widgets/header";
|
|||||||
import { AddingWidget } from "@site/src/components/widgets/adding";
|
import { AddingWidget } from "@site/src/components/widgets/adding";
|
||||||
import { WidgetConfig } from "@site/src/components/widgets/configuration";
|
import { WidgetConfig } from "@site/src/components/widgets/configuration";
|
||||||
import { WidgetIntegrations } from "@site/src/components/widgets/integrations";
|
import { WidgetIntegrations } from "@site/src/components/widgets/integrations";
|
||||||
import { WidgetInteractionGuide } from "@site/src/components/widgets/interactions";
|
|
||||||
import { IconAd } from "@tabler/icons-react";
|
import { IconAd } from "@tabler/icons-react";
|
||||||
import Tabs from "@theme/Tabs";
|
import Tabs from "@theme/Tabs";
|
||||||
import TabItem from "@theme/TabItem";
|
import TabItem from "@theme/TabItem";
|
||||||
@@ -50,8 +49,6 @@ Each container row has an action menu, accessible via the three-dot icon or by r
|
|||||||
- **Remove** - permanently remove the container after a second confirmation click
|
- **Remove** - permanently remove the container after a second confirmation click
|
||||||
- **Add to Homarr** - create a bookmark app from the container
|
- **Add to Homarr** - create a bookmark app from the container
|
||||||
|
|
||||||
<WidgetInteractionGuide advancedView={false} />
|
|
||||||
|
|
||||||
### Adding the widget
|
### Adding the widget
|
||||||
|
|
||||||
<AddingWidget />
|
<AddingWidget />
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 116 KiB |
|
Before Width: | Height: | Size: 76 KiB |
@@ -21,79 +21,36 @@ import { downloadsWidget } from ".";
|
|||||||
|
|
||||||
<WidgetHeader widget={downloadsWidget} categories={["Torrent client", "Usenet client", "Downloads"]} />
|
<WidgetHeader widget={downloadsWidget} categories={["Torrent client", "Usenet client", "Downloads"]} />
|
||||||
|
|
||||||
This widget displays torrent, Usenet, and miscellaneous download jobs, along with their progress and other relevant information. It supports 7 download client integrations and provides a rich, responsive table interface.
|
This widget displays a list of torrents or usenet-articles that are currently being downloaded, along with their progress and other relevant information. It supports 7 download client integrations and provides a rich, responsive table interface.
|
||||||
|
|
||||||
### Screenshots
|
### Screenshots
|
||||||
|
|
||||||
import downloadsCard from "./img/screenshot.png";
|
import downloadsCard from "./img/screenshot.png";
|
||||||
import contextMenuImg from "./img/context-menu.png";
|
import contextMenuImg from "./img/context-menu.png";
|
||||||
import advancedViewImg from "./img/advanced-view.png";
|
|
||||||
import filterPanelImg from "./img/filter-panel.png";
|
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<img src={downloadsCard} alt="Downloads widget showing torrent and usenet items" width={128 * 4} />
|
<img src={downloadsCard} alt="Downloads widget showing torrent and usenet items" width={128 * 4} />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
#### Download-row context menu
|
#### Right-click context menu
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<img src={contextMenuImg} alt="Downloads row context menu with pause, delete, and copy actions" width={128 * 4} />
|
<img src={contextMenuImg} alt="Downloads widget context menu with pause, delete, and copy actions" width={128 * 4} />
|
||||||
</div>
|
|
||||||
|
|
||||||
#### Advanced view
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<img
|
|
||||||
src={advancedViewImg}
|
|
||||||
alt="Downloads widget in advanced view with stats, sortable columns, and expanded details"
|
|
||||||
width={128 * 6}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
#### Advanced filter panel
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<img src={filterPanelImg} alt="Downloads advanced view with the status filter panel open" width={128 * 6} />
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
### Features
|
### Features
|
||||||
|
|
||||||
- **Responsive compact table** — in compact mode, selected columns adapt to both widget width and height; narrow or short tiles hide speed/state columns, and the shortest tiles also hide the ETA column
|
- **Responsive table** — columns automatically adapt to widget width, hiding less important columns at smaller sizes
|
||||||
- **Sortable columns** — click any sortable column header to sort the current view; the configured default controls the initial column and direction
|
- **Sortable columns** — click any column header to sort ascending/descending
|
||||||
- **Column customization** — choose which columns to display, then hover a header to reveal its grab handle for reordering or drag its edge to resize it; layouts save automatically per widget
|
- **Column customization** — choose which columns to display, then hover a header to reveal its grab handle for reordering or drag its edge to resize it; layouts save automatically per widget
|
||||||
- **Download-row context menu** — copy a download name or ID from any row; pause, resume, and delete actions appear when you have Interact access to that integration
|
- **Right-click context menu** — pause, resume, delete downloads, or copy download names directly from the context menu
|
||||||
- **Row expansion** — click any row to see full details inline without opening a separate modal
|
- **Row expansion** — click any row to see full details inline without opening a separate modal
|
||||||
- **Hover tooltips** — hover a download name to see size, speeds, ETA, ratio, and category; open tooltips close when switching between compact and advanced mode
|
- **Hover tooltips** — hover a download name to see size, speeds, ETA, ratio, and category; open tooltips close when switching between compact and advanced mode
|
||||||
- **Global stats bar** — show queue progress, downloaded/total size, transfer speeds, global torrent ratio, and per-state counts in compact mode; advanced view always includes it
|
- **Global stats bar** — toggle a summary bar showing queue progress, total size, speeds, ratio, and per-state counts
|
||||||
- **Client filtering** — filter downloads by integration or status using the footer filter panel
|
- **Client filtering** — filter downloads by integration or status using the footer filter panel
|
||||||
- **Global controls** — pause/resume actionable queues from the footer bar, limited to selected integrations where you have Interact access
|
- **Global controls** — pause/resume all downloads across all clients from the footer bar
|
||||||
- **Status indicators** — color-coded badges show download state at a glance
|
- **Status indicators** — color-coded badges show download state at a glance
|
||||||
- **Speed overview** — total download and upload speeds for the selected clients are displayed in the footer
|
- **Speed overview** — total download and upload speeds displayed in the footer
|
||||||
|
|
||||||
:::note
|
|
||||||
|
|
||||||
Compact layouts use both dimensions: below 500px wide, speed columns are hidden; below 300px wide, the ETA and state
|
|
||||||
columns are hidden too. A tile shorter than 180px hides speed and state columns, and a tile shorter than 120px also
|
|
||||||
hides ETA. The footer is hidden below 96px in compact mode. Advanced view bypasses these compact size reductions,
|
|
||||||
keeps the selected column set, and always includes the stats bar and footer controls, with the filter panel available
|
|
||||||
from the footer.
|
|
||||||
|
|
||||||
The filter panel changes the visible rows. Its client/status filters also change the stats bar's progress, size, and
|
|
||||||
state counts, while transfer-speed totals summarize the selected clients and the global torrent ratio summarizes the
|
|
||||||
selected torrent clients. The configured category/label filter can optionally be applied to the global torrent ratio
|
|
||||||
through **Use category filter for global torrent ratio**; footer client/status filters do not change that ratio.
|
|
||||||
|
|
||||||
The per-item **Ratio** is sent bytes divided by the item's total size. **Global Ratio** is total uploaded bytes divided
|
|
||||||
by total downloaded bytes.
|
|
||||||
|
|
||||||
Mutation controls depend on the integration's Interact permission. Users without that permission can still view rows and
|
|
||||||
use the row menu's copy actions. `slskd` is list-only: its pause, resume, and delete operations are no-ops, so those
|
|
||||||
controls have no effect for that client even when Interact permission exposes them.
|
|
||||||
|
|
||||||
The screenshot above is a Downloads row menu, separate from the shared widget context menu. When board right-click menus
|
|
||||||
are enabled, the shared menu provides widget-level actions such as advanced view, widget options, refresh, and settings.
|
|
||||||
|
|
||||||
:::
|
|
||||||
|
|
||||||
### Supported Integrations
|
### Supported Integrations
|
||||||
|
|
||||||
@@ -125,20 +82,20 @@ are enabled, the shared menu provides widget-level actions such as advanced view
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
integration: slskdIntegration,
|
integration: slskdIntegration,
|
||||||
note: "Soulseek client (list-only; mutation controls are no-ops)",
|
note: "Soulseek client (read-only)",
|
||||||
},
|
},
|
||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
### Interactions
|
### Interactions
|
||||||
|
|
||||||
- **Right-click** any download to copy its name or ID; pause, resume, and delete are available only with Interact access
|
- **Right-click** any download to open a context menu with pause/resume, delete, and copy actions
|
||||||
- **Click** any row to expand it and see full download details inline
|
- **Click** any row to expand it and see full download details inline
|
||||||
- **Hover** a download name for a quick stats tooltip
|
- **Hover** a download name for a quick stats tooltip
|
||||||
- **Stats toggle** — show or hide the global stats bar in compact mode; advanced view always shows the stats bar
|
- **Stats toggle** — show or hide the global stats bar from the footer
|
||||||
- **Pause / Resume** actionable queues using the footer controls
|
- **Pause / Resume** all downloads using the footer controls
|
||||||
- **Filter** rows by integration or status using the filter button in the footer
|
- **Filter** by integration or status using the filter button in the footer
|
||||||
- **Sort** by clicking sortable column headers; the default sort is configured per widget, while header changes apply to the current view
|
- **Sort** by clicking column headers (with persistent sort direction)
|
||||||
|
|
||||||
<WidgetInteractionGuide />
|
<WidgetInteractionGuide />
|
||||||
|
|
||||||
|
|||||||
@@ -30,20 +30,19 @@ export const downloadsWidget: WidgetDefinition = {
|
|||||||
{
|
{
|
||||||
name: "Columns to show",
|
name: "Columns to show",
|
||||||
description:
|
description:
|
||||||
"Select the columns you want to display in the widget. Compact layouts automatically hide/show selected columns based on widget width and height; advanced view keeps the selected columns visible.",
|
"Select the columns you want to display in the widget. Columns automatically hide/show based on widget width.",
|
||||||
values: `List of columns: ${columnsList.join(", ")}`,
|
values: `List of columns: ${columnsList.join(", ")}`,
|
||||||
defaultValue: ["name", "progress", "downSpeed", "time", "state"].join(", "),
|
defaultValue: ["name", "progress", "downSpeed", "time", "state"].join(", "),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Default sort column",
|
name: "Default sort column",
|
||||||
description:
|
description: "The column used for initial sorting when the widget loads.",
|
||||||
"The column used for initial sorting when the widget loads. Clicking a column header changes the current view only.",
|
|
||||||
defaultValue: "progress",
|
defaultValue: "progress",
|
||||||
values: `List of columns: ${sortColumns.join(", ")}`,
|
values: `List of columns: ${sortColumns.join(", ")}`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Invert sorting",
|
name: "Invert sorting",
|
||||||
description: "This sets the initial sorting direction.",
|
description: "This will invert the default sorting order.",
|
||||||
values: { type: "boolean" },
|
values: { type: "boolean" },
|
||||||
defaultValue: "no",
|
defaultValue: "no",
|
||||||
},
|
},
|
||||||
@@ -67,7 +66,8 @@ export const downloadsWidget: WidgetDefinition = {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Hide completed torrent under this threshold (in kiB/s)",
|
name: "Hide completed torrent under this threshold (in kiB/s)",
|
||||||
description: "This will hide completed torrent entries whose upload speed is below the specified threshold.",
|
description:
|
||||||
|
"This will hide completed torrent entries that have a download speed below the specified threshold.",
|
||||||
values: "Any number above 0, 0 to disable",
|
values: "Any number above 0, 0 to disable",
|
||||||
defaultValue: "0",
|
defaultValue: "0",
|
||||||
},
|
},
|
||||||
@@ -85,16 +85,15 @@ export const downloadsWidget: WidgetDefinition = {
|
|||||||
defaultValue: "no",
|
defaultValue: "no",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Use category filter for global torrent ratio",
|
name: "Use filter to calculate Ratio",
|
||||||
description:
|
description: "This will use the category filter when calculating the global torrent ratio.",
|
||||||
"When enabled, the configured category/label filter is applied to the global torrent ratio. Footer client/status filters do not change this ratio.",
|
|
||||||
values: { type: "boolean" },
|
values: { type: "boolean" },
|
||||||
defaultValue: "yes",
|
defaultValue: "yes",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Limit items per integration",
|
name: "Limit items per integration",
|
||||||
description: "This will limit the number of items shown per integration, not globally.",
|
description: "This will limit the number of items shown per integration, not globally.",
|
||||||
values: "Any whole number from 1 upward",
|
values: "Any number above 1",
|
||||||
defaultValue: "50",
|
defaultValue: "50",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -23,6 +23,8 @@ import { glancesIntegration } from "@site/docs/integrations/glances";
|
|||||||
|
|
||||||
This widget displays information about the health and status of your system(s), including CPU, memory, disk usage, and more.
|
This widget displays information about the health and status of your system(s), including CPU, memory, disk usage, and more.
|
||||||
|
|
||||||
|
Advanced view is a complete health workspace: it shows every available CPU, temperature, memory, GPU, filesystem, update, reboot, and system-information section even when compact visibility switches hide some of them on the board. Proxmox clusters likewise show uptime, CPU, memory, and every node, VM, container, and storage section. Storage-volume filters, units, and permissions remain in effect.
|
||||||
|
|
||||||
### Screenshots
|
### Screenshots
|
||||||
|
|
||||||
import systemView from "./img/system-view.png";
|
import systemView from "./img/system-view.png";
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ import screen from "./img/screen.png";
|
|||||||
|
|
||||||
<WidgetInteractionGuide />
|
<WidgetInteractionGuide />
|
||||||
|
|
||||||
Use the pause or resume control to pause its slideshow; touch devices keep the control available. A paused slideshow keeps its resume control visible. The advanced view displays the complete photo without cropping, groups previous, pause or resume, and next together, and includes every loaded photo in its thumbnail strip.
|
Hover or focus the widget to pause its slideshow; touch devices keep the control available. A paused slideshow keeps its resume control visible. The advanced view displays the complete photo without cropping, groups previous, pause or resume, and next together, and includes every loaded photo in its thumbnail strip. If an Immich refresh fails, the last loaded album stays visible with a stale-data warning.
|
||||||
|
|
||||||
### Adding the widget
|
### Adding the widget
|
||||||
|
|
||||||
|
|||||||
@@ -18,6 +18,8 @@ import { sonarrIntegration } from "@site/docs/integrations/sonarr";
|
|||||||
|
|
||||||
Monitor which movies and episodes are missing from your library, and track what is currently being downloaded. The widget pulls data from Radarr and Sonarr and groups results by type in two tabs.
|
Monitor which movies and episodes are missing from your library, and track what is currently being downloaded. The widget pulls data from Radarr and Sonarr and groups results by type in two tabs.
|
||||||
|
|
||||||
|
Advanced view always shows both Missing and Queued panels side by side when space allows, requests at least 50 items per source, exposes queue status and time remaining, and keeps partial-integration warnings visible. Compact tab visibility and page-size choices continue to shape the board tile.
|
||||||
|
|
||||||
### Screenshots
|
### Screenshots
|
||||||
|
|
||||||
import widgetMissing from "./img/missing.png";
|
import widgetMissing from "./img/missing.png";
|
||||||
|
|||||||
@@ -19,6 +19,10 @@ import { plexIntegration } from "@site/docs/integrations/plex";
|
|||||||
|
|
||||||
Provides a list of newly added media or upcoming releases from your media server.
|
Provides a list of newly added media or upcoming releases from your media server.
|
||||||
|
|
||||||
|
Releases retain the name and icon of the integration that supplied them. If one integration is unavailable, releases from healthy integrations remain visible and a warning identifies the failed source without exposing connection details. The widget reports an error only when every selected integration fails.
|
||||||
|
|
||||||
|
Advanced view displays every release in a roomy poster layout with its complete available metadata, description, tags, and visible source name, regardless of the compact layout and visibility options.
|
||||||
|
|
||||||
### Screenshots
|
### Screenshots
|
||||||
|
|
||||||
import backdrop from "./img/backdrop.png";
|
import backdrop from "./img/backdrop.png";
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 48 KiB |
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 7.3 KiB |
@@ -24,19 +24,15 @@ import { plexIntegration } from "@site/docs/integrations/plex";
|
|||||||
The media server widget shows active sessions across your media servers.
|
The media server widget shows active sessions across your media servers.
|
||||||
It shows playback progress, pause state, time remaining, and whether each session is direct play, direct stream, or transcoding audio or video. Location and bitrate can be toggled independently.
|
It shows playback progress, pause state, time remaining, and whether each session is direct play, direct stream, or transcoding audio or video. Location and bitrate can be toggled independently.
|
||||||
|
|
||||||
Select a session to inspect its media metadata in an anchored popover. Advanced mode adds search, sorting, and a summary of playing and transcoding sessions while keeping separate integration instances identifiable.
|
Select a session to inspect its media metadata in an anchored popover. Advanced mode adds search, sorting, location, bitrate, and a summary of playing and transcoding sessions while keeping separate integration instances identifiable. Compact visibility switches do not hide location or bitrate from the complete advanced session view.
|
||||||
If one selected server is unavailable, a warning indicator identifies the degraded result while sessions from healthy servers remain usable.
|
If one selected server is unavailable, a warning indicator identifies the degraded result while sessions from healthy servers remain usable.
|
||||||
Sessions without user metadata remain visible and are labeled as an unknown user.
|
Sessions without user metadata remain visible and are labeled as an unknown user.
|
||||||
|
|
||||||
### Screenshots
|
### Screenshots
|
||||||
|
|
||||||
import mediaTable from "./img/table.png";
|
import mediaTable from "./img/table.png";
|
||||||
import mediaAdvancedView from "./img/advanced-view.png";
|
|
||||||
|
|
||||||
<div className="flex flex-col gap-1">
|
<img src={mediaTable} alt="media-server-streams" width={128 * 3 * 1.5} height={128 * 1.5} />
|
||||||
<img src={mediaTable} alt="Media server compact streams table" width={303} height={198} />
|
|
||||||
<img src={mediaAdvancedView} alt="Media server advanced view with stream summary" width={800} height={484} />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
### Supported Integrations
|
### Supported Integrations
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import { tdarrIntegration } from "@site/docs/integrations/tdarr";
|
|||||||
|
|
||||||
The media transcoding widget provides you with an overview of your media transcoding status.
|
The media transcoding widget provides you with an overview of your media transcoding status.
|
||||||
It shows you the current queue, worker status, and statistics about your transcoding jobs.
|
It shows you the current queue, worker status, and statistics about your transcoding jobs.
|
||||||
|
Advanced view presents all three panels together. If refreshes fail after data has loaded, Homarr keeps the last useful result visible and marks it as stale.
|
||||||
|
|
||||||
### Screenshots
|
### Screenshots
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,8 @@ import { networkControllerStatusWidget } from ".";
|
|||||||
|
|
||||||
Shows connected users and connected guest devices on wired or wireless networks.
|
Shows connected users and connected guest devices on wired or wireless networks.
|
||||||
|
|
||||||
|
Compact view aggregates the configured controllers into the selected Wi-Fi or wired total. Advanced view shows both totals separately for every controller, preserving each integration's name, type, and exact update time while keeping partial-source and stale-data warnings visible.
|
||||||
|
|
||||||
### Screenshots
|
### Screenshots
|
||||||
|
|
||||||
import wifiCard from "./img/wifi.png";
|
import wifiCard from "./img/wifi.png";
|
||||||
|
|||||||
@@ -36,7 +36,9 @@ import summaryCard from "./img/summary.png";
|
|||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<WidgetInteractionGuide advancedView={false} />
|
In advanced view, each controller gets its own information matrix showing source, last update, WAN and web status, latency, ping, web uptime, separate Wi-Fi and LAN user and guest counts, and connected VPN users. The compact board view keeps its progressive aggregate layout.
|
||||||
|
|
||||||
|
<WidgetInteractionGuide />
|
||||||
|
|
||||||
### Adding the widget
|
### Adding the widget
|
||||||
|
|
||||||
|
|||||||
@@ -34,7 +34,9 @@ import notificationsScreenshot from "./img/notifications.png";
|
|||||||
items={[{ integration: ntfyIntegration }, { integration: nextcloudIntegration }, { integration: gotifyIntegration }]}
|
items={[{ integration: ntfyIntegration }, { integration: nextcloudIntegration }, { integration: gotifyIntegration }]}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<WidgetInteractionGuide advancedView={false} />
|
Advanced view always shows available notification logos and sources and removes the compact body line limit. External notification links retain the same safe new-tab behavior.
|
||||||
|
|
||||||
|
<WidgetInteractionGuide advancedView />
|
||||||
|
|
||||||
### Adding the widget
|
### Adding the widget
|
||||||
|
|
||||||
|
|||||||
@@ -72,6 +72,10 @@ The widget adapts its layout based on the available space:
|
|||||||
|
|
||||||
When the widget has enough space, a "last updated" timestamp appears at the bottom showing how recently PatchMon refreshed its data. Narrow layouts use a shortened timestamp such as `5m ago`; wider short layouts can show the full translated text.
|
When the widget has enough space, a "last updated" timestamp appears at the bottom showing how recently PatchMon refreshed its data. Narrow layouts use a shortened timestamp such as `5m ago`; wider short layouts can show the full translated text.
|
||||||
|
|
||||||
|
### Advanced view
|
||||||
|
|
||||||
|
Advanced view is a complete PatchMon posture view. It always shows the compliance hero, all eight host and package statistics, the full OS distribution with versions, and the last-updated time. Compact visibility switches and OS limits still shape the board tile, but do not hide already-fetched security information in advanced view. Threshold and chart-style choices remain in effect.
|
||||||
|
|
||||||
### Supported Integrations
|
### Supported Integrations
|
||||||
|
|
||||||
<WidgetIntegrations
|
<WidgetIntegrations
|
||||||
@@ -83,7 +87,7 @@ When the widget has enough space, a "last updated" timestamp appears at the bott
|
|||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<WidgetInteractionGuide advancedView={false} />
|
<WidgetInteractionGuide />
|
||||||
|
|
||||||
### Adding the widget
|
### Adding the widget
|
||||||
|
|
||||||
|
|||||||
@@ -35,7 +35,9 @@ GitHub, Docker Hub, GitLab, NPM, Codeberg, GitHub Container Registry, Quay, and
|
|||||||
For GitHub Container Registry, use `owner/package` identifiers such as `homarr-labs/homarr`.
|
For GitHub Container Registry, use `owner/package` identifiers such as `homarr-labs/homarr`.
|
||||||
Full image references such as `ghcr.io/homarr-labs/homarr:latest` are also accepted.
|
Full image references such as `ghcr.io/homarr-labs/homarr:latest` are also accepted.
|
||||||
|
|
||||||
<WidgetInteractionGuide advancedView={false} />
|
Advanced view shows every configured repository even when compact view is limited to highlighted or top releases. Repository names and details remain visible, and selecting a repository still expands its description and links.
|
||||||
|
|
||||||
|
<WidgetInteractionGuide />
|
||||||
|
|
||||||
### Adding the widget
|
### Adding the widget
|
||||||
|
|
||||||
|
|||||||
@@ -21,7 +21,9 @@ import screenshot from "./img/screenshot.png";
|
|||||||
|
|
||||||
<img src={screenshot} alt="rss-feed noted-lol" width={128 * 4} />
|
<img src={screenshot} alt="rss-feed noted-lol" width={128 * 4} />
|
||||||
|
|
||||||
<WidgetInteractionGuide advancedView={false} />
|
Advanced view keeps the configured feeds and post limit unchanged while showing each fetched post's full description, image, source, relative time, and exact publication timestamp. Right-to-left text and safe external links continue to follow the widget configuration.
|
||||||
|
|
||||||
|
<WidgetInteractionGuide advancedView />
|
||||||
|
|
||||||
### Adding the widget
|
### Adding the widget
|
||||||
|
|
||||||
|
|||||||
@@ -22,6 +22,8 @@ The entity state enables you to display the current state of an entity.
|
|||||||
This works with most entities and enables you display almost any data.
|
This works with most entities and enables you display almost any data.
|
||||||
It is recommended that you transform data on the integration as much as possible since Homarr's capabilities in transformation are very limited.
|
It is recommended that you transform data on the integration as much as possible since Homarr's capabilities in transformation are very limited.
|
||||||
|
|
||||||
|
Advanced view shows the safe Home Assistant metadata owned by Homarr: the friendly name, entity ID, unit, device class, icon, last-changed time, and last-updated time. Arbitrary attributes remain intentionally excluded.
|
||||||
|
|
||||||
### Screenshots
|
### Screenshots
|
||||||
|
|
||||||
import sun from "./img/sun.png";
|
import sun from "./img/sun.png";
|
||||||
|
|||||||
@@ -20,6 +20,8 @@ import { homeAssistantIntegration } from "@site/docs/integrations/home-assistant
|
|||||||
|
|
||||||
The execute automation widget allows you to trigger an automation with one click.
|
The execute automation widget allows you to trigger an automation with one click.
|
||||||
|
|
||||||
|
Advanced view shows the automation ID, interaction permission, last successful run in the current browser session, and the latest action error together. Session-only history is not presented as Home Assistant history.
|
||||||
|
|
||||||
### Screenshots
|
### Screenshots
|
||||||
|
|
||||||
import empty from "./img/empty.png";
|
import empty from "./img/empty.png";
|
||||||
|
|||||||
@@ -18,6 +18,10 @@ import { speedtestTrackerIntegration } from "@site/docs/integrations/speedtest-t
|
|||||||
This widget displays internet speed test results from your [Speedtest Tracker](https://docs.speedtest-tracker.dev/) instance,
|
This widget displays internet speed test results from your [Speedtest Tracker](https://docs.speedtest-tracker.dev/) instance,
|
||||||
including the latest result, historical averages, and a live chart of the last 12 hours.
|
including the latest result, historical averages, and a live chart of the last 12 hours.
|
||||||
|
|
||||||
|
Advanced view renders a source-labeled panel for every healthy integration. Each panel exposes that source's latest test, statistics, speed and ping charts, plus 12-hour, 24-hour, and truthful **Last 30** result ranges regardless of compact visibility switches. Compact mode keeps the responsive aggregate overview and names its healthy sources when multiple integrations are selected.
|
||||||
|
|
||||||
|
When multiple Speedtest Tracker integrations are selected, results from healthy sources remain visible if another source fails. A warning indicator identifies each unavailable integration without exposing private request details. If every selected integration fails, the widget reports an error; if cached data remains visible after a later total failure, a stale-data warning is shown.
|
||||||
|
|
||||||
### Screenshots
|
### Screenshots
|
||||||
|
|
||||||
import screenshot from "./img/screenshot.png";
|
import screenshot from "./img/screenshot.png";
|
||||||
|
|||||||
@@ -16,6 +16,8 @@ import { stockPriceWidget } from ".";
|
|||||||
Using the Stocks widget, you can show the current stock prices of your favorite companies on your dashboard.
|
Using the Stocks widget, you can show the current stock prices of your favorite companies on your dashboard.
|
||||||
The widget prioritizes the symbol, current price, and trend. Company name, change, time range, and a taller chart appear progressively when both widget dimensions can support them.
|
The widget prioritizes the symbol, current price, and trend. Company name, change, time range, and a taller chart appear progressively when both widget dimensions can support them.
|
||||||
|
|
||||||
|
In advanced view, the widget always shows the returned symbol and company name, configured range and interval, current and previous close, absolute and percentage change, range minimum and maximum, and the full price-history chart. These values use the same configured Yahoo Finance query as the compact widget; advanced view does not change the symbol, range, or interval.
|
||||||
|
|
||||||
### Screenshots
|
### Screenshots
|
||||||
|
|
||||||
import apple from "./img/apple.png";
|
import apple from "./img/apple.png";
|
||||||
@@ -34,7 +36,7 @@ import nvidia from "./img/nvidia.png";
|
|||||||
<img src={nvidia} alt="stock-price nvidia" width={128 * 2 + 2} height={128 * 2 + 4} />
|
<img src={nvidia} alt="stock-price nvidia" width={128 * 2 + 2} height={128 * 2 + 4} />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<WidgetInteractionGuide advancedView={false} />
|
<WidgetInteractionGuide />
|
||||||
|
|
||||||
### Adding the widget
|
### Adding the widget
|
||||||
|
|
||||||
|
|||||||
@@ -44,7 +44,9 @@ This widget displays filesystem and SMART disk usage for supported server and NA
|
|||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<WidgetInteractionGuide advancedView={false} />
|
Advanced view keeps your configured volume filters while showing each integration name, usage percentage, used and total space, free-space percentage, SMART status, available temperature, and the usage background bar regardless of compact display options.
|
||||||
|
|
||||||
|
<WidgetInteractionGuide />
|
||||||
|
|
||||||
### Adding the widget
|
### Adding the widget
|
||||||
|
|
||||||
|
|||||||
@@ -17,6 +17,8 @@ import { tracearrIntegration } from "@site/docs/integrations/tracearr";
|
|||||||
|
|
||||||
The Tracearr widget provides a real-time monitoring dashboard for your media server activity. It displays active streams, user statistics, recent watching history, and policy violations.
|
The Tracearr widget provides a real-time monitoring dashboard for your media server activity. It displays active streams, user statistics, recent watching history, and policy violations.
|
||||||
|
|
||||||
|
When multiple Tracearr integrations are selected, every stream, violation, and activity row keeps its source identity and an integration-scoped key. Data from healthy sources remains visible if another source fails, and a warning identifies each unavailable integration without exposing private request details. If every selected integration fails, the widget reports an error; if cached data remains visible after a later total failure, a stale-data warning is shown.
|
||||||
|
|
||||||
### Sections
|
### Sections
|
||||||
|
|
||||||
| Section | Description |
|
| Section | Description |
|
||||||
|
|||||||