diff --git a/apps/docs/docs/advanced/keyboard-shortcuts/index.mdx b/apps/docs/docs/advanced/keyboard-shortcuts/index.mdx
index 2883d436e..8e7f08a26 100644
--- a/apps/docs/docs/advanced/keyboard-shortcuts/index.mdx
+++ b/apps/docs/docs/advanced/keyboard-shortcuts/index.mdx
@@ -29,6 +29,7 @@ When a tile is focused in edit mode:
| `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.
diff --git a/apps/docs/docs/getting-started/after-the-installation.mdx b/apps/docs/docs/getting-started/after-the-installation.mdx
index a0ebecea8..d96e379ca 100644
--- a/apps/docs/docs/getting-started/after-the-installation.mdx
+++ b/apps/docs/docs/getting-started/after-the-installation.mdx
@@ -14,6 +14,10 @@ import manageBoardHeaderEditMode from "./img/manage-board-header-edit-mode.png";
import manageBoardHeaderAddItem from "./img/manage-board-header-add-item-menu.png";
import manageBoardHeaderChooseItem from "./img/manage-board-header-choose-item.png";
import manageBoardNoApp from "./img/manage-board-no-app.png";
+import currentBoardEditMode from "../management/boards/img/board-edit-mode.png";
+import currentAddBoardContentMenu from "../management/boards/img/add-board-content-menu.png";
+import currentKeyboardTileEditing from "../management/boards/img/keyboard-tile-editing.png";
+import currentBoardMobileView from "./img/board-mobile-view.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";
@@ -131,6 +135,7 @@ It is important that you first migrate correctly using [the list of breaking cha
5. Go to your new >1.0.0 Homarr 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:
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.
+ 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 so you can review the result before saving.
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.
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.
@@ -192,6 +197,10 @@ When entering the edit mode, you'll get some additional buttons to work with:
+The current editor keeps the board visible while it prepares its controls:
+
+
+
- **Add board content**: Click this button to create a new item, app, integration, or Container.
- **Exit edit mode**: Click this button to save your changes and exit edit mode. If you leave with unsaved changes, Homarr asks whether to discard them.
@@ -205,6 +214,14 @@ canvas; it is not inserted at a clicked empty cell or directly into a rail or Co
+The same menu also exposes direct actions for an app, integration, and Container:
+
+
+
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.
@@ -224,16 +241,13 @@ In the modal you can edit the app that you want to display:

As soon as you save your changes, the tile on the board will refresh and display your app.
-Use the resize handle at the bottom right to resize the tile.
-Press and hold the handle, move the pointer, and release it when the tile has the size you want.
+Resize from any visible edge or corner handle. For a Container, activate its top-left grip before using its resize handles.
+Press and hold a 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 content, move it to the desired position, and release it.
+To move a tile in edit mode, press and hold its inert content area, 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.
-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.
-
-
+The tile snaps to the grid. A single compatible collision may swap the two items when both resulting placements fit;
+otherwise the collision chain reflows neighboring tiles automatically.
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.
@@ -242,6 +256,15 @@ The complete canvas always fits the available width without horizontal board scr
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.
+On a narrow screen, Homarr uses the Mobile layout and stacks the board content vertically while preserving each widget's
+fixed logical proportions:
+
+
+
:::note
Viewing a board initially uses the lightweight, non-interactive layout.
@@ -262,7 +285,12 @@ within its current canvas, rail, or Container. Press Escape to stop keyboard edi
hold of about `200 ms`; resize handles accept direct touch input. During a pointer or touch move or resize, press Escape
to cancel and restore the previous layout. For cross-grid moves or precise numeric controls, choose **Move / resize item**
from the tile's edit menu.
-The dialog can also move the tile to another section or fixed sidebar:
+Keyboard commands at a grid boundary or minimum tile size are ignored and announced; they do not move or shrink the tile.
+
+
+
+Open **Move / resize item** from the tile menu to move the tile to another section or rail and enter precise numeric
+coordinates and dimensions. The image below shows the menu entry point:

@@ -345,7 +373,7 @@ Each Container can configure:
- Show or hide **Open all in new tabs**.
- 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.
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.
diff --git a/apps/docs/docs/getting-started/img/board-mobile-view.png b/apps/docs/docs/getting-started/img/board-mobile-view.png
new file mode 100644
index 000000000..87686b455
Binary files /dev/null and b/apps/docs/docs/getting-started/img/board-mobile-view.png differ
diff --git a/apps/docs/docs/management/api/index.mdx b/apps/docs/docs/management/api/index.mdx
index 35e9f49e4..82fde7057 100644
--- a/apps/docs/docs/management/api/index.mdx
+++ b/apps/docs/docs/management/api/index.mdx
@@ -93,6 +93,10 @@ 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
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
The dashboard editor saves item positions and sections as one board update.
diff --git a/apps/docs/docs/management/assistant.mdx b/apps/docs/docs/management/assistant.mdx
index ca8202437..43c56278c 100644
--- a/apps/docs/docs/management/assistant.mdx
+++ b/apps/docs/docs/management/assistant.mdx
@@ -20,6 +20,10 @@ focus whenever the command menu opens, including when it is opened by an assista
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 see **Sign in**; configured-but-disabled users cannot use the
+user-menu or `Shift + A` entry points; and `Cmd/Ctrl + K` keeps the assistant result visible but unavailable and
+non-interactive until an administrator enables it.
+
While a response is running, a compact activity bar appears at the bottom of the page and the user-menu
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
@@ -35,6 +39,8 @@ 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.
The Shift+A panel is non-modal: opening it focuses its composer, but it does not capture focus from the board.
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
@@ -78,14 +84,18 @@ working provider, model, and enabled state are saved.
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.
-The model discovery path defaults to `/models` and is appended to the API base URL. Leave it blank when
-the service does not expose model discovery. A manual model ID can still be used when discovery is
-disabled, unavailable, or returns no models.
+Changing the provider, base URL, or discovery path clears the selected model and disables the assistant. Save the
+connection again, refresh or enter a model ID, then enable the assistant and save the configuration once more.
+
+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 clears existing credentials. This prevents credentials for one service from being sent
-to another endpoint.
+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
@@ -166,7 +176,7 @@ 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
-stored on the conversation after a completed request. Thinking mode can be left on **Auto**, disabled, or set
+saved to the current conversation when selected. 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
@@ -206,8 +216,9 @@ calculated value as estimated. Missing provider data is shown as not reported ra
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 an explicit approval in the
-conversation before they execute. The approval appears as a large **Approve and run** or **Deny** action;
+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
@@ -218,7 +229,8 @@ activity such as **Looking for “homarr” icons** instead of exposing the inte
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 pauses for its normal approval. A safely recoverable truncated icon-search object is repaired
+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
@@ -273,7 +285,7 @@ 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. Users can select one of the proposed answers or choose **Other** and
+of automatic approval is unambiguous. When enabled by the tool, users can select **Other** and
enter their own response. 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
diff --git a/apps/docs/docs/management/boards/img/add-board-content-menu.png b/apps/docs/docs/management/boards/img/add-board-content-menu.png
new file mode 100644
index 000000000..4c0ad9860
Binary files /dev/null and b/apps/docs/docs/management/boards/img/add-board-content-menu.png differ
diff --git a/apps/docs/docs/management/boards/img/board-edit-mode.png b/apps/docs/docs/management/boards/img/board-edit-mode.png
new file mode 100644
index 000000000..568e42253
Binary files /dev/null and b/apps/docs/docs/management/boards/img/board-edit-mode.png differ
diff --git a/apps/docs/docs/management/boards/img/keyboard-tile-editing.png b/apps/docs/docs/management/boards/img/keyboard-tile-editing.png
new file mode 100644
index 000000000..d650821fc
Binary files /dev/null and b/apps/docs/docs/management/boards/img/keyboard-tile-editing.png differ
diff --git a/apps/docs/docs/management/boards/img/layout-settings-custom-rails.png b/apps/docs/docs/management/boards/img/layout-settings-custom-rails.png
new file mode 100644
index 000000000..7284c5831
Binary files /dev/null and b/apps/docs/docs/management/boards/img/layout-settings-custom-rails.png differ
diff --git a/apps/docs/docs/management/boards/img/layout-settings-mobile.png b/apps/docs/docs/management/boards/img/layout-settings-mobile.png
new file mode 100644
index 000000000..c3e44e30f
Binary files /dev/null and b/apps/docs/docs/management/boards/img/layout-settings-mobile.png differ
diff --git a/apps/docs/docs/management/boards/index.mdx b/apps/docs/docs/management/boards/index.mdx
index 2b93cb0a8..82c11ab08 100644
--- a/apps/docs/docs/management/boards/index.mdx
+++ b/apps/docs/docs/management/boards/index.mdx
@@ -11,10 +11,12 @@ tags:
import iconColorImage from "./img/icon-color.png";
import itemRadiusImage from "./img/item-radius.png";
-import layoutLargeImage from "./img/layout-large.png";
-import layoutMediumImage from "./img/layout-medium.png";
-import layoutSmallImage from "./img/layout-small.png";
import layoutSettingsImage from "./img/layout-settings.png";
+import layoutSettingsCustomRailsImage from "./img/layout-settings-custom-rails.png";
+import layoutSettingsMobileImage from "./img/layout-settings-mobile.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".
You can create as many boards as you want.
@@ -99,6 +101,15 @@ In this section you can configure the different responsive layouts. Homarr selec
style={{ maxWidth: "100%" }}
/>
+The layout cards show the representative geometry used for planning. This current example also shows a custom layout
+with both fixed rails enabled; the rails reserve columns and the remaining canvas reflows automatically.
+
+
+
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.
@@ -120,9 +131,10 @@ Each layout stores independent positions and sizes. Moving or resizing a widget
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. Homarr restores missing Mobile/Base layouts, promotes the narrowest
-and widest existing layouts to those protected roles, keeps intermediate layouts custom, and normalizes duplicate or
-out-of-order breakpoints without discarding saved positions.
+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.
@@ -148,6 +160,7 @@ The preview shows how much space remains for the main canvas.
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.
+The combined rail widths cannot consume the final main-canvas column.
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.
@@ -156,27 +169,43 @@ Apps, widgets, and Containers inside them still use the same fixed `200 × 200`
#### Breakpoint
-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.
+The minimum screen width where the layout is used; a layout is eligible at its breakpoint and above. Mobile is fixed at
+`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 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.
-Entering edit mode keeps the static board visible until that preparation finishes, then enables collision-aware movement and resizing without changing the board geometry.
-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.
-For other collisions, or when a tile grows into occupied space, nearby tiles are compacted out of the way. A compatible
-single-item collision can swap when both placements fit; other collision chains reflow around the move.
+Entering edit mode keeps the static board visible until that preparation finishes, then enables collision-aware movement and resizing.
+Collapsed Containers are expanded while editing so their contents and controls are reachable.
+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.
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
changes, Homarr asks whether to discard them. If the editor cannot load, the board remains in view mode.
+
+
While edit mode is active, **Add board content** creates a new item, app, integration, or Container on the main canvas.
New content uses the first available position; clicking an empty cell does not place it there, and items cannot be added
directly into a rail or Container from this menu.
-Pointer users can drag anywhere on a widget tile. Containers use the grab button at their top-left corner.
+
+
+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
@@ -187,17 +216,26 @@ Keyboard moves and resizes apply immediately within the current canvas, rail, or
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.
+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.
+
+
#### Preview
-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.
+Layout Settings shows a lightweight structural preview for every layout, including saved spans, Containers, widget labels, and app icons.
+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.
-
-
-
+On a narrow screen, the same settings page stacks each layout card vertically so the preview and controls remain usable:
+
+
### Containers and rails
@@ -354,7 +392,8 @@ 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.
:::
-Duplicating a board will create a new board with the same settings and layout as the original board.
+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 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".

@@ -412,7 +451,11 @@ For the global home board you can only select boards that are public.
### Mobile home board
-Same as the home board, you can also set a mobile home board. It is used for devices detected as mobile devices from the
-User-Agent header. For the server-wide fallback, configure **Global mobile board** under `Management` > `Settings` >
-`Boards`; the selected board must be public. See the [global board defaults](/docs/management/settings#boards) for the
-desktop and mobile fallback rules.
+The mobile home board controls which board opens for devices that Homarr detects as mobile from the User-Agent header.
+This is separate from a board's **Mobile layout**, which controls the layout selected inside that board.
+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`.
+
+Homarr checks a user's mobile home board first, then that user's desktop home board, matching group defaults, and finally
+the server-wide mobile or desktop board. Global defaults must be public. See the
+[global board defaults](/docs/management/settings#boards) for the complete precedence and the required public-board rule.
diff --git a/apps/docs/docs/management/custom-widgets/agent-authoring.mdx b/apps/docs/docs/management/custom-widgets/agent-authoring.mdx
index ec51d17a1..25e6fc774 100644
--- a/apps/docs/docs/management/custom-widgets/agent-authoring.mdx
+++ b/apps/docs/docs/management/custom-widgets/agent-authoring.mdx
@@ -79,7 +79,9 @@ These interfaces do not return an archive URL or archive hash.
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
exact tested preview candidate locally.
-11. Create the widget from that final tested preview, including any source URLs and credentials the user already supplied.
+11. Create the widget from that final tested preview with `customWidget_createFromPreview`, including any source URLs and
+ credentials the user already supplied. The create call persists that tested preview and accepts its session ID plus an
+ optional target 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.
14. Create a final preview with the saved definition ID so Homarr loads its stored credentials, then test it again.
diff --git a/apps/docs/docs/management/custom-widgets/authoring.mdx b/apps/docs/docs/management/custom-widgets/authoring.mdx
index d13a893c5..5cbfc872e 100644
--- a/apps/docs/docs/management/custom-widgets/authoring.mdx
+++ b/apps/docs/docs/management/custom-widgets/authoring.mdx
@@ -3,7 +3,9 @@
import { CanonicalCustomWidgetExample } from "@site/src/components/custom-widget-code";
import workbenchImage from "./img/workbench.png";
-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.
+The workbench exposes General, API sources, Requests, Options, JSX, and Preview sections. Advanced JSON is available in the
+manifest and request/option editors. Code and preview sit side by side on desktop; mobile switches between Configure and
+Preview.
For multiline JSX, prefer `templateLines` in agent or MCP input and keep the final tested preview as the source of truth before saving.
-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.
+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`.
+
+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
diff --git a/apps/docs/docs/management/custom-widgets/custom-jsx.mdx b/apps/docs/docs/management/custom-widgets/custom-jsx.mdx
index bbf15a0c8..b6fdb1284 100644
--- a/apps/docs/docs/management/custom-widgets/custom-jsx.mdx
+++ b/apps/docs/docs/management/custom-widgets/custom-jsx.mdx
@@ -7,10 +7,14 @@ Templates are JSX expressions interpreted inside a widget-local safety and rende
- `options.name` — saved widget configuration
- `inputs.name` — temporary values from declarative `bind`
-The v2 manifest supports up to eight sources and 64 requests. Source IDs are case-insensitively unique, and
-the template and secret values have bounded sizes. Validation reports the exact field when a limit is exceeded.
+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.
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
@@ -35,7 +39,9 @@ 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.
-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.
+Bounded regex literals are supported for string matching, splitting, search, and replacement. Regex literals are limited to
+128 characters and flags `gimsu`; lookarounds, backreferences, repeated alternatives/groups, unsupported flags, and more
+than one variable quantifier are rejected.
## Runtime components
@@ -45,8 +51,9 @@ Bounded regex literals are supported for string matching, splitting, search, 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 refreshes load queries for authenticated viewers. It
- is disabled for anonymous public-board viewers because refreshing invalidates shared server cache state.
+- `RefreshButton` renders a compact, accessible icon control that invalidates the client's load-query cache; 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.
Always include responsive loading, empty, error, and success states. Runtime failures remain inside the widget tile.
diff --git a/apps/docs/docs/management/custom-widgets/index.mdx b/apps/docs/docs/management/custom-widgets/index.mdx
index cc9917b1d..e3ea98cde 100644
--- a/apps/docs/docs/management/custom-widgets/index.mdx
+++ b/apps/docs/docs/management/custom-widgets/index.mdx
@@ -42,7 +42,10 @@ interface HomarrCustomWidgetV2 {
### Design with AI
-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.
+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 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.
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.
@@ -62,8 +65,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.
Adding or configuring a Custom Widget placement requires both administrator access and permission to modify that
-board. A non-administrator with board-modify access can move, resize, change presentation settings, or remove an
-existing placement, but cannot add one, change its definition, refresh interval, or Custom Widget options.
+board. Duplicating a board that contains Custom Widgets also requires an administrator. A non-administrator with
+board-modify access can move, resize, change presentation settings, or remove an existing placement, but cannot add one,
+change its definition, refresh interval, or Custom Widget options.
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.
@@ -128,6 +132,7 @@ replace the v1 backup.
## Bundled examples
-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:
+Homarr seeds five disabled examples without credentials and never overwrites an edited seed. They use the same public
+contract. Tautulli Activity is one of the bundled examples preserved from Homarr's AI authoring evaluation:
-#### Right-click context menu
+#### Download-row context menu
- Advanced view reuses the widget's live data and cache. Preview dims the rest of the board; the manual - view traps focus and locks background scrolling. On touch devices, use the widget menu where your browser - exposes it; compact-only widgets adapt in place instead. + Advanced view reuses existing data where possible; some widgets request additional or denser data. Hold Shift + while hovering for a temporary preview, which closes when Shift is released, the pointer leaves, or the window + loses focus. The manual view closes with Escape, its close button, or the backdrop; it traps focus and locks + background scrolling. Shift + wheel is routed to a scrollable advanced panel when possible. On touch devices, + use the widget menu where your browser exposes it; compact-only widgets adapt in place instead.
)}