Skip to content

fix: derive embedded FletApp WebSocket endpoint from its own URL on web - #6795

Open
jmvillalba wants to merge 5 commits into
flet-dev:mainfrom
jmvillalba:fix/embedded-fletapp-websocket-path
Open

fix: derive embedded FletApp WebSocket endpoint from its own URL on web#6795
jmvillalba wants to merge 5 commits into
flet-dev:mainfrom
jmvillalba:fix/embedded-fletapp-websocket-path

Conversation

@jmvillalba

@jmvillalba jmvillalba commented Aug 28, 2026

Copy link
Copy Markdown

Description

Fixes #6794.

On web, an embedded FletApp builds its websocket URL from the host document's endpoint configuration (window.flet.webSocketEndpoint) instead of from its own url. That value describes the host app and is shared by every app embedded on the page, so a path-prefixed embedded URL like FletApp(url="https://gateway/device1/") (device UIs behind a reverse proxy, in my case) loses its prefix and never connects. io already derives the path from the URL — this aligns web with it, for embedded sessions only.

Changes:

  • flet_backend.dart: connect() passes embedded: controlId != null to the channel factory (controlId is only set for embedded backends).
  • flet_backend_channel.dart: optional embedded flag on the factory (default false), forwarded to the websocket channel only.
  • flet_backend_channel_web_socket.dart: when embedded, derive the ws path from the app's own URL; the root branch is untouched (its URL path can contain the app route rather than the mount point, which is why the endpoint is injected by the server in the first place).
  • utils/uri.dart: small shared helper mirroring the io implementation ("""ws", "/sub1""sub1/ws").
  • test/transport/web_socket_endpoint_test.dart: unit tests for the embedded branch (prefix kept, dedicated port, schemes, no-trailing-slash/nested paths), a guard that the root branch is unchanged, and the factory pass-through (flag forwarded, defaults to non-embedded). Helper cases added to the existing test/utils/uri_test.dart.
  • CHANGELOG.md: entry under 1.0.0 / Bug fixes.

Behavior before/after:

Case Before After
Root app (any mount) host config host config (unchanged)
Embedded by port (http://host:9001/) works works, same endpoint
Embedded by path (https://gateway/device1/) wss://gateway/ws, never connects wss://gateway/device1/ws
Embedded on io/desktop works works (both branches equivalent on io)

Assets for path-embedded apps can already be handled with FletApp.assets_dir; the websocket endpoint had no equivalent, hence this fix.

Test Code

cd packages/flet
flutter test test/transport/web_socket_endpoint_test.dart

Summary by Sourcery

Ensure embedded web apps derive their WebSocket endpoint from their own URL so path-prefixed deployments connect correctly.

Bug Fixes:

  • Fix embedded FletApp web sessions so WebSocket endpoints preserve path prefixes from the embedded app URL while leaving root app endpoint resolution unchanged.

Enhancements:

  • Share WebSocket endpoint path derivation between web and io implementations and propagate embedded-session context through the backend channel factory.

CI:

  • Run browser-specific WebSocket endpoint tests in CI alongside the existing Flutter test suite.

Tests:

  • Add VM and Chrome coverage for embedded and root WebSocket endpoint resolution, URL schemes, ports, nested paths, and factory defaults.

@CLAassistant

CLAassistant commented Aug 28, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@sourcery-ai sourcery-ai Bot left a comment

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.

Hey - I've reviewed your changes and they look great!


Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

The io implementation and getWebSocketEndpointPathFromUriPath were the same
three lines in two places; the embedded fix relies on them agreeing, so make
that structural rather than coincidental. Also drop two [FletApp] dartdoc
references that don't resolve in the files they appear in.
…s differ

Under flutter test the conditional import resolves to platform_utils_non_web,
where both branches of getWebSocketEndpoint derive the path from the URL — so
the endpoint assertions passed with or without the fix, and the root-branch
test asserted io behavior under a name claiming platform independence (it
fails under --platform chrome).

Move the discriminating assertions into a @teston("browser") file: with
window.flet undefined the root branch falls back to the bare "ws" endpoint,
which is exactly the value a path-prefixed embedded app used to get. Reverting
the fix now fails that file. Keep the io claim as a kIsWeb-skipped group, and
run the web file in CI.

Copilot AI left a comment

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.

Pull request overview

This PR fixes a web-only regression/bug where embedded FletApp instances derived their WebSocket endpoint path from the host document’s injected configuration (shared across all embeds) instead of from the embedded app’s own url, breaking path-prefixed reverse-proxy deployments. The change aligns embedded-web behavior with the existing io path-derivation logic while preserving root-app behavior on web.

Changes:

  • Thread an embedded flag from FletBackend.connect() through the backend channel factory into FletWebSocketBackendChannel.
  • When embedded == true on web, derive the WebSocket endpoint path from the app’s own URL path; keep the root-web behavior unchanged.
  • Add unit + browser-only tests for endpoint composition and add a CI step to run the browser regression test.

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
packages/flet/lib/src/flet_backend.dart Marks channels as embedded when controlId is set (embedded FletApp).
packages/flet/lib/src/transport/flet_backend_channel.dart Adds embedded flag to the channel factory and forwards it to the WebSocket channel.
packages/flet/lib/src/transport/flet_backend_channel_web_socket.dart Uses embedded-specific endpoint path derivation on web; root branch unchanged.
packages/flet/lib/src/utils/uri.dart Introduces shared helper to derive …/ws path from a URL path (mirrors prior io logic).
packages/flet/lib/src/utils/platform_utils_non_web.dart Delegates io endpoint-path logic to the shared URI helper.
packages/flet/test/utils/uri_test.dart Adds unit tests for the new URI-path → websocket-path helper.
packages/flet/test/transport/web_socket_endpoint_test.dart Adds VM tests for embedded endpoint composition and factory plumbing; skips io-root group on web.
packages/flet/test/transport/web_socket_endpoint_web_test.dart Adds browser-only regression test for embedded-vs-root web behavior.
.github/workflows/ci.yml Runs the new browser-only test on CI via flutter test --platform chrome ….
CHANGELOG.md Adds a 1.0.0 bug-fix entry describing the embedded-web endpoint fix.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@@ -0,0 +1,41 @@
@TestOn("browser")
library;

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

FWIW, library; (the unnamed library directive) is valid Dart since 2.19 and is the idiomatic anchor for library-level annotations like @TestOn — the file parses and runs fine under flutter test --platform chrome. Leaving the call to @FeodorFitsner since it's his test, but I don't believe there's anything to fix here.

Comment thread packages/flet/lib/src/utils/uri.dart Outdated
@ndonkoHenri

Copy link
Copy Markdown
Contributor

@jmvillalba can u please check this comment?

@jmvillalba

Copy link
Copy Markdown
Author

Done — the commit email is now verified on my GitHub account and the CLA check shows all committers signed. Thanks for the ping @ndonkoHenri!

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.

Embedded FletApp (web) ignores the URL path when connecting its WebSocket, so path-prefixed URLs never connect

5 participants