Open
Description
Describe the problem
I am using svelte in several embedded webviews. I used to have to run a static file server before bundleStrategy: 'inline'
became available yesterday.
Normally (if we click this html file) the url will start with file://
, and everything works fine.
But In the webview implementation I use the url is a data url, and hydration always fails because of:
Uncaught TypeError: Failed to construct 'URL': Invalid URL
at data:text/html;chars…8L2h0bWw+Cg==:16:13
In another case, I want to parse metadata from an url using an iframe, but sveltekit apps always fail to hydrate because of a similar error:
Uncaught TypeError: Failed to construct 'URL': Invalid URL
at about:blank:16:13
Describe the proposed solution
Sveltekit always generates
<body data-sveltekit-preload-data="hover">
<div style="display: contents">
<script>
{
__sveltekit_1bknoa9 = {
base: new URL('.', location).pathname.slice(0, -1)
};
where new URL('.', location)
will fail when location.protocol
is data://
or about://
Alternatives considered
No response
Importance
would make my life easier
Additional Information
No response
Activity
[-]Handle cases when location.protocal is `about:` or `data:`[/-][+]Handle cases when location.protocol is `about:` or `data:`[/+]CNSeniorious000 commentedon Dec 23, 2024
kit/packages/kit/src/runtime/server/page/render.js
Lines 103 to 113 in 64c8e04
An ugly fix would be
eltigerchino commentedon Dec 23, 2024
You are welcome to open a pull request. Are there any other protocols we need to consider? Maybe we can create a set and search that.
CNSeniorious000 commentedon Dec 23, 2024
I think maybe
ftp:
? But it doesn't disrupt the current implementation. The only issues seem to arise withdata:
andabout:
.eltigerchino commentedon Jan 10, 2025
Did some investigation and there seems to be two ways of embedding SvelteKit through HTML text:
1. iframe srcdoc="..."
The document will have an embedded URL of
about:srcdoc
which is an invalid URL base.2. iframe src="data:text/html;charset=utf-8,..."
The document will have an embedded URL of
data:text/html...
which is an invalid URL base.Overall, there's a number of changes we need to make to avoid the "invalid base URL" error when constructing a new URL object to improve embedding SvelteKit apps as HTML text.
kit/packages/kit/src/runtime/server/page/render.js
Line 105 in 5b667e4
kit/packages/kit/src/runtime/server/page/render.js
Line 112 in 5b667e4
kit/packages/kit/src/runtime/client/utils.js
Lines 15 to 22 in 5b667e4
kit/packages/kit/src/runtime/client/utils.js
Line 132 in 5b667e4
kit/packages/kit/src/runtime/client/client.js
Line 1854 in 5b667e4
kit/packages/kit/src/runtime/client/client.js
Line 2504 in 5b667e4
cc: @kran6a
Also, when using a hash router, it's possible for the page to infinitely refresh due to the embedded URL pathname not passing any of the conditions below (#13287):
kit/packages/kit/src/runtime/client/utils.js
Lines 313 to 324 in 5b667e4
Fortunately, we can check if
location.url.origin === 'null'
to detect non-http/https URLs or if thekit.config.embedded
option is set and perhaps handle these situations more gracefully.kran6a commentedon Jan 20, 2025
I applied this patch on my node_modules and it works for my use-case. There are no invalid base URL errors and no infinite reloads.
Absolute links work, relative links won't ever work because I am using an iframe with srcdoc which makes relative URL take the parent base.
One strange thing I noticed that also broke when migrating widgets from raw svelte (bundling to a single .js file then inlining it into an HTML shell) to sveltekit is that previously I injected some classes into the iframe from the host website via
These classes use runes and this approach worked on svelte but reactivity broke after transitioning to sveltekit.
Importing the classes from the widget code fixes reactivity but the point of injecting those classes is that widgets don't need to bundle them to reduce their size, dependencies and maintenance as they all will use the most recent version of those classes.
I am not attempting to achieve cross-document reactivity, classes are instanced and meant to be reactive only within the iframe.
I am a bit puzzled on why this does not work. The class state is updated correctly and if you trigger a reload somehow (e.g: navigating to another route and then back) you can see the updated state correctly but reactivity is still nonexistant.
data:
andabout:
protocols better #13490