Skip to content

feat(connect-ui): non-root base path via relative base + runtime basepath#6802

Draft
macko911 wants to merge 35 commits into
masterfrom
matej/nan-6242-connect-ui-runtime-basepath
Draft

feat(connect-ui): non-root base path via relative base + runtime basepath#6802
macko911 wants to merge 35 commits into
masterfrom
matej/nan-6242-connect-ui-runtime-basepath

Conversation

@macko911

@macko911 macko911 commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Problem

Connect UI's built assets are referenced from the domain root (/assets/…), so self-hosters serving it under a shared path prefix (e.g. example.com/nango/connect/) get 404s and a blank page. PR #6765 solves this with a build-time placeholder rewritten in dist at container startup, but that requires a writable dist at runtime, leaves the artifact broken until the rewrite runs, and goes stale if the env changes on a container restart.

Prototype — one of two alternative approaches to #6765, built for comparison. Sibling: the hash-routing prototype (#6801, closed — complexity turned out near-identical, so its URL/observability trade-offs bought nothing).

Solution

Build with a relative base and derive the router basepath from the document URL at load, so the same prebuilt bundle serves from any base path with zero rewriting — no writable filesystem, no CI step, nothing baked in, and URL shapes unchanged from today.

  • Vite base: './': assets resolve relative to the document URL.
  • Router basepath comes from new URL('.', document.baseURI) — works at the base root and at depth-1 route refreshes; import.meta.env.BASE_URL is useless with a relative base (it's the literal './').
  • serve:unsafe gains -s (SPA fallback) so an in-app refresh at /integrations keeps working; custom static hosts need the equivalent rewrite-to-index rule.
  • Failure-driven trailing-slash retry: an onerror hook on the entry script redirects to the slashed URL only when the asset load actually failed — no route names in index.html to keep in sync, no false redirects on deep-route refreshes. (A slashless sub-path URL is e2e-confirmed to white-screen without it.)
  • Normalized trailing slash at every URL producer: frontend SDK iframe, dashboard preview iframe, server connect_link (new buildConnectUiSessionLink in utils), and CSP sources (path matching is exact without a trailing slash).
  • Fixed two latent origin bugs that break any sub-path deployment: telemetry CORS compared the path-less Origin header against the full URL, and the dashboard preview's message listener did the same.
  • Deleted the placeholder/rewrite machinery from feat(connect-ui): support non-root base path #6765: set-base-path scripts + tests, the deploy workflow step, and the writable-dist docs caveats (net −180 lines).

Fixes NAN-6242

Testing

  • Browser e2e behind a prefix-stripping proxy: sub-path entry, slashless URL with query (guard redirects, query preserved), deep-route refresh at /integrations under the prefix, and root deployment all boot with assets 200.
  • ts-build, connect-ui browser tests (incl. basepathFromDocumentBaseURI cases pinning root, sub-path, deep-refresh, and the documented slashless misconfiguration), utils unit tests, and a build inspection (relative refs, no placeholder) all pass.

Trade-offs vs the sibling prototype

  • URLs, server-log visibility, and future options (SSR, analytics route tracking) unchanged from today.
  • Costs: basepath derivation logic + a small build plugin to maintain, and SPA fallback required on static hosts for deep-route refreshes.

macko911 and others added 30 commits July 15, 2026 11:53
Self-hosters behind a reverse proxy that routes by path (everything under
a shared prefix, no per-service subdomain) could not serve Connect UI: the
bundle was built with a root-relative base, so assets resolved at the
origin root and the app failed to load.

Build the bundle with a placeholder base and rewrite it to the configured
path at container start (derived from NANGO_PUBLIC_CONNECT_URL, or an
explicit NANGO_CONNECT_UI_BASE_PATH override; defaults to "/"). The
prebuilt image needs no rebuild. The router basepath is read from
import.meta.env.BASE_URL so client-side routing works under the sub-path.
Address review feedback on base path handling:

- Insert the base path with a function replacer so a literal `$` in it
  isn't read as a replacement pattern ($&, $1, ...).
- Strip any query or fragment mistakenly passed in the explicit
  NANGO_CONNECT_UI_BASE_PATH override.
- Extract the BASE_URL -> router basepath derivation into a pure
  function and cover it, resolveBasePath, and the query/fragment case
  with tests.
The connect_ui deploy workflow builds the bundle and syncs it straight to
static hosting (e.g. connect.nango.dev). Since the build now emits a
placeholder base, that upload would ship unresolved placeholders and break
the hosted UI. Run set-base-path.js after the build so the placeholder is
rewritten to "/" (the origin root) before upload.

Also clarify the surrounding comments: the rewrite is mandatory before
serving (not a no-op for root), and note the docs/self-hoster follow-up.
Document serving Connect UI under a non-root base path via
NANGO_PUBLIC_CONNECT_URL (with the NANGO_CONNECT_UI_BASE_PATH override)
and the reverse-proxy prefix-stripping requirement.
Expose the base-path rewrite as `npm run -w @nangohq/connect-ui
set-base-path` and use it in the entrypoint and the connect_ui deploy
workflow. Gives self-hosters who serve the static bundle themselves an
ergonomic command instead of a raw node invocation.
Self-hosters serving Connect UI's static files from their own host must
run the base-path rewrite before uploading; the built assets carry a
placeholder base until then.
The base path is written verbatim into the built HTML/CSS/JS, so a
malformed value could emit broken or unsafe asset URLs. Reject anything
outside a safe URL-path character set so misconfiguration fails loudly at
rewrite time instead. Also guards the JS template-literal context, where
a "$" or backtick in the base could otherwise break out of the string.
Run the base-path rewrite as the first step of serve:unsafe so any
deployment that serves the static bundle with that command works — not
just the FLAG_SERVE_CONNECT_UI entrypoint. This covers self-hosters who
run Connect UI as a standalone container (command = serve:unsafe) without
the server entrypoint, and removes the manual pre-step for them. The
entrypoint no longer needs a separate set-base-path call.
The rewrite runs for both FLAG_SERVE_CONNECT_UI and a standalone
serve:unsafe container; the manual step is only for uploading dist to a
static host/CDN.
The connect_link returned by POST /connect/sessions and .../reconnect is
the shareable "open Connect UI" link. It was built as connectUrl plus the
session token, ignoring any base path, so a self-hoster serving Connect
UI under a sub-path got a broken link even when the embedded iframe
worked. Build it via buildConnectUiSessionLink, which applies the base
path from NANGO_PUBLIC_CONNECT_URL (or NANGO_CONNECT_UI_BASE_PATH).
The rewrite kept a pristine .dist-template copy so it could be re-run
with a different base path in place. Every deployment starts from a
freshly built dist (ephemeral containers, deploy builds fresh), and the
base path is fixed per container via env vars, so that never happens.
Simplify to a one-shot placeholder replace.

Also move the pure resolveBasePath tests to a node test and split vitest
into browser and node projects so the script has real coverage.
Validate NANGO_CONNECT_UI_BASE_PATH in the ENVS schema so a malformed
value fails at startup instead of throwing when a connect session is
created. buildConnectUiSessionLink now takes the connect URL and base
path as arguments, and the controllers pass the server's validated envs
rather than the util reading process.env.

Also cross-reference the base-path contract between the util and the
connect-ui rewrite script, which can't share code across the package
boundary.
Extract the base-path source (override → connect URL path → root) into a
small helper with early returns instead of reassigning a `raw` variable,
and drop the TODO comment (tracked on the PR/ticket instead).
The browser project's include already scopes to src/**/*.test.tsx, but
exclude the node test glob explicitly (preserving vitest's defaults) so a
node script test can't be pulled into the chromium runner.
Deriving the base path from NANGO_PUBLIC_CONNECT_URL silently fell back to
root when the URL was set but unparseable, masking a misconfiguration.
Throw instead so it fails loudly at startup, consistent with the base
path character validation.
Drop NANGO_CONNECT_UI_BASE_PATH. The base path is by definition the path
of NANGO_PUBLIC_CONNECT_URL — the frontend SDK loads the Connect UI
iframe from that URL, so it must already include any sub-path. A separate
override could only duplicate or drift from it.

This also simplifies the session link: since the public URL already
includes the sub-path, buildConnectUiSessionLink just appends the session
token (the base-path normalization it did was only needed for the
override), and the controllers pass the validated envs value.
The startup rewrite edits files in dist in place, so a read-only root
filesystem would fail before serving.
Keep it, but out of the rewrite paragraph so it's easier to spot.
The session link is just NANGO_PUBLIC_CONNECT_URL + the session token,
and that URL already includes any sub-path, so master's inline
`new URL(`${connectUrl}?session_token=...`)` was already correct. Remove
the buildConnectUiSessionLink util and revert the two controllers.
A read-only root filesystem still works if dist is a writable volume or
tmpfs; only dist needs to be writable.
An empty tmpfs/volume mounted over dist shadows the image's prebuilt
assets, so the rewrite finds nothing. State the requirement (dist must be
writable at runtime) without prescribing a workaround that breaks.
Replace the placeholder-base rewrite with vite base './' and a router
basepath derived from document.baseURI at load: assets resolve
relative to the document URL, so the same prebuilt bundle serves from
any base path with no startup rewrite, no writable dist, and no CI
step. URL shapes are unchanged. An inline guard in index.html
self-heals a missing trailing slash at the base root, and serve:unsafe
gains -s so in-app refreshes at deep routes keep working.
Relative asset paths only resolve when the document path ends with a
slash. Normalize everywhere Nango produces a Connect UI document URL:
the frontend SDK iframe, the dashboard preview iframe, and the
server-generated connect_link (new buildConnectUiSessionLink helper).
The CSP sources get the same treatment since CSP path matching is
exact without a trailing slash.
The telemetry CORS check and the dashboard preview message listener
compared against NANGO_PUBLIC_CONNECT_URL verbatim. Browser origins
never contain a path, so both silently failed once the URL included
a sub-path.
@linear-code

linear-code Bot commented Jul 16, 2026

Copy link
Copy Markdown

NAN-6242

@github-actions

github-actions Bot commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Preview Deploy

Status URL Deploy Logs Last Updated
✅ Ready Preview URL Deploy Logs 16 Jul 2026, 13:02 UTC

@mintlify

mintlify Bot commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated (UTC)
nango 🟢 Ready View Preview Jul 16, 2026, 9:30 AM

💡 Tip: Enable Workflows to automatically generate PRs for you.

@mintlify

mintlify Bot commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated (UTC)
nango 🟡 Building Jul 16, 2026, 9:28 AM

💡 Tip: Enable Workflows to automatically generate PRs for you.

@cubic-dev-ai cubic-dev-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.

No issues found across 19 files

Confidence score: 5/5

  • Automated review surfaced no issues in the provided summaries.
  • No files require special attention.

Re-trigger cubic

macko911 added 4 commits July 16, 2026 14:41
Replace the route-allowlist guard with an onerror hook on the entry
script: retry with a trailing slash only when the asset load actually
failed. No route names to keep in sync with index.html, and documents
served at real routes are never misredirected. Vite drops extra
attributes when rewriting the entry script tag, so a small build
plugin re-attaches the hook.
Drop the redundant CORS comment; explain why the webapp preview
normalization stays inline (@nangohq/utils reads process.env on
import and is not a webapp dependency).

@cubic-dev-ai cubic-dev-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.

6 issues found and verified against the latest diff

Confidence score: 3/5

  • The highest-risk path is deep-link refresh handling across packages/connect-ui/src/lib/routes.ts, packages/connect-ui/vite.config.ts, and packages/connect-ui/index.html: trailing-slash URLs like /nango/connect/integrations/ can resolve under the wrong base and load no entry module, so users may see the root page or a blank UI on refresh. Align route normalization and asset base/retry behavior for already-trailing-slash deep routes before merging.
  • In packages/server/lib/middleware/security.ts, removing slashless Connect UI iframe sources can block valid existing embed URLs before client-side self-healing runs, causing Connect UI not to render in host apps. Keep both configured slashless and normalized prefix entries in frameSrc to preserve compatibility.
  • In packages/utils/lib/connect-ui.ts, NANGO_PUBLIC_CONNECT_URL values with ?/# are treated as part of the base path, so generated session links and CSP base sources can inherit unintended URL state. Strip query/fragment components when deriving the Connect UI base before merging.
  • docs/guides/platform/self-hosting.mdx currently overstates slashless recovery coverage; as implemented it only recovers after index.html is served and an entry asset fails, not initial document HTTP failures. Update the guide wording so operators set correct expectations and troubleshoot the right layer.
Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="docs/guides/platform/self-hosting.mdx">

<violation number="1" location="docs/guides/platform/self-hosting.mdx:223">
P2: Slashless recovery only works after `index.html` has been served and its relative entry asset fails; it cannot recover an HTTP failure for the initial document itself. Please describe this as entry-asset recovery and retain the requirement that the host serve the base URL/fallback.</violation>
</file>

<file name="packages/utils/lib/connect-ui.ts">

<violation number="1" location="packages/utils/lib/connect-ui.ts:9">
P2: A `NANGO_PUBLIC_CONNECT_URL` containing `?` or `#` is treated as part of the Connect UI base, so generated session links retain unrelated URL state and the CSP base source is not limited to the configured path. Clearing `url.search` and `url.hash` before normalizing the pathname keeps the override as a base URL only.

(Based on your team's feedback about stripping query and fragment components from the Connect UI base override.) [FEEDBACK_USED].</violation>
</file>

<file name="packages/connect-ui/src/lib/routes.ts">

<violation number="1" location="packages/connect-ui/src/lib/routes.ts:40">
P2: A deep-route refresh with a trailing slash is mounted under the wrong basepath: `/nango/connect/integrations/` yields `/nango/connect/integrations`, so the router can render the root page rather than `IntegrationsList`. Base-path derivation needs to canonicalize or otherwise distinguish trailing-slash route suffixes before creating the router.</violation>
</file>

<file name="packages/connect-ui/index.html">

<violation number="1" location="packages/connect-ui/index.html:13">
P2: An entry-module failure on a supported deep route such as `/nango/connect/integrations` is rewritten to `/nango/connect/integrations/` because this condition does not exclude known routes. That trailing-slash URL resolves the relative assets under `integrations/assets`, so recovery can turn an asset failure into a persistent blank page; the route allowlist should be applied here.</violation>
</file>

<file name="packages/connect-ui/vite.config.ts">

<violation number="1" location="packages/connect-ui/vite.config.ts:30">
P2: Refreshing a trailing-slash deep URL such as `/nango/connect/integrations/` leaves the UI blank: `base: './'` resolves assets beneath the route directory, and the retry handler does not normalize an already-trailing-slash path. Normalizing trailing-slash route URLs (or using an asset base independent of the current route) would avoid this failure.</violation>
</file>

<file name="packages/server/lib/middleware/security.ts">

<violation number="1" location="packages/server/lib/middleware/security.ts:40">
P2: Slashless Connect UI iframe URLs are now blocked before the inline trailing-slash guard can self-heal them. Keeping both the configured slashless source and the normalized prefix source in `frameSrc` would preserve compatibility with older SDKs while still allowing the subpath's assets and routes.</violation>
</file>

Reply with feedback, questions, or to request a fix.

Re-trigger cubic


Your reverse proxy must strip the base path prefix before forwarding to Connect UI: a request for `/nango/connect/assets/app.js` must reach Connect UI as `/assets/app.js`.

URLs loading Connect UI at a sub-path must end with a trailing slash (`…/connect/`) — the Nango SDK and the generated links produce this automatically, and Connect UI itself retries with a trailing slash if the initial load fails.

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.

P2: Slashless recovery only works after index.html has been served and its relative entry asset fails; it cannot recover an HTTP failure for the initial document itself. Please describe this as entry-asset recovery and retain the requirement that the host serve the base URL/fallback.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At docs/guides/platform/self-hosting.mdx, line 223:

<comment>Slashless recovery only works after `index.html` has been served and its relative entry asset fails; it cannot recover an HTTP failure for the initial document itself. Please describe this as entry-asset recovery and retain the requirement that the host serve the base URL/fallback.</comment>

<file context>
@@ -208,6 +208,22 @@ Nango Connect is available by default at `http://localhost:3009`.
+
+Your reverse proxy must strip the base path prefix before forwarding to Connect UI: a request for `/nango/connect/assets/app.js` must reach Connect UI as `/assets/app.js`.
+
+URLs loading Connect UI at a sub-path must end with a trailing slash (`…/connect/`) — the Nango SDK and the generated links produce this automatically, and Connect UI itself retries with a trailing slash if the initial load fails.
+
+If you serve Connect UI's built `dist` from your own static host, enable SPA fallback (rewrite unknown paths to `index.html`) so in-app refreshes work.
</file context>
Suggested change
URLs loading Connect UI at a sub-path must end with a trailing slash (`…/connect/`) — the Nango SDK and the generated links produce this automatically, and Connect UI itself retries with a trailing slash if the initial load fails.
URLs loading Connect UI at a sub-path should end with a trailing slash (`…/connect/`) — the Nango SDK and the generated links produce this automatically. The built UI can recover when the slashless document is served but its relative entry asset fails; otherwise the host must serve the base URL and provide the SPA fallback described below.

* or without one, so normalize before using it as a document URL.
*/
export function connectUrlAsDocumentBase(raw: string = connectUrl): URL {
const url = new URL(raw);

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.

P2: A NANGO_PUBLIC_CONNECT_URL containing ? or # is treated as part of the Connect UI base, so generated session links retain unrelated URL state and the CSP base source is not limited to the configured path. Clearing url.search and url.hash before normalizing the pathname keeps the override as a base URL only.

(Based on your team's feedback about stripping query and fragment components from the Connect UI base override.) .

View Feedback

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/utils/lib/connect-ui.ts, line 9:

<comment>A `NANGO_PUBLIC_CONNECT_URL` containing `?` or `#` is treated as part of the Connect UI base, so generated session links retain unrelated URL state and the CSP base source is not limited to the configured path. Clearing `url.search` and `url.hash` before normalizing the pathname keeps the override as a base URL only.

(Based on your team's feedback about stripping query and fragment components from the Connect UI base override.) .</comment>

<file context>
@@ -0,0 +1,20 @@
+ * or without one, so normalize before using it as a document URL.
+ */
+export function connectUrlAsDocumentBase(raw: string = connectUrl): URL {
+    const url = new URL(raw);
+    if (!url.pathname.endsWith('/')) {
+        url.pathname += '/';
</file context>

// the base root ('{base}/') or at a depth-1 route under it ('{base}/integrations'), and no route ends
// with a trailing slash, so resolving '.' against document.baseURI yields the base path.
export function basepathFromDocumentBaseURI(baseURI: string): string | undefined {
const pathname = new URL('.', baseURI).pathname;

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.

P2: A deep-route refresh with a trailing slash is mounted under the wrong basepath: /nango/connect/integrations/ yields /nango/connect/integrations, so the router can render the root page rather than IntegrationsList. Base-path derivation needs to canonicalize or otherwise distinguish trailing-slash route suffixes before creating the router.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/connect-ui/src/lib/routes.ts, line 40:

<comment>A deep-route refresh with a trailing slash is mounted under the wrong basepath: `/nango/connect/integrations/` yields `/nango/connect/integrations`, so the router can render the root page rather than `IntegrationsList`. Base-path derivation needs to canonicalize or otherwise distinguish trailing-slash route suffixes before creating the router.</comment>

<file context>
@@ -31,4 +31,15 @@ export const goRouter = createRoute({
+// the base root ('{base}/') or at a depth-1 route under it ('{base}/integrations'), and no route ends
+// with a trailing slash, so resolving '.' against document.baseURI yields the base path.
+export function basepathFromDocumentBaseURI(baseURI: string): string | undefined {
+    const pathname = new URL('.', baseURI).pathname;
+    // TanStack Router wants the basepath without a trailing slash; root stays default.
+    return pathname === '/' ? undefined : pathname.replace(/\/$/, '');
</file context>

// served at real routes (deep-route refresh via SPA fallback) are never misredirected.
window.__nangoBasePathRetry = function () {
var path = location.pathname;
if (!path.endsWith('/')) {

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.

P2: An entry-module failure on a supported deep route such as /nango/connect/integrations is rewritten to /nango/connect/integrations/ because this condition does not exclude known routes. That trailing-slash URL resolves the relative assets under integrations/assets, so recovery can turn an asset failure into a persistent blank page; the route allowlist should be applied here.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/connect-ui/index.html, line 13:

<comment>An entry-module failure on a supported deep route such as `/nango/connect/integrations` is rewritten to `/nango/connect/integrations/` because this condition does not exclude known routes. That trailing-slash URL resolves the relative assets under `integrations/assets`, so recovery can turn an asset failure into a persistent blank page; the route allowlist should be applied here.</comment>

<file context>
@@ -2,6 +2,19 @@
+            // served at real routes (deep-route refresh via SPA fallback) are never misredirected.
+            window.__nangoBasePathRetry = function () {
+                var path = location.pathname;
+                if (!path.endsWith('/')) {
+                    location.replace(path + '/' + location.search + location.hash);
+                }
</file context>

// inline script in index.html) and all routes staying depth-1 without trailing slashes — from a
// deep-route document ('{base}/integrations'), relative assets resolve one level up, back to the
// base. The dev server stays at root.
base: command === 'build' ? './' : '/',

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.

P2: Refreshing a trailing-slash deep URL such as /nango/connect/integrations/ leaves the UI blank: base: './' resolves assets beneath the route directory, and the retry handler does not normalize an already-trailing-slash path. Normalizing trailing-slash route URLs (or using an asset base independent of the current route) would avoid this failure.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/connect-ui/vite.config.ts, line 30:

<comment>Refreshing a trailing-slash deep URL such as `/nango/connect/integrations/` leaves the UI blank: `base: './'` resolves assets beneath the route directory, and the retry handler does not normalize an already-trailing-slash path. Normalizing trailing-slash route URLs (or using an asset base independent of the current route) would avoid this failure.</comment>

<file context>
@@ -5,11 +5,30 @@ import react from '@vitejs/plugin-react-swc';
+    // inline script in index.html) and all routes staying depth-1 without trailing slashes — from a
+    // deep-route document ('{base}/integrations'), relative assets resolve one level up, back to the
+    // base. The dev server stays at root.
+    base: command === 'build' ? './' : '/',
+    plugins: [react(), svgr(), tailwindcss(), basePathRetry()] as UserConfig['plugins'],
     resolve: {
</file context>

hostApi,
hostWs.href,
connectUrl,
connectUrlCspSource,

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.

P2: Slashless Connect UI iframe URLs are now blocked before the inline trailing-slash guard can self-heal them. Keeping both the configured slashless source and the normalized prefix source in frameSrc would preserve compatibility with older SDKs while still allowing the subpath's assets and routes.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/server/lib/middleware/security.ts, line 40:

<comment>Slashless Connect UI iframe URLs are now blocked before the inline trailing-slash guard can self-heal them. Keeping both the configured slashless source and the normalized prefix source in `frameSrc` would preserve compatibility with older SDKs while still allowing the subpath's assets and routes.</comment>

<file context>
@@ -33,15 +37,23 @@ export function securityMiddlewares(): RequestHandler[] {
                     hostApi,
                     hostWs.href,
-                    connectUrl,
+                    connectUrlCspSource,
                     'https://*.posthog.com',
                     'https://*.stripe.com',
</file context>

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