Closed jamesst20 closed 2 months ago
Please provide a smaller reproduction. There are a ton of things going on here.
As an initial guess without looking at any details, are you running the SSR output through an HTML minifier and/or stripping comments? Server-rendered comments are necessary in order to be able to properly hydrate in the browser.
Please provide a smaller reproduction. There are a ton of things going on here.
As an initial guess without looking at any details, are you running the SSR output through an HTML minifier and/or stripping comments? Server-rendered comments are necessary in order to be able to properly hydrate in the browser.
Thanks @Conduitry for the quick reply. How do we build a smaller reproductible exemple with SSR? Got any templates for this?
What I can do is give you the output though. Comments don't appear to be stripped
source_ssr.html.txt source_full_response.html.txt
SSR output
Browser output
SSR disabled output
Inertia expects an empty body with only a <div id=app that includes a data-page attribute for the router information. Based on this it runs Svelte app.
How do we build a smaller reproductible exemple with SSR? Got any templates for this?
You can use npm create svelte@latest
, then select "skeleton project" and the Svelte 5 option, then add the Svelte components that reproduce this (import them into +page.svelte
)
@dummdidumm @Conduitry Here is a minimal reproduction bug
1. Extract zip
2. npm install
3. npm run dev
You will see it works just fine. Now upgrade Svelte and it's broken
Edit: Updated first post too
I started exploring this a bit but got stuck and had to leave the desk. It seems that it's trying to hydrate an empty text node but that's the only thing i discovered so far.
So trying to look into this, where is your HTML generated for SSR? I ask because it's generating HTML without a <body>
element
This will completely break Svelte 5 as it uses opening and closing comment markers to mark where hydration starts and ends – but because you didn't put in a <body>
the browser puts it in for you – after the first hydration marker.
Update: I think your server.js
is wrong, and the line should be
const html = template
.replace(`<!--app-head-->`, rendered.head?.[0] ?? "")
- .replace(templateBody, rendered.body ?? "");
+ .replace(templateBody, `<body>${rendered.body ?? ""}</body>`);
There's still another issue, looking into that too.
So the culprit here looks to be the wonky stuff that svelte-inertia
is doing, which breaks with Svelte 5:
https://github.com/inertiajs/inertia/blob/master/packages/svelte/src/lib/components/Render.svelte
In fact, svelte-inertia
seems to be doing lots odd things that simply won't work with Svelte 5, it would be good if that package was updated to properly support Svelte 5. It looks like it doesn't even process the same components during SSR as it does during hydration:
https://github.com/inertiajs/inertia/blob/master/packages/svelte/src/lib/createInertiaApp.ts#L31-L90
Which means that our special comment markers will be missing from the SSR output – meaning that we incorrectly try and match the current hydration DOM node up to the wrong piece of content (as we're expecting comments to be there for blocks, but instead we get actual elements instead).
I think there is still an issue with Svelte 5 here too though as at best we should be capturing a hydration mismatch issue here. I wonder if we this sequence of blocks is enough to break the compiler:
{#if store.component}
{#key key}
<svelte:component this={component} {...props}>
{#each childComponents as child, index (component && component.length === index ? store.key : null)}
<svelte:self {...child} />
{/each}
</svelte:component>
{/key}
{/if}
Update 2: digging more into to above, it seems that the if
block is the culprit for this error:
<!-- {#if store.component} -->
{#key key}
<svelte:component this={component} {...props}>
{#each childComponents as child, index (component && component.length === index ? store.key : null)}
<svelte:self {...child} />
{/each}
</svelte:component>
{/key}
<!-- {/if} -->
Making that change fixes the issue entirely. The HTML output between the two is also interesting:
<!DOCTYPE html>
<html lang="en">
<head>
<script type="module" src="/@vite/client"></script>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite + Svelte + TS</title>
<script type="module" src="/src/entry-client.ts"></script>
<!--[-->
<!--]-->
<title>Home - SSR Reproduction</title>
</head>
<!--[-->
<div
data-server-rendered="true"
id="app"
data-page='{"component":"Home","props":{"appName":"SSR Reproduction","users":[{"id":1,"name":"Test","email":"test@example.com"}]},"url":"http://localhost:5173/","version":"12345"}'
>
<!--[--><!----><!---->
<nav class="flex items-center space-x-6 bg-slate-800 px-10 py-6 text-white">
<div class="rounded-lg bg-slate-700 px-4 py-1">SSR Reproduction</div>
<a href="/" class="hover:underline">Home</a>
<a href="/users" class="hover:underline">Users</a>
<a href="/article" class="hover:underline">Article</a>
<a href="/form" class="hover:underline">Form</a>
<button type="button" class="hover:underline">Logout</button>
</nav>
<main class="px-10 py-8">
<!----><!--[--><!--[--><!----><!---->
<h1 class="text-3xl">Home</h1>
<p class="mt-6">
<a href="/article#far-down" class="text-blue-700 underline"
>Link to bottom of article page</a
>
</p>
<!----><!----><!--]--><!----><!--]--><!---->
</main>
<!----><!----><!--]--><!----><!---->
</div>
<!--]-->
</html>
With if
block removed:
<!DOCTYPE html>
<html lang="en">
<head>
<script type="module" src="/@vite/client"></script>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite + Svelte + TS</title>
<script type="module" src="/src/entry-client.ts"></script>
<!--[-->
<!--]-->
<title>Home - SSR Reproduction</title>
</head>
<!--[-->
<div
data-server-rendered="true"
id="app"
data-page='{"component":"Home","props":{"appName":"SSR Reproduction","users":[{"id":1,"name":"Test","email":"test@example.com"}]},"url":"http://localhost:5173/","version":"12345"}'
>
<!----><!---->
<nav class="flex items-center space-x-6 bg-slate-800 px-10 py-6 text-white">
<div class="rounded-lg bg-slate-700 px-4 py-1">SSR Reproduction</div>
<a href="/" class="hover:underline">Home</a>
<a href="/users" class="hover:underline">Users</a>
<a href="/article" class="hover:underline">Article</a>
<a href="/form" class="hover:underline">Form</a>
<button type="button" class="hover:underline">Logout</button>
</nav>
<main class="px-10 py-8">
<!----><!--[--><!----><!---->
<h1 class="text-3xl">Home</h1>
<p class="mt-6">
<a href="/article#far-down" class="text-blue-700 underline"
>Link to bottom of article page</a
>
</p>
<!----><!----><!----><!--]--><!---->
</main>
<!----><!----><!----><!---->
</div>
<!--]-->
</html>
So the culprit here looks to be the wonky stuff that
svelte-inertia
is doing, which breaks with Svelte 5:https://github.com/inertiajs/inertia/blob/master/packages/svelte/src/lib/components/Render.svelte
In fact,
svelte-inertia
seems to be doing lots odd things that simply won't work with Svelte 5, it would be good if that package was updated to properly support Svelte 5. It looks like it doesn't even process the same components during SSR as it does during hydration:https://github.com/inertiajs/inertia/blob/master/packages/svelte/src/lib/createInertiaApp.ts#L31-L90
Which means that our special comment markers will be missing from the SSR output – meaning that we incorrectly try and match the current hydration DOM node up to the wrong piece of content (as we're expecting comments to be there for blocks, but instead we get actual elements instead).
I think there is still an issue with Svelte 5 here too though as at best we should be capturing a hydration mismatch issue here. I wonder if we this sequence of blocks is enough to break the compiler:
{#if store.component} {#key key} <svelte:component this={component} {...props}> {#each childComponents as child, index (component && component.length === index ? store.key : null)} <svelte:self {...child} /> {/each} </svelte:component> {/key} {/if}
Update 2: digging more into to above, it seems that the
if
block is the culprit for this error:<!-- {#if store.component} --> {#key key} <svelte:component this={component} {...props}> {#each childComponents as child, index (component && component.length === index ? store.key : null)} <svelte:self {...child} /> {/each} </svelte:component> {/key} <!-- {/if} -->
Making that change fixes the issue entirely.
Thanks for the quick investigation @trueadm :)
My reproduction exemple use my own fork of Inertia because I have converted the components to be Svelte 5 so the proper source would be https://github.com/jamesst20/inertia/blob/main/packages/svelte/src/lib/components/Render.svelte
What should be done instead? I could investigate further why the component could be null, but the createInertiaApp(...) signature I believe expects null components to be valid I guess if only props update are expected and the router shouldn't act.
@jamesst20 Actually, I noticed that the above commenting out of the if block still hits a hydration mismatch, except you are not passing recover: false
to the hydrate
call in entry-client.ts
so the app just gets scrapped and rebuilt on the client. Looking into it more, it seems you're also setting the hydration target to be div#app
but the server rendered content starts outside of the this div
?
So I think the server.js replacement should be:
const html = template
.replace(`<!--app-head-->`, rendered.head?.[0] ?? "")
.replace('<!--app-body-->', rendered.body ?? "");
Then in your hbs
you need an <!--app-body-->
comment to replace it with.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite + Svelte + TS</title>
<script type="module" src="/src/entry-client.ts"></script>
<!--app-head-->
</head>
<body>
<div id="app" data-page='{{ page }}'><!--app-body--></div>
</body>
</html>
However, that doesn't seem to work and I can't tell why as the whole thing is wonky. It also seems like we also render another element with the id
of app
inside the <!--app-body-->
that comes from somewhere – which doesn't seem right either.
It's so hard to debug what's going on because of the odd way this project is setup. However, the target
you provide hydrate
must be an exclusive element with all the SSR content within that element. Part of the problem with this case is that this element isn't exclusive and there seems to be lots of odd things around that. If you can fix these issues, then it should make debugging the hydration failing cases easier.
Hi @trueadm I am facing this exact issue after sveltekit svelte 5.0.0-next.178 and with ssr w.r.t web components. This is the repro. You can find bundled web component in static folder
@jamesst20 Actually, I noticed that the above commenting out of the if block still hits a hydration mismatch, except you are not passing
recover: false
to thehydrate
call inentry-client.ts
so the app just gets scrapped and rebuilt on the client. Looking into it more, it seems you're also setting the hydration target to bediv#app
but the server rendered content starts outside of the thisdiv
?So I think the server.js replacement should be:
const html = template .replace(`<!--app-head-->`, rendered.head?.[0] ?? "") .replace('<!--app-body-->', rendered.body ?? "");
Then in your
hbs
you need an<!--app-body-->
comment to replace it with.<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <link rel="icon" type="image/svg+xml" href="/vite.svg" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Vite + Svelte + TS</title> <script type="module" src="/src/entry-client.ts"></script> <!--app-head--> </head> <body> <div id="app" data-page='{{ page }}'><!--app-body--></div> </body> </html>
However, that doesn't seem to work and I can't tell why as the whole thing is wonky. It also seems like we also render another element with the
id
ofapp
inside the<!--app-body-->
that comes from somewhere – which doesn't seem right either.It's so hard to debug what's going on because of the odd way this project is setup. However, the
target
you providehydrate
must be an exclusive element with all the SSR content within that element. Part of the problem with this case is that this element isn't exclusive and there seems to be lots of odd things around that. If you can fix these issues, then it should make debugging the hydration failing cases easier.
I'm really sorry about the reproduction exemple. It's very possible it is a little off as it is not a real world usage at all, I was required to provide a smaller reproduction exemple. A real world demo that is supposed to be accurate is https://github.com/jamesst20/inertia/tree/main/playgrounds/svelte if you check first post edits, I had given instructions on how to test it
I believe one of your question the answer lies here: https://github.com/jamesst20/inertia/blob/main/packages/svelte/src/lib/components/SSR.svelte#L13 and here https://github.com/jamesst20/inertia/blob/main/packages/svelte/src/lib/createInertiaApp.ts#L49
I don't know why Inertia works this way but the way it is meant to work is
<div id="app" data-page="...">
. That div is given by the backend itself.Hi @trueadm I am facing this exact issue after sveltekit svelte 5.0.0-next.178 and with ssr w.r.t web components. This is the repro. You can find bundled web component in static folder
So looking into this, and it appears the issue is you have a <style>
element as the first child of the custom-select
element? Svelte doesn't expect your custom element to have any children other than the ones it puts inside it, so this will break. If you remove the <style>
element you add in custom-comp.js
then everything works as expected.
Hi @trueadm I am facing this exact issue after sveltekit svelte 5.0.0-next.178 and with ssr w.r.t web components. This is the repro. You can find bundled web component in static folder
So looking into this, and it appears the issue is you have a
<style>
element as the first child of thecustom-select
element? Svelte doesn't expect your custom element to have any children other than the ones it puts inside it, so this will break. If you remove the<style>
element you add incustom-comp.js
then everything works as expected.
This feels like a different bug but a bug nonetheless...the custom element is not from svelte so this seems something we should probably address right if we want custom elements to work in general
This feels like a different bug but a bug nonetheless...the custom element is not from svelte so this seems something we should probably address right if we want custom elements to work in general
I think a new issue around this would be good then, as Svelte 5 is working as intended here. If someone mutates the DOM outside of Svelte's knowledge, then things are obviously going to break because we now create templates from their code. If they put a <style></style>
element in their Svelte template and then reference it in the custom element, then that too should work.
I'm really sorry about the reproduction exemple. It's very possible it is a little off as it is not a real world usage at all, I was required to provide a smaller reproduction exemple. A real world demo that is supposed to be accurate is https://github.com/jamesst20/inertia/tree/main/playgrounds/svelte if you check first post edits, I had given instructions on how to test it
I believe one of your question the answer lies here: https://github.com/jamesst20/inertia/blob/main/packages/svelte/src/lib/components/SSR.svelte#L13 and here https://github.com/jamesst20/inertia/blob/main/packages/svelte/src/lib/createInertiaApp.ts#L49
I don't know why Inertia works this way but the way it is meant to work is
- When SSR is disabled, the response is supposed to provide
<div id="app" data-page="...">
. That div is given by the backend itself.- When SSR is enabled, the response is supposed to be identical with an extra data-server-rendered="true". That div is given by the Svelte component "SSR" which render as a child the "App" component.
I was unable to get it working – sorry. Would it be possible for you to try without Inertia and using something like SvelteKit?
@trueadm
Not sure if this made that clear, but if I were to do
const html = template
.replace(`<!--app-head-->`, rendered.head?.[0] ?? "")
.replace('<!--app-body-->', rendered.body ?? "");
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite + Svelte + TS</title>
<script type="module" src="/src/entry-client.ts"></script>
<!--app-head-->
</head>
<body>
<div id="app" data-page='{{ page }}'><!--app-body--></div>
</body>
</html>
because the SSR renders the Svelte SSR component which already includes the <div id="app" ...
it would end up being
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite + Svelte + TS</title>
<script type="module" src="/src/entry-client.ts"></script>
<!--app-head-->
</head>
<body>
<div id="app" data-page='...'>
<div id="app" data-server-rendered="true" data-page='...'>
some html rendered content
</div>
</div>
</body>
</html>
this is why I am doing this in the reproduction exemple, I replace the whole body content
const rendered = await render(
await res.inertiaObject(component, { appName: "SSR Reproduction", users })
);
const templateBody = parse(template).querySelector("body").toString();
const html = template
.replace(`<!--app-head-->`, rendered.head?.[0] ?? "")
.replace(templateBody, rendered.body ?? "");
This feels like a different bug but a bug nonetheless...the custom element is not from svelte so this seems something we should probably address right if we want custom elements to work in general
I think a new issue around this would be good then, as Svelte 5 is working as intended here. If someone mutates the DOM outside of Svelte's knowledge, then things are obviously going to break because we now create templates from their code. If they put a
<style></style>
element in their Svelte template and then reference it in the custom element, then that too should work.
Shall I create a new issue?
This feels like a different bug but a bug nonetheless...the custom element is not from svelte so this seems something we should probably address right if we want custom elements to work in general
I think a new issue around this would be good then, as Svelte 5 is working as intended here. If someone mutates the DOM outside of Svelte's knowledge, then things are obviously going to break because we now create templates from their code. If they put a
<style></style>
element in their Svelte template and then reference it in the custom element, then that too should work.Shall I create a new issue?
Yes please 🙏🏻
Shall I create a new issue?
Please.
@jamesst20
Not sure if this made that clear, but if I were to do
So you can't do that. The content that Svelte renders, the <div id="app" ..
is also wrapped in hydration markers, which are indicators when to start hydrating. However, you're calling hydrate
with the reference to the div#app
element?! You can't hydrate an element that is part of the hydrated output, it needs to be completely isolated from it. This is likely the main culprit for why you're experiencing all these issues.
You should never have Svelte to render the HTML for the element that you intend to use as your entry point into your app.
This feels like a different bug but a bug nonetheless...the custom element is not from svelte so this seems something we should probably address right if we want custom elements to work in general
I think a new issue around this would be good then, as Svelte 5 is working as intended here. If someone mutates the DOM outside of Svelte's knowledge, then things are obviously going to break because we now create templates from their code. If they put a
<style></style>
element in their Svelte template and then reference it in the custom element, then that too should work.Shall I create a new issue?
Yes please 🙏🏻
Done
Shall I create a new issue?
Please.
@jamesst20
Not sure if this made that clear, but if I were to do
So you can't do that. The content that Svelte renders, the
<div id="app" ..
is also wrapped in hydration markers, which are indicators when to start hydrating. However, you're callinghydrate
with the reference to thediv#app
element?! You can't hydrate an element that is part of the hydrated output, it needs to be completely isolated from it. This is likely the main culprit for why you're experiencing all these issues.You should never have Svelte to render the HTML for the element that you intend to use as your entry point into your app.
I have removed Inertia as a dependency and written simplified code to mimic only necessary part ssr-reproduction-bug-simplified.zip
There is a boolean in server.js to toggle ON/OFF SSR but you can also use ssr=false/true as a get parameter.
I created a different html file for ssr and for normal rendering.
About your explanation, I am not really sure if it is something I don't see or understand or something you might have not seen about inertia. I hope the example clarifies it.
Edit: Ok I think I get your explanation I am investigating further now
@trueadm
You were right about the markers. Because the <div id="app" ...>
was rendered by a Svelte component during SSR but not when the response is generated by the backend, in the SSR scenarios there were markers outside that div and this is what caused the issue.
I wrote a fix here to ensure only the content of the div is rendered by Svelte https://github.com/jamesst20/inertia/commit/c8493ab9358fb520461940ef7f043987f0b39d17
It now renders properly, but I still get an hydratation error missmatch
App.svelte:19 [svelte] hydration_mismatch
Hydration failed because the initial UI does not match what was rendered on the server
By looking at the before/after, I can see there are markers at the end in the SSR response but not after hydratation. Do you have any idea? Breakpoint is before hydratation is called
Thats good, I can look into that tomorrow. Is the repro updated to reflect your changes?
Thats good, I can look into that tomorrow. Is the repro updated to reflect your changes?
This repo is reflecting yes:
(Have a compatible PHP version installed like 8.1)
1. git clone https://github.com/jamesst20/inertia.git
2. cd inertia
3. pnpm install
4. pnpm run build:all
5. cd playgrounds/svelte
6. cp .env.example .env
7. composer install
8. php artisan keys:generate
9. Terminal 1: php artisan serve
10. Terminal 2: pnpm run dev
11. Terminal 3: pnpm run build && php artisan inertia:start-ssr
12. Visit http://localhost:8000/
It really is odd, I tried emptying the layout to keep only <slot />
and fully emptying the Home.svelte and I still get the same warning about the mismatch. I added a debugger breakpoint just beforehydrate(...)
is called and copy pasted from chrome inspector the DOM to have a comparison of before/after.
Here is how it looks: Left before, Right after. (Both formatted with Prettier for readability)
The only difference I see is the Svelte comments (anchors)
Edit: You can set in both ssr.js/app.js progress: false
to the createInertiaApp({ ...here })
call to remove the added CSS and stuff to the <head>
@trueadm
Have you had the chance to take a look? Should I create a new issue and close this one as I believe it might be unrelated?
@jamesst20 I'm still digging into it. I'll let you know when I find out more :)
I get a ton of errors when trying to run php artisan keys:generate
from above. I'm using PHP 8.3.11 (cli) (built: Aug 27 2024 19:16:34) (NTS)
PHP Warning: require(/Users/trueadm/projects/inertia/playgrounds/svelte/vendor/autoload.php): Failed to open stream: No such file or directory in /Users/trueadm/projects/inertia/playgrounds/svelte/artisan on line 18
I get a ton of errors when trying to run
php artisan keys:generate
from above. I'm usingPHP 8.3.11 (cli) (built: Aug 27 2024 19:16:34) (NTS)
PHP Warning: require(/Users/trueadm/projects/inertia/playgrounds/svelte/vendor/autoload.php): Failed to open stream: No such file or directory in /Users/trueadm/projects/inertia/playgrounds/svelte/artisan on line 18
This is my bad, after step 6 you need to run composer install
if it says command not found you can also grab it here https://getcomposer.org/download/2.7.9/composer.phar and run instead php composer.phar install
@jamesst20 Thanks I got it working. When I remove the content from Layout.svelte
so its empty, why is the SSR content still including the content? Update: ah, I have to run one the scripts again.
So it seems like disabling hmr
fixes this issue:
svelte({
compilerOptions: {
hmr: false
}
}),
Not sure why hmr
is causing these issues though, I'll need to dig further.
With HMR turned on, in some places extra comments are added on the client so HMR can replace the components
Okay, so after digging into this for hours with @dummdidumm it turns out the issue is with laravel-vite-plugin
. It doesn't seem to be calling into the same Svelte compiler as the vite-plugin used for the client hydration – in fact it seems completely detached. This is where the issue is though – as the server components are compiled with hmr
always disabled and the client compiler runs with it enabled – and this is why you are having your mismatch.
Okay, so after digging into this for hours with @dummdidumm it turns out the issue is with
laravel-vite-plugin
. It doesn't seem to be calling into the same Svelte compiler as the vite-plugin used for the client hydration – in fact it seems completely detached. This is where the issue is though – as the server components are compiled withhmr
always disabled and the client compiler runs with it enabled – and this is why you are having your mismatch.
What should be done? I must admit I do not use Laravel in my own projects, I use Inertia with Ruby on Rails but I did my testing with the closest playground I had which was the Laravel one. Should we open an issue here? https://github.com/laravel/vite-plugin I wouldn't know what to say though
I honestly don't know enough about laravel-vite-plugin
either. It seems to not be using the @sveltejs/vite-plugin-svelte
plugin though, as if I put a console.log
inside the vite-plugin-svelte
in node_modules
and check for ssr
, then it's never run with true
. So I'm utterly confused as to how laravel-vite-plugin
is working.
Maybe it's this line that's setting hmr to false
for Vite, but only on the server? And because nothing is set on the client v-p-s sets it true there?
cc @dominikg
I have created an issue at the plugin repository just in case they can provide some insights about this issue as it doesn't appear Svelte is at fault? https://github.com/laravel/vite-plugin/issues/304
Maybe it's this line that's setting hmr to
false
for Vite, but only on the server? And because nothing is set on the client v-p-s sets it true there?cc @dominikg
vps sets hmr here
server
refers to the vite devserver here so there is no separate client.hmr
option. It is possible that the two plugins are incompatible right now because they both try to manage the hmr option for the user.
edit: vps does not set viteConfig.server.hmr, it just reads it. Maybe try running the setup with DEBUG=vite-plugin-svelte:*
to see what it uses exactly.
Closing this as I feel like there's a solution linked from https://github.com/laravel/vite-plugin/issues/304.
Edit: The described bug has been resolved, but there is a new one. It might be faster to simply skip to this comment: https://github.com/sveltejs/svelte/issues/13115#issuecomment-2330053369
Describe the bug
For some reasons, starting with Svelte 5 build 179 up to the last I have tested (next.241) I am getting this error when using SSR:
I have tried to pin point what in the DOM could be causing this but I was unsuccessful. Sometimes only wrapping something in a div trigger the error.
Reproduction
ssr-reproduction-bug.zip
Svelte 5 build 178 works perfectly. Svelte 5 build 179 we get a first render then the error Svelte 5 build 180+ blank page identical error
Logs
No response
System Info
Severity
blocking an upgrade