Skip to content

fix(desktop): fix browser pane not loading images#1571

Merged
Kitenite merged 1 commit into
mainfrom
kitenite/fix/browser-pane-not-loading-images
Feb 19, 2026
Merged

fix(desktop): fix browser pane not loading images#1571
Kitenite merged 1 commit into
mainfrom
kitenite/fix/browser-pane-not-loading-images

Conversation

@Kitenite
Copy link
Copy Markdown
Collaborator

@Kitenite Kitenite commented Feb 18, 2026

Summary

  • The persistent webview refactor (refactor(desktop): Make browser tabs persistent #1535) switched from JSX-rendered <webview> to programmatic createElement, but lost the display: flex; flex: 1 styling needed for proper element sizing
  • The renderer's CSP lacked explicit frame-src (falling back to restrictive default-src 'self') and was missing http:/blob: in img-src, which could block the webview from loading external content and images

Changes

  • usePersistentWebview.ts: Added display: flex and flex: 1 to the programmatically-created webview element, matching the old JSX implementation
  • index.html (CSP): Added http: and blob: to img-src for full image source compatibility; added explicit frame-src https: http: data: blob: to allow the webview browser pane to load any URL; added child-src 'self' blob: for worker compatibility

Test Plan

  • Open a browser pane and navigate to an image-heavy site (e.g. google images)
  • Verify images render correctly within the browser pane
  • Switch tabs and return — verify images persist after webview reparenting
  • Test both HTTP and HTTPS sites load images correctly
  • Verify URL suggestion favicons load in the address bar dropdown

Summary by CodeRabbit

Chores

  • Expanded security policy directives to permit loading of images, frames, web worker content, and blob-based resources from additional sources, improving system resource compatibility.

Style

  • Enhanced webview component layout and rendering by applying flexbox CSS styling properties for improved display consistency and visual presentation.

The persistent webview refactor (#1535) introduced two issues that
prevented the browser pane from loading/rendering images:

1. Missing display styling on programmatically-created webview element.
   The old JSX-rendered <webview> had `display: flex; flex: 1` but the
   new createElement approach only set width/height, causing the custom
   element to default to `display: inline` where dimensions may not
   apply correctly.

2. Restrictive Content Security Policy. The renderer CSP lacked explicit
   `frame-src` (falling back to `default-src 'self'`) which could block
   the webview from loading external content. Also added `http:` and
   `blob:` to `img-src` for full image source compatibility.
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Feb 18, 2026

📝 Walkthrough

Walkthrough

The pull request updates the Content-Security-Policy in the desktop renderer to permit additional image sources and webview-related content, while also adding CSS flex styling properties to webview elements to improve their layout behavior.

Changes

Cohort / File(s) Summary
Content-Security-Policy Directives
apps/desktop/src/renderer/index.html
Expanded img-src to allow http: and blob: sources; added frame-src and child-src directives to support webview content, workers, and blob-based resource loading.
Webview Styling
apps/desktop/src/renderer/screens/main/components/.../usePersistentWebview/usePersistentWebview.ts
Applied CSS flex properties (display: flex and flex: 1) to webview elements during creation for improved layout flexibility.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

Poem

🐰 The webview stretches with flex so fine,
CSP rules now drawing the line,
Blobs and frames in harmony's dance,
Layout improves with each flex advance!

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main fix: addressing an issue where the browser pane was not loading images, which directly matches the core problem identified in the PR objectives.
Description check ✅ Passed The PR description provides a clear summary of changes, specific file modifications, and a detailed test plan. It thoroughly addresses the root causes and implementation details, though it doesn't strictly follow the provided template structure with explicit sections.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch kitenite/fix/browser-pane-not-loading-images

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
apps/desktop/src/renderer/index.html (1)

18-20: Use worker-src instead of (or alongside) child-src for explicit worker control.

In CSP Level 3, frame-src has been undeprecated and continues to defer to child-src if not present. A worker-src directive has been added, deferring to child-src if not present. Since frame-src is now explicitly set in this policy, child-src will only be consulted as a fallback for workers — its frame-control role is effectively superseded. Modern best practices recommend using worker-src instead of child-src for clarity and control, though child-src should be retained for backward compatibility with older browsers.

♻️ Proposed addition for explicit worker control
-      - child-src 'self' blob:: Allow workers from same origin + blob workers
+      - worker-src 'self' blob:: Allow workers from same origin + blob workers (CSP Level 3)
+      - child-src 'self' blob:: Fallback for worker-src in older browsers
- content="...; frame-src https: http: data: blob:; child-src 'self' blob:;"
+ content="...; frame-src https: http: blob:; worker-src 'self' blob:; child-src 'self' blob:;"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/desktop/src/renderer/index.html` around lines 18 - 20, The
Content-Security-Policy meta tag currently uses child-src for worker control;
add an explicit worker-src directive (e.g., worker-src 'self' blob:) alongside
the existing child-src to ensure modern browsers use the intended worker policy
while retaining child-src for backward compatibility—update the
Content-Security-Policy meta tag content attribute in the renderer index.html to
include worker-src with the same sources as child-src.
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/TabView/BrowserPane/hooks/usePersistentWebview/usePersistentWebview.ts (1)

143-144: display: flex on the webview is a no-op for its rendered content — flex: 1 is the actual fix.

display: flex makes the <webview> element itself a flex container (meaningless since the webview renders an isolated page). The property that enables it to fill the parent flex container as a flex item is flex: 1. If the original JSX used Tailwind's flex class (which emits display: flex), this is a faithful restore, so no action is strictly required — but if you want semantic precision, display: block is sufficient alongside flex: 1.

♻️ Minimal alternative if you want to remove the no-op
-			webview.style.display = "flex";
 			webview.style.flex = "1";
 			webview.style.width = "100%";
 			webview.style.height = "100%";

Or if the original JSX class set display: flex intentionally (e.g., Tailwind flex), keep it as-is — it is harmless.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/TabView/BrowserPane/hooks/usePersistentWebview/usePersistentWebview.ts`
around lines 143 - 144, The webview.style.display = "flex" is a no-op for the
webview's rendered page and should be removed or changed to a semantic value; in
usePersistentWebview.ts update the webview styling so only the flex item
behavior remains (keep webview.style.flex = "1" and either remove the
webview.style.display assignment or change it to "block") — locate the webview
DOM reference in the hook where webview.style.display and webview.style.flex are
set and apply this change.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@apps/desktop/src/renderer/index.html`:
- Around line 17-20: Remove the insecure "data:" source from the
Content-Security-Policy meta tag's frame-src directive in the renderer
index.html (the meta tag with http-equiv="Content-Security-Policy"); update the
content attribute so frame-src only contains https: and http: (and blob: if
still required for other uses) — ensure you do not reintroduce "data:" anywhere
in the frame-src value while keeping other directives (script-src, style-src,
connect-src, img-src, child-src) unchanged.

---

Nitpick comments:
In `@apps/desktop/src/renderer/index.html`:
- Around line 18-20: The Content-Security-Policy meta tag currently uses
child-src for worker control; add an explicit worker-src directive (e.g.,
worker-src 'self' blob:) alongside the existing child-src to ensure modern
browsers use the intended worker policy while retaining child-src for backward
compatibility—update the Content-Security-Policy meta tag content attribute in
the renderer index.html to include worker-src with the same sources as
child-src.

In
`@apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/TabView/BrowserPane/hooks/usePersistentWebview/usePersistentWebview.ts`:
- Around line 143-144: The webview.style.display = "flex" is a no-op for the
webview's rendered page and should be removed or changed to a semantic value; in
usePersistentWebview.ts update the webview styling so only the flex item
behavior remains (keep webview.style.flex = "1" and either remove the
webview.style.display assignment or change it to "block") — locate the webview
DOM reference in the hook where webview.style.display and webview.style.flex are
set and apply this change.

Comment on lines +17 to +20
- frame-src https: http: data: blob:: Allow webview browser pane to load any URL
- child-src 'self' blob:: Allow workers from same origin + blob workers
-->
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self' 'wasm-unsafe-eval' https://*.posthog.com; style-src 'self' 'unsafe-inline'; connect-src 'self' ws: wss: %NEXT_PUBLIC_API_URL% %NEXT_PUBLIC_ELECTRIC_URL% %NEXT_PUBLIC_STREAMS_URL% https://*.posthog.com https://*.sentry.io sentry-ipc:; img-src 'self' data: https:; font-src 'self';" />
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self' 'wasm-unsafe-eval' https://*.posthog.com; style-src 'self' 'unsafe-inline'; connect-src 'self' ws: wss: %NEXT_PUBLIC_API_URL% %NEXT_PUBLIC_ELECTRIC_URL% %NEXT_PUBLIC_STREAMS_URL% https://*.posthog.com https://*.sentry.io sentry-ipc:; img-src 'self' data: https: http: blob:; font-src 'self'; frame-src https: http: data: blob:; child-src 'self' blob:;" />
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

data: in frame-src enables arbitrary-HTML frames — remove it unless explicitly required.

data: URIs as a content source allows loading arbitrary content; this is insecure since an attacker can inject arbitrary data: URIs. It should be avoided and is not recommended. Allowing data: in frame-src means any code path that can influence a frame's src could inject a data:text/html,<script>...</script> payload. For the browser-pane use case (loading http:/https: sites in a webview), data: is not needed. The http: and https: sources already cover all legitimate frame/webview loading scenarios.

🛡️ Proposed fix
-      - frame-src https: http: data: blob:: Allow webview browser pane to load any URL
+      - frame-src https: http: blob:: Allow webview browser pane to load any URL
-    <meta http-equiv="Content-Security-Policy" content="...; frame-src https: http: data: blob:; child-src 'self' blob:;" />
+    <meta http-equiv="Content-Security-Policy" content="...; frame-src https: http: blob:; child-src 'self' blob:;" />
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- frame-src https: http: data: blob:: Allow webview browser pane to load any URL
- child-src 'self' blob:: Allow workers from same origin + blob workers
-->
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self' 'wasm-unsafe-eval' https://*.posthog.com; style-src 'self' 'unsafe-inline'; connect-src 'self' ws: wss: %NEXT_PUBLIC_API_URL% %NEXT_PUBLIC_ELECTRIC_URL% %NEXT_PUBLIC_STREAMS_URL% https://*.posthog.com https://*.sentry.io sentry-ipc:; img-src 'self' data: https:; font-src 'self';" />
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self' 'wasm-unsafe-eval' https://*.posthog.com; style-src 'self' 'unsafe-inline'; connect-src 'self' ws: wss: %NEXT_PUBLIC_API_URL% %NEXT_PUBLIC_ELECTRIC_URL% %NEXT_PUBLIC_STREAMS_URL% https://*.posthog.com https://*.sentry.io sentry-ipc:; img-src 'self' data: https: http: blob:; font-src 'self'; frame-src https: http: data: blob:; child-src 'self' blob:;" />
- frame-src https: http: blob:: Allow webview browser pane to load any URL
- child-src 'self' blob:: Allow workers from same origin + blob workers
-->
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self' 'wasm-unsafe-eval' https://*.posthog.com; style-src 'self' 'unsafe-inline'; connect-src 'self' ws: wss: %NEXT_PUBLIC_API_URL% %NEXT_PUBLIC_ELECTRIC_URL% %NEXT_PUBLIC_STREAMS_URL% https://*.posthog.com https://*.sentry.io sentry-ipc:; img-src 'self' data: https: http: blob:; font-src 'self'; frame-src https: http: blob:; child-src 'self' blob:;" />
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/desktop/src/renderer/index.html` around lines 17 - 20, Remove the
insecure "data:" source from the Content-Security-Policy meta tag's frame-src
directive in the renderer index.html (the meta tag with
http-equiv="Content-Security-Policy"); update the content attribute so frame-src
only contains https: and http: (and blob: if still required for other uses) —
ensure you do not reintroduce "data:" anywhere in the frame-src value while
keeping other directives (script-src, style-src, connect-src, img-src,
child-src) unchanged.

@Kitenite Kitenite merged commit 86afbf0 into main Feb 19, 2026
5 of 6 checks passed
@Kitenite Kitenite deleted the kitenite/fix/browser-pane-not-loading-images branch February 19, 2026 00:27
@github-actions
Copy link
Copy Markdown
Contributor

🧹 Preview Cleanup Complete

The following preview resources have been cleaned up:

  • ⚠️ Neon database branch
  • ⚠️ Electric Fly.io app

Thank you for your contribution! 🎉

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant