diff --git a/.github/ISSUE_TEMPLATE/docs-feedback.yml b/.github/ISSUE_TEMPLATE/docs-feedback.yml new file mode 100644 index 00000000..34f47299 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/docs-feedback.yml @@ -0,0 +1,49 @@ +name: Docs feedback +description: Report missing, unclear, outdated, or incorrect documentation. +title: "[Docs feedback]: " +labels: [documentation] +body: + - type: markdown + attributes: + value: | + Help us improve the docs by describing where you got stuck. + This report will be public. Please do not include passwords, API keys, or private logs. + For general help with Open WebUI, use [community discussions](https://github.com/open-webui/open-webui/discussions). + - type: input + id: page-title + attributes: + label: Page title + placeholder: Which documentation page needs improvement? + validations: + required: true + - type: input + id: page-url + attributes: + label: Page URL + placeholder: https://docs.openwebui.com/... + validations: + required: true + - type: dropdown + id: problem-type + attributes: + label: What needs improvement? + options: + - Missing information + - Unclear explanation + - Outdated or incorrect instructions + - Broken example or link + - Other documentation problem + validations: + required: true + - type: textarea + id: feedback + attributes: + label: What went wrong? + description: What were you trying to do, and where did you get stuck? If you know a correction, include it here. + validations: + required: true + - type: input + id: version + attributes: + label: Open WebUI version (optional) + description: Include your version if the instructions do not match what you see. diff --git a/docs/contributing.mdx b/docs/contributing.mdx index a2cded83..5be6b061 100644 --- a/docs/contributing.mdx +++ b/docs/contributing.mdx @@ -76,6 +76,8 @@ To add a new language: 3. Translate the string values in each JSON file while preserving the object structure 4. Register the language in `src/lib/i18n/locales/languages.json` +In `en-US`, many values are empty because the key is already the English text. For those entries, translate the key and write the result as the value. + ### Improve accessibility Accessibility is a core part of good design. Report accessibility problems with reproduction details through Issues. When implementing a maintainer-requested UI change: diff --git a/docs/features/administration/analytics/index.mdx b/docs/features/administration/analytics/index.mdx index f8824371..7bb3d18c 100644 --- a/docs/features/administration/analytics/index.mdx +++ b/docs/features/administration/analytics/index.mdx @@ -439,7 +439,12 @@ Accepts either `days` (7-732) or an explicit `start_date` / `end_date` range, an | `metric` | string | `messages` (default) counts assistant responses, `tokens` sums input and output tokens | | `compare` | bool | `true` adds a `previous` object to each bucket with the value for the window of the same length directly before the range, plus the `start` and `end` of both. It needs both `start_date` and `end_date`, with `start_date` not after `end_date`, or the request fails with `400` | -**`/api/v1/analytics/users` parameters:** `metric` set to `tokens` ranks users by total tokens before `limit` is applied. The default `messages` ranks them by message count. +**`/api/v1/analytics/users` parameters:** + +| Parameter | Type | Description | +|-----------|------|-------------| +| `metric` | string | `messages` (default) ranks users by assistant responses, `tokens` ranks them by total input and output tokens | +| `limit` | int | How many of the top-ranked users to return, 50 users by default. Users are ranked before the cut, and there is no `skip` or other offset, so to get every user in the range, set `limit` to at least your user count | :::tip API Access All Analytics endpoints require admin authentication. Include your admin bearer token: diff --git a/docs/features/authentication-access/mfa.md b/docs/features/authentication-access/mfa.md index 06cc1411..a94d0cd4 100644 --- a/docs/features/authentication-access/mfa.md +++ b/docs/features/authentication-access/mfa.md @@ -19,7 +19,7 @@ The setting covers every user on the instance. Users who have not set up an auth - **Persistent configuration turned on.** [`ENABLE_PERSISTENT_CONFIG`](/reference/env-configuration#enable_persistent_config) must stay at its default `True`. - **A stable encryption key.** The secret behind each user's authenticator is stored encrypted in the database. The key is derived from [`WEBUI_SECRET_KEY`](/reference/env-configuration#webui_secret_key), or taken from [`MFA_ENCRYPTION_KEY`](/reference/env-configuration#mfa_encryption_key) when that is set. If the key changes after users have enrolled, their authenticators can no longer be read. -While MFA is on, Open WebUI checks all of this at startup and refuses to start when authentication or persistent configuration is off, when `MFA_ENCRYPTION_KEY` is not a valid key, or when a stored authenticator secret cannot be decrypted with the current key. Restore the previous key to get the instance running again. +While MFA is on, Open WebUI checks all of this at startup and refuses to start when authentication or persistent configuration is off, when `MFA_ENCRYPTION_KEY` is not a valid key, or when a stored authenticator secret cannot be decrypted with the current key. In that last case, the log shows `ValueError: Stored MFA secrets cannot be decrypted. Restore the WEBUI_SECRET_KEY or MFA_ENCRYPTION_KEY they were encrypted with.` Restore the previous key to get the instance running again. --- diff --git a/docs/features/authentication-access/rbac/permissions.md b/docs/features/authentication-access/rbac/permissions.md index 1d0ec64e..56fcb426 100644 --- a/docs/features/authentication-access/rbac/permissions.md +++ b/docs/features/authentication-access/rbac/permissions.md @@ -91,7 +91,7 @@ A sharing change that asks for an audience the user may not add is refused with | **Allow Sharing With Users** | Ability to share with **specific users** ([`USER_PERMISSIONS_ACCESS_GRANTS_ALLOW_USERS`](/reference/env-configuration#user_permissions_access_grants_allow_users)). | | **Allow Sharing With Groups** | Ability to share with **groups** ([`USER_PERMISSIONS_ACCESS_GRANTS_ALLOW_GROUPS`](/reference/env-configuration#user_permissions_access_grants_allow_groups)). | -Every toggle in the panel's **Sharing Permissions** section is off unless you turn it on, and a public toggle is only drawn once the parent permission named in its row is on. The two **Allow Sharing With ...** rows sit in a separate **Access Grants** section and are on by default. +Every toggle in the panel's **Sharing Permissions** section is off unless you turn it on, and a public toggle is only drawn once the parent permission named in its row is on. The two **Allow Sharing With ...** rows sit in a separate **Access Grants** section and are on by default. With **Allow Sharing With Groups** off, the **Add Access** picker lists no groups. With **Allow Sharing With Users** off, it lists no users. :::warning Re-check Tools and Notes public sharing after an upgrade @@ -112,7 +112,7 @@ Controls the features available to the user inside the chat interface. | **Allow Chat Params** | *(Requires Allow Chat Controls)* Ability to adjust LLM parameters (e.g., temperature, top_k). When disabled, the **Advanced Params** sections in the chat and in **Settings > General** are hidden. This only hides them: users can still set parameters through the API. That trade-off lets admins hide the panels and still offer [model controls](/features/workspace/models#using-model-controls-in-chat). | | **Allow File Upload** | Ability to upload files to the chat. | | **Allow Web Upload** | Ability to attach a web page to a chat by URL, using **Attach Webpage** in the message input's attach menu ([`USER_PERMISSIONS_CHAT_WEB_UPLOAD`](/reference/env-configuration#user_permissions_chat_web_upload)). On by default. When disabled, the option is greyed out and the attach is refused. Admins are always exempt. | -| **Allow Chat Delete** | Ability to delete chats ([`USER_PERMISSIONS_CHAT_DELETE`](/reference/env-configuration#user_permissions_chat_delete)). On by default. When disabled, every chat delete control is hidden, including **Delete All Chats**, and deleting a folder that still holds chats is refused. Archiving still works. | +| **Allow Chat Delete** | Ability to delete chats ([`USER_PERMISSIONS_CHAT_DELETE`](/reference/env-configuration#user_permissions_chat_delete)). On by default. When disabled, every chat delete control is hidden, including **Delete All Chats**, and deleting a folder together with its chats is refused. Archiving still works. | | **Allow Delete Messages** | Ability to delete individual messages. | | **Allow Chat Edit** | Ability to edit messages ([`USER_PERMISSIONS_CHAT_EDIT`](/reference/env-configuration#user_permissions_chat_edit)), both your own and responses. | | **Allow Continue Response** | Ability to use the "Continue" feature for truncated responses. | diff --git a/docs/features/calendar/index.md b/docs/features/calendar/index.md index 10fc2dfd..7e30fe43 100644 --- a/docs/features/calendar/index.md +++ b/docs/features/calendar/index.md @@ -123,6 +123,8 @@ Click the small **+** button next to the **Calendars** heading in the calendar s Click any event on the calendar to open the event editor. From there you can update details or delete the event. Automation-generated virtual events cannot be edited directly; clicking them navigates to the automation or the run's chat. +Clicking one occurrence of a repeating event opens the whole series, dated from its first occurrence. **Save** changes every occurrence, and **Delete** removes the series. + --- ## Calendar Views diff --git a/docs/features/channels/index.md b/docs/features/channels/index.md index 895ea90e..db4d0f7a 100644 --- a/docs/features/channels/index.md +++ b/docs/features/channels/index.md @@ -117,6 +117,10 @@ Point at someone's profile picture next to their messages or in the channel's me Hover any message to react with emoji, pin it for reference, reply inline, or start a threaded side conversation. +You can delete your own messages, and an admin can delete anyone's. Deleting a message that started a thread also deletes every reply in that thread, including replies other people wrote. + +If you can only read a channel, messages show no hover actions and the reactions under them cannot be clicked. The message box reads **You do not have permission to send messages in this channel.** + ### Muting a channel The **...** menu of a channel or direct message, in the sidebar or in the channel header, has a **Notifications** setting. **Mentions only** mutes it for you: the channel is dimmed in the sidebar and shows no unread count. Only a message that @mentions you still sends a pop-up, browser notification or [notification webhook](/features/chat-conversations/chat-features/notifications); the unread count stays hidden for it too. **All messages** turns it back on. The setting is per member, so muting a channel changes nothing for anyone else. diff --git a/docs/features/chat-conversations/audio/speech-to-text/env-variables.md b/docs/features/chat-conversations/audio/speech-to-text/env-variables.md index ae8a761a..63d4fcf6 100644 --- a/docs/features/chat-conversations/audio/speech-to-text/env-variables.md +++ b/docs/features/chat-conversations/audio/speech-to-text/env-variables.md @@ -111,7 +111,7 @@ See the [Azure AI Speech STT guide](/features/chat-conversations/audio/speech-to | `AUDIO_TTS_MISTRAL_API_BASE_URL` | Mistral API base URL | `https://api.mistral.ai/v1` | :::info -When `AUDIO_TTS_ENGINE=mistral`, Open WebUI uses `mistral-tts-latest` when `AUDIO_TTS_MODEL` is empty. +When `AUDIO_TTS_ENGINE=mistral`, Open WebUI uses `voxtral-mini-tts-2603` when `AUDIO_TTS_MODEL` is empty. ::: ### Azure TTS diff --git a/docs/features/chat-conversations/audio/speech-to-text/stt-config.md b/docs/features/chat-conversations/audio/speech-to-text/stt-config.md index 06f0b21e..2f6b7430 100644 --- a/docs/features/chat-conversations/audio/speech-to-text/stt-config.md +++ b/docs/features/chat-conversations/audio/speech-to-text/stt-config.md @@ -38,9 +38,9 @@ To configure a speech to text provider: ### Restricting Accepted Audio Extensions -Open WebUI ships with an **Allowed Extensions** list under **Settings → Admin → Audio → STT** that controls which audio file extensions the upload endpoint will accept (default: `mp3,wav,m4a,webm,ogg,flac,mp4,mpga,mpeg`). Uploads with any other extension are rejected with `400 Invalid audio file extension` before transcription runs. +Open WebUI keeps an allowed extensions list that controls which audio file extensions the upload endpoint will accept (default: `mp3,wav,m4a,webm,ogg,flac,mp4,mpga,mpeg`). Uploads with any other extension are rejected with `400 Invalid audio file extension` before transcription runs. -This is enforced server-side in addition to the MIME-type check (`AUDIO_STT_SUPPORTED_CONTENT_TYPES`), so tightening it is a low-cost way to harden the STT endpoint against unexpected file types. Set the matching `AUDIO_STT_ALLOWED_EXTENSIONS` environment variable to seed the list at startup, or clear it in the UI to skip the extension check entirely. +This is enforced server-side in addition to the MIME-type check (`AUDIO_STT_SUPPORTED_CONTENT_TYPES`), so tightening it is a low-cost way to harden the STT endpoint against unexpected file types. The admin **Audio** settings do not show this list. Set it with the `AUDIO_STT_ALLOWED_EXTENSIONS` environment variable, or set that variable to an empty value to skip the extension check entirely. ## User-Level Settings diff --git a/docs/features/chat-conversations/audio/text-to-speech/mistral-tts-integration.md b/docs/features/chat-conversations/audio/text-to-speech/mistral-tts-integration.md index fbb73dc5..1c0f37e3 100644 --- a/docs/features/chat-conversations/audio/text-to-speech/mistral-tts-integration.md +++ b/docs/features/chat-conversations/audio/text-to-speech/mistral-tts-integration.md @@ -40,11 +40,7 @@ See the companion guide: [Using Mistral Voxtral for Speech-to-Text](/features/ch | `voxtral-tts-26-03` | Voxtral TTS — current Mistral text-to-speech model, with zero-shot voice cloning | :::info -If `AUDIO_TTS_MODEL` is empty, Open WebUI falls back to `mistral-tts-latest`. -::: - -:::caution Set the model explicitly -Mistral no longer publishes `-latest` alias names, so the built-in `mistral-tts-latest` fallback may be rejected. Set **TTS Model** to a current ID such as `voxtral-tts-26-03` rather than leaving the field empty. See the [Mistral models overview](https://docs.mistral.ai/getting-started/models/models_overview/) for the current list. +If `AUDIO_TTS_MODEL` is empty, Open WebUI falls back to `voxtral-mini-tts-2603`. Choosing **MistralAI** as the engine fills in that model. ::: ## Environment Variables Setup @@ -71,7 +67,7 @@ services: | `AUDIO_TTS_ENGINE` | Set to `mistral` | empty (uses browser-only TTS) | | `AUDIO_TTS_MISTRAL_API_KEY` | Your Mistral API key | empty | | `AUDIO_TTS_MISTRAL_API_BASE_URL` | Mistral API base URL | `https://api.mistral.ai/v1` | -| `AUDIO_TTS_MODEL` | TTS model | `mistral-tts-latest` (built-in fallback; set `voxtral-tts-26-03` explicitly) | +| `AUDIO_TTS_MODEL` | TTS model | `voxtral-mini-tts-2603` (built-in fallback) | | `AUDIO_TTS_VOICE` | Voice ID | empty | ## Choosing Voices diff --git a/docs/features/chat-conversations/chat-features/automations.mdx b/docs/features/chat-conversations/chat-features/automations.mdx index 8865d775..d3229c03 100644 --- a/docs/features/chat-conversations/chat-features/automations.mdx +++ b/docs/features/chat-conversations/chat-features/automations.mdx @@ -93,6 +93,10 @@ On the editor page, you can: Execution logs are paginated with infinite scroll in the editor, so large run histories load incrementally. +### Quick delete + +Hold **Shift** while the Automations list is open and each automation's menu button and on/off switch turn into a delete button. Clicking it deletes that automation straight away, without asking. Release **Shift** and the menu and switch come back. Deleting from the menu still asks you to confirm. + ## Export and Import The Automations list header has a split **Create** button. Its dropdown holds **Import JSON** and **Export JSON**, which move automations between instances or accounts. diff --git a/docs/features/chat-conversations/chat-features/code-execution/python.md b/docs/features/chat-conversations/chat-features/code-execution/python.md index 30899e44..8be07bbc 100644 --- a/docs/features/chat-conversations/chat-features/code-execution/python.md +++ b/docs/features/chat-conversations/chat-features/code-execution/python.md @@ -275,7 +275,7 @@ This is a known compatibility issue between Edge's enhanced security mode and We - **Mention the environment**: Tell the LLM it's running in a "Pyodide environment" or "code interpreter" for better code generation - **Be explicit about output**: Ask for "base64 data URL output" for images -- **Use print statements**: Results must be printed to appear in the output +- **Use print statements**: Printed output appears under **STDOUT/STDERR**. When the last line of a block is an expression, such as `square(7)`, its value also shows under **RESULT** - **Check library support**: Verify the libraries you need are available in Pyodide ## Further Reading diff --git a/docs/features/chat-conversations/chat-features/history-search.mdx b/docs/features/chat-conversations/chat-features/history-search.mdx index 798cbb74..9fe2c4ad 100644 --- a/docs/features/chat-conversations/chat-features/history-search.mdx +++ b/docs/features/chat-conversations/chat-features/history-search.mdx @@ -79,13 +79,17 @@ Matching ignores case and works on substrings, so `log` also matches "login" and In the search window and the **Reference Chats** picker you can narrow results with filter prefixes, alone or combined with a query: -* `tag:`, chats with a given tag +* `tag:`, chats with a given tag, or `tag:none` for chats with no tags * `folder:`, chats in a folder * `pinned:true` or `pinned:false`: only pinned chats, or only chats that are not pinned * `archived:true` or `archived:false`: only archived chats, or only chats that are not archived * `shared:true` or `shared:false`: only chats with a share link, or only chats without one -The last three need `true` or `false` after the colon. Typed on their own, `pinned:`, `archived:` and `shared:` are dropped from the query and filter nothing. +The last three need `true` or `false` after the colon. Typed on their own, `pinned:`, `archived:` and `shared:` are dropped from the query and filter nothing. In the search window, `tag:` and `folder:` with nothing after them are dropped too. + +The search window suggests the prefixes as you type. When you type the first letters of a prefix, such as `t` for `tag:`, a list under the search box offers it with a short description. Picking `tag:` lists your tags, `folder:` lists your folders, and `pinned:`, `archived:` and `shared:` offer `true` and `false`. Click a suggestion, or use the arrow keys with `Enter` or `Tab`. `Escape` closes the list and leaves the window open. + +A filter in the search window searches only chats you own. Notes, channel messages and shared snapshots have no tags, folders or archive state, so they drop out of the results while a filter is in the query. For example, `folder:work meeting notes` searches for "meeting notes" within the **work** folder. diff --git a/docs/features/chat-conversations/chat-features/keyboard-shortcuts.mdx b/docs/features/chat-conversations/chat-features/keyboard-shortcuts.mdx index e87c5294..6ff09674 100644 --- a/docs/features/chat-conversations/chat-features/keyboard-shortcuts.mdx +++ b/docs/features/chat-conversations/chat-features/keyboard-shortcuts.mdx @@ -15,6 +15,8 @@ An **Enable Keyboard Shortcuts** toggle at the top of **Settings > Keyboard** sw Turn it off when Open WebUI's shortcuts collide with ones your browser or operating system already uses, `Cmd+Shift+C` for the browser inspector being a common example. While it is off, the configurable shortcuts below do not fire and the key combinations pass through to the browser or OS untouched, dictation included, and the small hotkey hints stop appearing in the interface. +To stop a single shortcut, unassign it. Its key combination then reaches the browser like any other. That is the usual fix for **Regenerate response**, bound by default to the keys browsers use to reload the page. + Nothing locks you out: the **Settings > Keyboard** tab keeps working while shortcuts are disabled, so you can rebind them or switch them back on at any time. The chat input triggers (`/`, `@`, `#`), `Tab` to accept an autocomplete suggestion, and `Esc` to stop a response or close a dialog are unaffected, since they are not global shortcuts. `Cmd` below means the `Ctrl` key on Windows and Linux. On macOS it means the `Command` key specifically: `Ctrl` is treated as its own modifier there and does not stand in for `Cmd`, so `Ctrl+K` will not open search on a Mac, only `Cmd+K` will. @@ -51,6 +53,8 @@ These twenty-one can be rebound: **Clear Input Selections** resets the chat input's choices: it removes the model override, deselects tools and filters and turns off web search, image generation and code interpreter. It only fires while the chat input has focus. +**Close modal** closes only the dialog on top, so a confirmation opened over **Settings** closes and leaves **Settings** open. `Escape` always closes dialogs, so keys you assign here work alongside `Escape`, not in place of it. + Anything not listed here is fixed and cannot be reassigned. ## Fixed Shortcuts @@ -98,6 +102,6 @@ The `/` menu includes a **Model** entry that opens the model picker with its sea Distinct from the shortcuts above, stepping through the interface with `Tab` and `Shift+Tab` works everywhere and is unaffected by the **Enable Keyboard Shortcuts** toggle. Whatever you have reached is marked with a clear outline, so you can always see where you are. Buttons that normally appear under the pointer, such as the actions under a message, appear when you reach them with `Tab` as well. -The first `Tab` on a page reaches a **Skip to main content** link. Tooltips also show on keyboard focus, and `Escape` closes them. Arrow keys move through the **+** and **Integrations** menus. +The first `Tab` on a page reaches a **Skip to main content** link. Tooltips also show on keyboard focus, and `Escape` closes them. Opening a menu from the keyboard moves focus to its first item, and arrow keys move through it. Screen readers get names for icon buttons and hear reply status, notifications and the call status as they change. diff --git a/docs/features/chat-conversations/chat-features/notifications.mdx b/docs/features/chat-conversations/chat-features/notifications.mdx index 7edb4afa..19f9b452 100644 --- a/docs/features/chat-conversations/chat-features/notifications.mdx +++ b/docs/features/chat-conversations/chat-features/notifications.mdx @@ -34,6 +34,7 @@ Each target has: - **Events** it subscribes to. - **Enabled**, to pause a target without deleting it. - **Automatic Delivery**, either `away` or `always`. +- **Target ID for notify**, the name the `notify` tool uses to pick this target. Left empty, it becomes the webhook's host name. It is saved in lowercase. Each run of characters other than letters, digits, `_` and `-` becomes a single `-`, so `Work/Slack` is saved as `work-slack`. Use **Send Test** to fire a test notification and confirm the endpoint works. diff --git a/docs/features/chat-conversations/data-controls/archived-chats.md b/docs/features/chat-conversations/data-controls/archived-chats.md index 8fcd3500..34e68c3e 100644 --- a/docs/features/chat-conversations/data-controls/archived-chats.md +++ b/docs/features/chat-conversations/data-controls/archived-chats.md @@ -46,7 +46,7 @@ An admin can hide **Archive** under [Visible controls](/features/administration/ ## FAQ **Q: Can I search within archived chats?** -**A:** Yes. The archive dashboard itself searches by chat title. The **Reference Chats** picker in the chat input's **+** menu reads the messages of archived chats too: add the `archived:true` filter, for example `archived:true quarterly report`. You do not need to restore a chat to search inside it. The search window (`Cmd+K` / `Ctrl+K`) leaves archived chats out unless you add `archived:true`. See [History & Search](/features/chat-conversations/chat-features/history-search#filter-prefixes). +**A:** Yes. The archive dashboard itself searches by chat title. The search window (`Cmd+K` / `Ctrl+K`) and the **Reference Chats** picker in the chat input's **+** menu read the messages of archived chats too when you add the `archived:true` filter, for example `archived:true quarterly report`. You do not need to restore a chat to search inside it. See [History & Search](/features/chat-conversations/chat-features/history-search#filter-prefixes). **Q: Is there a limit to how many chats I can archive?** **A:** There is no hard limit. The scalability depends on your database configuration. diff --git a/docs/features/chat-conversations/data-controls/import-export.md b/docs/features/chat-conversations/data-controls/import-export.md index fae581ec..1ac45110 100644 --- a/docs/features/chat-conversations/data-controls/import-export.md +++ b/docs/features/chat-conversations/data-controls/import-export.md @@ -43,6 +43,7 @@ Click the **Import Chats** button and select a JSON file to restore conversation - Imported chats are added to your existing conversations (they don't replace them) - Each imported chat receives a new unique ID, so re-importing the same file will create duplicates - If using ChatGPT exports, the format is automatically detected and converted +- Tags your account does not have yet are created from the file. An export stores each tag in lowercase with underscores, so a tag named Import Test comes back as import_test ## Chat Import JSON Schema @@ -136,7 +137,9 @@ If the objects in the array do **not** have a `chat` key, the entire object is t | `chat` | object | ✅ | The conversation data (see Chat Data below) | | `meta` | object | ❌ | Metadata such as `tags` (array of strings). Defaults to `{}` | | `pinned` | boolean | ❌ | Whether the chat is pinned. Defaults to `false` | -| `folder_id` | string \| null | ❌ | ID of the folder to place the chat in. Defaults to `null`. It has to name a folder **you own**: a folder that does not exist, or one merely shared with you, is cleared and the chat is imported outside any folder rather than failing the import | +| `archived` | boolean | ❌ | Whether the chat is archived. Defaults to `false`. An archived chat is imported into **Settings > Archived Chats** | +| `variables` | object | ❌ | Values filled in for the chat's [chat variables](/features/chat-conversations/chat-features/chat-params#chat-variables). Defaults to `{}` | +| `folder_id` | string \| null | ❌ | ID of the folder to place the chat in. Defaults to `null`. It has to name a folder you can write to, either one you own or one shared with you with **Write** access. A folder that does not exist, or one shared with you for reading only, is cleared and the chat is imported outside any folder rather than failing the import | | `created_at` | integer \| null | ❌ | Unix timestamp (seconds) for when the chat was created | | `updated_at` | integer \| null | ❌ | Unix timestamp (seconds) for when the chat was last updated | diff --git a/docs/features/chat-conversations/rag/document-extraction/external.md b/docs/features/chat-conversations/rag/document-extraction/external.md index dc8a4a2b..b8ede224 100644 --- a/docs/features/chat-conversations/rag/document-extraction/external.md +++ b/docs/features/chat-conversations/rag/document-extraction/external.md @@ -21,7 +21,7 @@ In **Settings > Admin > Documents**, set **Content Extraction Engine** to **Exte - **Document Loader URL**: the base URL of your service. Open WebUI appends `/process` to it. - **API Key**: sent as a bearer token. It is required. With the engine set to External but no key saved, Open WebUI silently falls back to its built-in loaders and never calls your service, and the admin panel does not warn about it. -- **Headers** (optional): a JSON object of additional headers to send with every request, see [templating](#the-contract) below. +- **Headers** (optional): a JSON object of additional headers to send with every request, see [templating](#the-contract) below. If it is not a valid JSON object, **Save** shows `Headers must be a valid JSON object` and stores nothing, even with another engine selected. Switch back to **External** to fix or clear the field. The same settings are available as environment variables: [`CONTENT_EXTRACTION_ENGINE=external`](/reference/env-configuration#content_extraction_engine), [`EXTERNAL_DOCUMENT_LOADER_URL`](/reference/env-configuration#external_document_loader_url), [`EXTERNAL_DOCUMENT_LOADER_API_KEY`](/reference/env-configuration#external_document_loader_api_key), [`EXTERNAL_DOCUMENT_LOADER_HEADERS`](/reference/env-configuration#external_document_loader_headers). diff --git a/docs/features/extensibility/plugin/development/valves.mdx b/docs/features/extensibility/plugin/development/valves.mdx index eed204e7..834e6c9c 100644 --- a/docs/features/extensibility/plugin/development/valves.mdx +++ b/docs/features/extensibility/plugin/development/valves.mdx @@ -271,7 +271,7 @@ Dynamic options are particularly useful for: - Any scenario where options change based on runtime context ::: -### Slider Input +### Slider Input (Number Ranges) A number field can render as a slider with a number box beside it. Both edit the same value, so you can drag or type. Use the range input type and set the ends with `ge` and `le`: @@ -289,4 +289,4 @@ class Tools: ) ``` -`step` is optional. Without it the slider moves in whole steps of 1. It works in `Valves` and `UserValves`. +`step` is optional. Without it the slider moves in whole steps of 1. Always set `ge` and `le`; without them the slider runs from 0 to 100. It works in `Valves` and `UserValves`. diff --git a/docs/features/extensibility/plugin/tools/openapi-servers/index.mdx b/docs/features/extensibility/plugin/tools/openapi-servers/index.mdx index dc534a16..6c9dc4b1 100644 --- a/docs/features/extensibility/plugin/tools/openapi-servers/index.mdx +++ b/docs/features/extensibility/plugin/tools/openapi-servers/index.mdx @@ -46,6 +46,7 @@ Open WebUI parses tool-server specs against the OpenAPI 3.x path-item model. The - Recognizes only the eight standard HTTP method keys (`get`, `put`, `post`, `delete`, `options`, `head`, `patch`, `trace`) as operations. Any other key under a path, including extension keys (`x-codeSamples`, `x-internal`, etc.), `summary`, `description`, `servers`, and `parameters`, is skipped during operation discovery so it never causes a parse error. - Honors **path-level `parameters`**: parameters declared once at the path level apply to every operation under that path. Operation-level parameters with the same `(name, in)` pair override path-level parameters, matching the OpenAPI specification. - URL-encodes path parameter values (`{id}` substitution) and query parameter values, so values containing spaces, `/`, `&`, `?`, or other reserved characters are transmitted correctly. +- Sends an array query parameter as one value per item, for example `tags=red&tags=blue`, which is the default OpenAPI form. - Falls back gracefully between JSON and YAML when fetching the spec: `.yaml`/`.yml` URLs are parsed as YAML; everything else is tried as JSON first and as YAML on failure. Specs that put `parameters` at the path level, expose extension keys, or rely on path-item metadata fields work without changes. diff --git a/docs/features/notes/index.md b/docs/features/notes/index.md index 27d8fde1..95aec8b1 100644 --- a/docs/features/notes/index.md +++ b/docs/features/notes/index.md @@ -105,7 +105,7 @@ Opens the full chat interface in a pane beside the note. It is the same componen **Voice mode** is the exception. Its button is not offered in a note's chat, so use a normal chat for a hands-free voice conversation. Dictation still works, from the microphone button in the chat input. -**Insert a response into the note.** Every assistant response carries an **Insert** button that drops that response into the note at the cursor. Insertion creates a note version first, so **Undo/Redo** (top right) reverts it. +**Insert a response into the note.** With write access on the note, every assistant response carries an **Insert into note** button that drops that response into the note at the cursor. A read-only collaborator does not get the button. Insertion creates a note version first, so **Undo/Redo** (top right) reverts it. **Several conversations per note.** The panel header is a dropdown listing every chat attached to this note. Use it to switch between them, start a new one or delete one. A new conversation is only stored once you send its first message, so opening one and walking away leaves nothing behind. Deleting the last remaining chat immediately recreates an empty one. @@ -194,8 +194,8 @@ Access management options via the **More (...)** menu in the top right corner. ### Export -* **Plain text (.txt)** or **Markdown (.md)** for raw content -* **PDF (.pdf)** with visual formatting and the images pasted into the note (dark mode detected automatically) +* **Plain text (.txt)** or **Plain text (.md)** for raw content +* **PDF document (.pdf)** with visual formatting and the images pasted into the note (dark mode detected automatically) **Download** in the **More (...)** menu exports the whole note, with each page under its own heading. **Download page** in a page's **⋯** menu exports that page alone. @@ -222,7 +222,7 @@ These can also be configured in **Admin Panel > Users > Groups**, as **Notes Sha Files live inside the page where you add them. Drop or paste a file into the editor, or pick **Upload files** in the **More (...)** menu, and it lands at the cursor. Images show inline. Other files become a file block that you can drag, click to open or remove with its **✕**. Adding and removing files needs write access on the note. Anyone with read access to a shared note can open the files attached to it, and the note's chat uses them too. This applies to files the note's owner uploaded, and those files stay read-only for them. -The files on the open page are added as retrieval context on every message you send in a chat opened from this note. +The non-image files on the open page are added as retrieval context on every message you send in a chat opened from this note. ### Formatting diff --git a/docs/features/workspace/models.md b/docs/features/workspace/models.md index 4deb0418..8cddf1e5 100644 --- a/docs/features/workspace/models.md +++ b/docs/features/workspace/models.md @@ -296,7 +296,7 @@ Rows you can edit also carry an **Enabled** switch, in **Workspace > Models** an ### Import and export - **Import**: From `.json` files or Open WebUI community links -- **Export**: Download all custom model configurations as a single `.json` +- **Export**: Download every custom model you can edit as a single `.json`, whatever the search box or filter shows. Admins get every custom model while `BYPASS_ADMIN_ACCESS_CONTROL` is on, which is the default - **Discover**: Browse community presets at the bottom of the page A model's background image travels with it. Export carries the image inside the file, and import stores it on the target instance as a fresh upload, so a model moved between instances keeps its background without you moving files by hand. See the [API endpoints reference](/reference/api-endpoints) for the export and import calls. diff --git a/docs/features/workspace/prompts.md b/docs/features/workspace/prompts.md index 61775f5b..9aa970e6 100644 --- a/docs/features/workspace/prompts.md +++ b/docs/features/workspace/prompts.md @@ -206,7 +206,7 @@ With 20 messages, `{{MESSAGES:MIDDLETRUNCATE:6}}` keeps messages 1-3 and 18-20, ## Version History -Every save creates a new version. When editing a prompt, the history menu above the prompt content starts on **Live**, the active production version. Open it to list the versions newest first, each with its commit message and author (hover for the date), and **Load more** for older ones. +Every save that changes the prompt's content creates a new version. When editing a prompt, the history menu above the prompt content starts on **Live**, the active production version. Open it to list the versions newest first, each with its commit message and author (hover for the date), and **Load more** for older ones. - **Preview** any version by clicking it. Its content opens read-only, with the version ID and date underneath. - **Compare to current** shows what differs between that version and the live one: the name and tags side by side, then the prompt content as a diff. The layout menu switches between **Split** and **Unified**, and the browser remembers the choice. A change that touches only line endings is reported as **Only line endings changed**. diff --git a/docs/getting-started/quick-start/connect-a-provider/starting-with-ollama.mdx b/docs/getting-started/quick-start/connect-a-provider/starting-with-ollama.mdx index 2a8e7ad1..f2f52a53 100644 --- a/docs/getting-started/quick-start/connect-a-provider/starting-with-ollama.mdx +++ b/docs/getting-started/quick-start/connect-a-provider/starting-with-ollama.mdx @@ -79,6 +79,10 @@ This method is perfect if you want to skip navigating through the Admin Settings Ollama can also download GGUF models straight from Hugging Face. In **Pull a model from Ollama.com** or the model selector, enter the model as `hf.co/{username}/{repository}:{quantization}`, for example `hf.co/ggml-org/gemma-3-270m-it-GGUF:Q8_0`. The quantization matches the one in the GGUF file's name, such as `Q4_K_M` or `Q8_0`. The model is then listed under that full name. See Hugging Face's [Ollama guide](https://huggingface.co/docs/hub/en/ollama) for which repositories work. +### Uploading a GGUF File + +To use a GGUF file you already have, open the connection's **Manage** dialog and click **Show** next to the **Experimental** badge at the bottom. The mode button under **Upload a GGUF model** picks the source. **File Mode** uploads a `.gguf` file from your computer, and **URL Mode** takes a Hugging Face resolve (download) URL. Open WebUI sends the file to that Ollama server and creates a model named after the file without its extension, then shows **Model created successfully!**. To give it a system prompt or parameters, base a new model on it as described in [Creating a Model](#creating-a-model). + --- ## Updating and Deleting Models diff --git a/docs/getting-started/quick-start/connect-a-provider/starting-with-openai-compatible/aiand.mdx b/docs/getting-started/quick-start/connect-a-provider/starting-with-openai-compatible/aiand.mdx new file mode 100644 index 00000000..2109bd90 --- /dev/null +++ b/docs/getting-started/quick-start/connect-a-provider/starting-with-openai-compatible/aiand.mdx @@ -0,0 +1,49 @@ +--- +sidebar_position: 1 +title: "ai&" +description: "Bring Japan-hosted AI to your Open WebUI workspace with ai&: open-weight models, domestic inference, and usage-based pricing." +--- + +[ai&](https://www.aiand.com/inference) is an official Open WebUI partner bringing open-weight AI models to teams in Japan through its own domestic infrastructure. Pair Open WebUI's chat and collaboration features with ai&'s hosted inference to give your team an AI workspace without operating GPU servers. + +## Why Choose ai& for Teams in Japan? + +- **Run inference close to your users.** ai& processes inference on its own infrastructure in Japan, designed for low latency across the Asia-Pacific region. +- **Keep inference processing in Japan.** ai&'s [service terms](https://www.aiand.com/legal/inference-terms-of-service) provide for domestic processing of inputs and outputs and prohibit using that content to train models. +- **Choose the model that fits the work.** Access model families such as Kimi, DeepSeek, and GLM through one API. Compare models in Open WebUI and choose from the [ai& catalog](https://docs.aiand.com/models/catalog/) for coding, reasoning, and everyday team chat. +- **Start small and grow.** Begin with per-token pricing, then explore reserved compute and custom SLAs as your team's needs expand. See [ai&'s plans and pricing](https://www.aiand.com/inference). + +**Ready to bring Japan-hosted AI to your workspace?** [Create an ai& API key](https://console.aiand.com/) and follow the steps below. For a Japanese-language overview, visit [ai& Inference 日本語](https://www.aiand.com/jp/inference). + +## Step 1: Get Your API Key + +1. Sign in at [console.aiand.com](https://console.aiand.com/). +2. Create an API key and store it securely; the key is shown only once. +3. Add credits to your account to use the API. + +See the [ai& quick start](https://docs.aiand.com/getting-started/) for account and billing setup. + +## Step 2: Add the Connection in Open WebUI + +1. Go to **Settings > Admin > Connections** and find the **Manage OpenAI API Connections** list. +2. Click **Add Connection**. +3. Enter the following settings: + +| Setting | Value | +|---|---| +| **URL** | `https://api.aiand.com/v1` | +| **API Key** | Your ai& API key | +| **Model IDs** | Leave empty to discover available models, or add specific model IDs to limit the list | + +4. Leave **Provider** under **Advanced** set to **Default**. +5. Click **Verify Connection**, then **Save**. + +ai& exposes a [`/v1/models` endpoint](https://docs.aiand.com/api/models/) for model discovery. Use the exact model IDs returned by that endpoint when adding models to the allowlist. + +## Step 3: Start Chatting + +Open a new chat, select an ai& model from the model selector, and send a message. + +Choose a model with the capabilities your workflow needs. Check the [ai& model catalog](https://docs.aiand.com/models/catalog/) for available models, context windows, and support for features such as reasoning, vision, and tool calling. + +For connection troubleshooting and other configuration options, see the [OpenAI-Compatible guide](/getting-started/quick-start/connect-a-provider/starting-with-openai-compatible). diff --git a/docs/getting-started/quick-start/connect-a-provider/starting-with-openai-compatible.mdx b/docs/getting-started/quick-start/connect-a-provider/starting-with-openai-compatible/index.mdx similarity index 98% rename from docs/getting-started/quick-start/connect-a-provider/starting-with-openai-compatible.mdx rename to docs/getting-started/quick-start/connect-a-provider/starting-with-openai-compatible/index.mdx index a7348a50..8ebd08d0 100644 --- a/docs/getting-started/quick-start/connect-a-provider/starting-with-openai-compatible.mdx +++ b/docs/getting-started/quick-start/connect-a-provider/starting-with-openai-compatible/index.mdx @@ -13,6 +13,12 @@ Open WebUI connects to **any server or provider that implements the OpenAI-compa For OpenAI itself (or Azure OpenAI), see the dedicated **[OpenAI guide](/getting-started/quick-start/connect-a-provider/starting-with-openai)**. +## Official Partners + +Explore our official partners and their setup guides: + +- **[ai& — AI inference from Japan](/getting-started/quick-start/connect-a-provider/starting-with-openai-compatible/aiand)**: Bring open-weight models to your team's workspace with inference hosted in Japan, usage-based pricing, and a straightforward OpenAI-compatible connection. A strong fit for teams building and deploying AI in Japan. + --- ## Protocol-Oriented Design @@ -617,7 +623,7 @@ Each connection has a **toggle switch** that lets you enable or disable it witho ![Lemonade Server](/images/getting-started/lemonade-server.png) - See [their docs](https://lemonade-server.ai/docs/server/apps/open-webui/) for details. + See [their docs](https://lemonade-server.ai/docs/integrations/open-webui/) for details. Then add the connection in Open WebUI using the URL and API Key above: diff --git a/docs/getting-started/quick-start/settings.md b/docs/getting-started/quick-start/settings.md index c87ca0c4..77caaeea 100644 --- a/docs/getting-started/quick-start/settings.md +++ b/docs/getting-started/quick-start/settings.md @@ -44,7 +44,7 @@ User Settings control personal preferences: your default model, interface theme, **Examples of what lives here:** -- Preferred default model and system prompt +- System prompt, and the default model you save with **Set as default** in the model selector - Interface theme and language - Personal API keys (if [Direct Connections](/features/chat-conversations/direct-connections) are enabled) - Per-feature toggles like autocomplete or rich text input diff --git a/docs/reference/env-configuration.mdx b/docs/reference/env-configuration.mdx index 10b629d1..de9bfb09 100644 --- a/docs/reference/env-configuration.mdx +++ b/docs/reference/env-configuration.mdx @@ -2300,7 +2300,7 @@ For maximum performance, enable both: `ENABLE_BASE_MODELS_CACHE=True` with `MODE - Type: `str` - Default: `4w` -- Description: Sets the JWT expiration time in seconds. Valid time units: `s`, `m`, `h`, `d`, `w` or `-1` for no expiration. +- Description: Sets how long a sign-in token stays valid, as a number followed by a unit: `ms`, `s`, `m`, `h`, `d` or `w`, for example `4w` or `12h`. Use `-1` for no expiration. A number without a unit, such as `30`, is not valid, and **Admin Panel > Settings > Authentication** does not save it. - Persistence: This environment variable is a `ConfigVar` variable. :::warning @@ -2756,7 +2756,7 @@ Encryption derives its key from [`WEBUI_SECRET_KEY`](#webui_secret_key). A key o - Type: `bool` - Default: `True` -- Description: When enabled, the application makes automatic update checks and notifies you about version updates. Only release builds check: the official images built from `main` or a release tag, and the pip package. Images built from `dev` and builds whose origin is unknown never check. A Docker image gets its channel from the `BUILD_CHANNEL` build argument (`main`, `dev` or `unknown`, default `unknown`), so build your own release images with `--build-arg BUILD_CHANNEL=main` to keep update checks. +- Description: When enabled, the application makes automatic update checks and notifies you about version updates. Only release builds check: the official images built from `main` or a release tag, and the pip package. Images built from `dev` and builds whose origin is unknown never check. A Docker image gets its channel from the `BUILD_CHANNEL` build argument (`main`, `dev` or `unknown`, default `unknown`), so build your own release images with `--build-arg BUILD_CHANNEL=main` to keep update checks. If the check cannot reach GitHub within one second, **Admin Panel > Settings > General** and **Settings > About** show **Could not check for updates** and the server logs `Version update check failed` as a warning. :::info @@ -5987,7 +5987,7 @@ Note: If none of the specified languages are available and `en` was not in your - Type: `str` - Default: `mp3,wav,m4a,webm,ogg,flac,mp4,mpga,mpeg` -- Description: Comma-separated list of audio file extensions accepted by the Speech-to-Text upload endpoint. Uploads with extensions outside this list are rejected with `400 Invalid audio file extension`. Comparison is case-insensitive. Set to an empty value to skip the extension check (MIME-type validation via `AUDIO_STT_SUPPORTED_CONTENT_TYPES` still applies). Configurable via **Settings → Admin → Audio → STT**. +- Description: Comma-separated list of audio file extensions accepted by the Speech-to-Text upload endpoint. Uploads with extensions outside this list are rejected with `400 Invalid audio file extension`. Comparison is case-insensitive. Set to an empty value to skip the extension check (MIME-type validation via `AUDIO_STT_SUPPORTED_CONTENT_TYPES` still applies). The admin **Audio** settings do not show this list, and saving them leaves it unchanged. - Persistence: This environment variable is a `ConfigVar` variable. ### Text-to-Speech @@ -6200,7 +6200,7 @@ These variables configure **Realtime** call mode for [Voice Mode](/features/chat :::info -When `AUDIO_TTS_ENGINE=mistral`, Open WebUI uses `mistral-tts-latest` when `AUDIO_TTS_MODEL` is empty. +When `AUDIO_TTS_ENGINE=mistral`, Open WebUI uses `voxtral-mini-tts-2603` when `AUDIO_TTS_MODEL` is empty. ::: @@ -7554,7 +7554,7 @@ If you set both `OAUTH_AUDIENCE` and `OAUTH_AUTHORIZE_PARAMS` containing an `aud - Type: `bool` - Default: `True` -- Description: Enables or disables user permission to delete chats. When `False`, the delete controls are hidden from non-admins rather than offered and refused, in the sidebar, the chat menu, search, archived chats and data controls, and the **Delete chat** shortcut stops doing anything. Archiving is unaffected. Deleting a folder that still holds chats needs the same permission and is refused rather than hidden. Configurable per-group as **Allow Chat Delete**. +- Description: Enables or disables user permission to delete chats. When `False`, the delete controls are hidden from non-admins rather than offered and refused, in the sidebar, the chat menu, search, archived chats and data controls, and the **Delete chat** shortcut stops doing anything. Archiving is unaffected. Deleting a folder with **Delete all contents inside this folder** ticked needs the same permission and is refused rather than hidden. With the box unticked, the folder is deleted and its chats are kept. Configurable per-group as **Allow Chat Delete**. - Persistence: This environment variable is a `ConfigVar` variable. #### `USER_PERMISSIONS_CHAT_EDIT` diff --git a/docs/reference/https/haproxy.md b/docs/reference/https/haproxy.md index 324d2113..653f0c86 100644 --- a/docs/reference/https/haproxy.md +++ b/docs/reference/https/haproxy.md @@ -6,7 +6,7 @@ title: "HTTPS using HAProxy" # HAProxy Configuration for Open WebUI -HAProxy (High Availability Proxy) is specialized load-balancing and reverse proxy solution that is highly configurable and designed to handle large amounts of connections with a relatively low resource footprint. for more information, please see: https://www.haproxy.org/ +HAProxy (High Availability Proxy) is a specialized load-balancing and reverse proxy solution that is highly configurable and designed to handle large amounts of connections with a relatively low resource footprint. For more information, please see: https://www.haproxy.org/ ## Install HAProxy and Let's Encrypt @@ -140,7 +140,7 @@ You will need to expose port 80 and 443 to your HAProxy server. These ports are ## Issuing SSL Certificates with Let's Encrypt -Before starting HAProxy, you will want to generate a self signed certificate to use as a placeholder until Let's Encrypt issues a proper one. Here's how to generate a self-signed certificate: +Before starting HAProxy, you will want to generate a self-signed certificate to use as a placeholder until Let's Encrypt issues a proper one. Here's how to generate a self-signed certificate: ```shell openssl req -x509 -newkey rsa:2048 -keyout /tmp/haproxy.key -out /tmp/haproxy.crt -days 3650 -nodes -subj "/CN=localhost" diff --git a/docs/troubleshooting/image-generation.md b/docs/troubleshooting/image-generation.md index 1c1697c0..724f42b5 100644 --- a/docs/troubleshooting/image-generation.md +++ b/docs/troubleshooting/image-generation.md @@ -17,6 +17,7 @@ title: "Image Generation" - **Images settings refuse to save** (saving **Settings** > **Admin** > **Images** shows an error such as `OpenAI API Key is required.`): - Keys and URLs are only required while their feature is on. Fill in the field, or switch the feature off, and save again. + - Invalid JSON in **Additional Parameters** is refused with `Invalid JSON format for Parameters`. Fix or clear it and save again. - **Engine settings are missing** (**Settings** > **Admin** > **Images** shows only the **Image Generation** switch): - The **Create Image** and **Edit Image** sections, with the engines, their keys, **Image Prompt Generation** and **Image Edit**, show only while **Image Generation** is on. Their saved values are kept while hidden. diff --git a/src/components/DocsFeedback/index.tsx b/src/components/DocsFeedback/index.tsx new file mode 100644 index 00000000..9658ad62 --- /dev/null +++ b/src/components/DocsFeedback/index.tsx @@ -0,0 +1,26 @@ +import React from "react"; +import { useDoc } from "@docusaurus/plugin-content-docs/client"; +import useDocusaurusContext from "@docusaurus/useDocusaurusContext"; + +import styles from "./styles.module.css"; + +export default function DocsFeedback() { + const { metadata } = useDoc(); + const { siteConfig } = useDocusaurusContext(); + const params = new URLSearchParams({ + template: "docs-feedback.yml", + title: `[Docs feedback]: ${metadata.title}`, + "page-title": metadata.title, + "page-url": new URL(metadata.permalink, siteConfig.url).href, + }); + + return ( + + ); +} diff --git a/src/components/DocsFeedback/styles.module.css b/src/components/DocsFeedback/styles.module.css new file mode 100644 index 00000000..257dfce9 --- /dev/null +++ b/src/components/DocsFeedback/styles.module.css @@ -0,0 +1,20 @@ +.card { + margin-top: 1.5rem; + padding: 1rem; + font-size: 0.875rem; + line-height: 1.5; +} + +.card p { + margin: 0.5rem 0; +} + +.card a { + font-weight: 600; +} + +@media (width >= 997px) { + .footer-with-sidebar { + display: none; + } +} diff --git a/src/theme/DocItem/Footer/index.tsx b/src/theme/DocItem/Footer/index.tsx index fc3b16c9..abed9576 100644 --- a/src/theme/DocItem/Footer/index.tsx +++ b/src/theme/DocItem/Footer/index.tsx @@ -1,12 +1,25 @@ import React from "react"; import DocItemFooter from "@theme-original/DocItem/Footer"; +import { useDoc } from "@docusaurus/plugin-content-docs/client"; +import DocsFeedback from "@site/src/components/DocsFeedback"; +import feedbackStyles from "@site/src/components/DocsFeedback/styles.module.css"; const DISCLAIMER_TEXT = 'This content is for informational purposes only and does not constitute a warranty, guarantee, or contractual commitment. Open WebUI is provided "as is." See your '; export default function DocItemFooterWrapper(props) { + const { frontMatter, toc } = useDoc(); + const hasSidebar = !frontMatter.hide_table_of_contents && toc.length > 0; + return ( <> +
+ +
{DISCLAIMER_TEXT} license for applicable terms. diff --git a/src/theme/DocItem/TOC/Desktop/index.tsx b/src/theme/DocItem/TOC/Desktop/index.tsx new file mode 100644 index 00000000..01c906d1 --- /dev/null +++ b/src/theme/DocItem/TOC/Desktop/index.tsx @@ -0,0 +1,14 @@ +import React from "react"; +import DocItemTOCDesktop from "@theme-original/DocItem/TOC/Desktop"; +import DocsFeedback from "@site/src/components/DocsFeedback"; + +import styles from "./styles.module.css"; + +export default function DocItemTOCDesktopWrapper() { + return ( +
+ + +
+ ); +} diff --git a/src/theme/DocItem/TOC/Desktop/styles.module.css b/src/theme/DocItem/TOC/Desktop/styles.module.css new file mode 100644 index 00000000..f1a761b2 --- /dev/null +++ b/src/theme/DocItem/TOC/Desktop/styles.module.css @@ -0,0 +1,27 @@ +.sidebar { + display: flex; + flex-direction: column; + position: sticky; + top: calc(var(--ifm-navbar-height) + 1rem); + max-height: calc(100vh - var(--ifm-navbar-height) - 2rem); + overflow-y: auto; + padding-bottom: 1px; +} + +/* Scroll long tables of contents while keeping the feedback card visible. */ +.sidebar > div { + position: static; + min-height: 0; + max-height: none; + overflow-y: auto; +} + +.sidebar > aside { + flex-shrink: 0; +} + +@media (width <= 996px) { + .sidebar { + display: none; + } +} diff --git a/src/theme/Footer/index.tsx b/src/theme/Footer/index.tsx index 19fc5672..be8e5521 100644 --- a/src/theme/Footer/index.tsx +++ b/src/theme/Footer/index.tsx @@ -33,8 +33,7 @@ export default function FooterWrapper(props) { data-no-analytics >

- Allow optional analytics to help us improve our documentation and - marketing pages? Your choice applies to both sites.{" "} + Allow optional analytics to help us improve our websites?{" "} Privacy policy