From 26524efceea88eacf2fee9765a4cf02baf3184f0 Mon Sep 17 00:00:00 2001 From: DrMelone <27028174+Classic298@users.noreply.github.com> Date: Sat, 7 Mar 2026 21:33:14 +0100 Subject: [PATCH] base64 warn --- .../extensibility/plugin/functions/action.mdx | 21 ++++++++++++++----- .../extensibility/plugin/functions/filter.mdx | 9 ++++---- docs/troubleshooting/performance.md | 1 + 3 files changed, 22 insertions(+), 9 deletions(-) diff --git a/docs/features/extensibility/plugin/functions/action.mdx b/docs/features/extensibility/plugin/functions/action.mdx index 1121c308..66199402 100644 --- a/docs/features/extensibility/plugin/functions/action.mdx +++ b/docs/features/extensibility/plugin/functions/action.mdx @@ -128,12 +128,12 @@ actions = [ { "id": "summarize", "name": "Summarize", - "icon_url": "data:image/svg+xml;base64,..." + "icon_url": "https://example.com/icons/summarize.svg" }, { "id": "translate", "name": "Translate", - "icon_url": "data:image/svg+xml;base64,..." + "icon_url": "https://example.com/icons/translate.svg" } ] @@ -231,9 +231,20 @@ Example of supported frontmatter fields: - `author`: Name of the creator. - `version`: Version number of the Action. - `required_open_webui_version`: Minimum compatible version of Open WebUI. -- `icon_url (optional)`: URL or Base64 string for a custom icon. +- `icon_url (optional)`: A URL pointing to an icon image (PNG, SVG, JPEG, etc.). While base64 data URIs are technically supported, **using a hosted URL is strongly recommended** — see the warning below. -**Base64-Encoded Example:** +:::danger Avoid Base64 Icons — Use URLs Instead +Do **not** embed base64-encoded images as your `icon_url`. The icon data for every action is included in the `/api/models` API response, which is sent to the frontend on every page load for **every model** that has the action enabled. + +**Example of the impact:** If you use a 500 KB base64 icon for an action, and that action is enabled on 20 models, the API response grows by **20 × 500 KB = ~10 MB** — just for that one action. If you have three such actions, that becomes **~30 MB of unnecessary payload**. This will: +- **Significantly slow down frontend load times** for all users +- **Increase backend memory usage and network bandwidth** on every request +- **Degrade the overall user experience**, especially on slower connections + +Instead, host your icon as a static file (e.g., on your web server, a CDN, or a public URL) and reference it by URL. This keeps the API payload minimal. +::: + +**Example (Recommended — URL icon):**
Example @@ -244,7 +255,7 @@ title: Enhanced Message Processor author: @admin version: 1.2.0 required_open_webui_version: 0.5.0 -icon_url: data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTEyIDJMMTMuMDkgOC4yNkwyMCA5TDEzLjA5IDE1Ljc0TDEyIDIyTDEwLjkxIDE1Ljc0TDQgOUwxMC45MSA4LjI2TDEyIDJaIiBzdHJva2U9ImN1cnJlbnRDb2xvciIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiLz4KPHN2Zz4K +icon_url: https://example.com/icons/message-processor.svg requirements: requests,beautifulsoup4 """ diff --git a/docs/features/extensibility/plugin/functions/filter.mdx b/docs/features/extensibility/plugin/functions/filter.mdx index 6ad4540e..7284e625 100644 --- a/docs/features/extensibility/plugin/functions/filter.mdx +++ b/docs/features/extensibility/plugin/functions/filter.mdx @@ -85,8 +85,9 @@ class Filter: def __init__(self): self.valves = self.Valves() self.toggle = True # IMPORTANT: This creates a switch UI in Open WebUI - # TIP: Use SVG Data URI! - self.icon = """data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGZpbGw9Im5vbmUiIHZpZXdCb3g9IjAgMCAyNCAyNCIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0cm9rZT0iY3VycmVudENvbG9yIiBjbGFzcz0ic2l6ZS02Ij4KICA8cGF0aCBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIGQ9Ik0xMiAxOHYtNS4yNW0wIDBhNi4wMSA2LjAxIDAgMCAwIDEuNS0uMTg5bS0xLjUuMTg5YTYuMDEgNi4wMSAwIDAgMS0xLjUtLjE4OW0zLjc1IDcuNDc4YTEyLjA2IDEyLjA2IDAgMCAxLTQuNSAwbTMuNzUgMi4zODNhMTQuNDA2IDE0LjQwNiAwIDAgMS0zIDBNMTQuMjUgMTh2LS4xOTJjMC0uOTgzLjY1OC0xLjgyMyAxLjUwOC0yLjMxNmE3LjUgNy41IDAgMSAwLTcuNTE3IDBjLjg1LjQ5MyAxLjUwOSAxLjMzMyAxLjUwOSAyLjMxNlYxOCIgLz4KPC9zdmc+Cg==""" + # TIP: Use a hosted URL for your icon instead of base64 to avoid API payload bloat. + # See the Action Function docs for details on why base64 icons are not recommended. + self.icon = "https://example.com/icons/lightbulb.svg" pass async def inlet( @@ -107,7 +108,7 @@ class Filter: #### 🖼️ What’s happening? - **toggle = True** creates a switch UI in Open WebUI—users can manually enable or disable the filter in real time. -- **icon** (with a Data URI) will show up as a little image next to the filter’s name. You can use any SVG as long as it’s Data URI encoded! +- **icon** will show up as a little image next to the filter’s name. You can use a URL pointing to any image (SVG, PNG, JPEG, etc.). While base64 data URIs are technically supported, **using a hosted URL is strongly recommended** to avoid bloating the `/api/models` payload — see the [Action Function icon_url warning](/features/extensibility/plugin/functions/action#example---specifying-action-frontmatter) for details. - **The `inlet` function** uses the `__event_emitter__` special argument to broadcast feedback/status to the UI, such as a little toast/notification that reads "Toggled!" ![Toggle Filter](/images/features/plugin/functions/toggle-filter.png) @@ -292,7 +293,7 @@ class ContentModerationFilter: class WebSearchFilter: def __init__(self): self.toggle = True # User can turn on/off - self.icon = "data:image/svg+xml;base64,..." # Shows in UI + self.icon = "https://example.com/icons/web-search.svg" # Shows in UI async def inlet(self, body: dict, __event_emitter__) -> dict: # Only runs when user has enabled this filter diff --git a/docs/troubleshooting/performance.md b/docs/troubleshooting/performance.md index 5b7cc77b..cc5ecb31 100644 --- a/docs/troubleshooting/performance.md +++ b/docs/troubleshooting/performance.md @@ -430,6 +430,7 @@ These are real-world mistakes that cause organizations to massively over-provisi | **Scaling replicas to mask memory leaks** | Leaky processes → OOM kills → auto-scaler adds more pods → more Redis connections → Redis overwhelmed | Fix the leaks first (content extraction, embedding engine), then right-size | | **Using Default (prompt-based) tool calling** | Injected prompts may break KV cache → higher latency → more resources needed per request | Switch to Native Mode for all capable models | | **Not configuring Redis stale connection timeout** | Connections accumulate forever → Redis OOM → you deploy Redis Cluster | Add `timeout 1800` to redis.conf | +| **Using base64-encoded icons in Actions/Filters** | Icon data is embedded in `/api/models` responses sent to the frontend on every page load for every model. A 500 KB base64 icon on 3 actions across 20 models = **30 MB of payload bloat** per request → slow frontend loads, high bandwidth usage, unnecessary backend memory pressure | Host icons as static files and reference them by URL in `icon_url` / `self.icon`. See [Action Function icon_url warning](/features/extensibility/plugin/functions/action#example---specifying-action-frontmatter) | ---