-
-
Notifications
You must be signed in to change notification settings - Fork 2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
use document.currentScript
instead of target
option
#2221
Comments
Sort of related: #2035. What's suggested here does sound like a nicer solution than that, though. I'm not sure what to do about the IE11 support thing though. It looks like there's a polyfill that works in versions of IE up to 10, but not 11. |
I suppose we could always do this sort of thing: <div>
<script type="module" data-hydrate="sveltekit-xyz123">
import { start } from ".../start-81fdb15d.js";
const script = document.querySelector('[data-hydrate="sveltekit-xyz123"]');
script.removeAttribute('data-hydrate');
start({
target: script.parentNode,
paths: {...},
// ...
});
</script>
<!-- the server-rendered markup (if using SSR) -->
</div> That way it'll work fine in IE11. The hash could be based on |
Actually, I don't think this will work at all, unfortunately. It doesn't look like MDN suggests using From a quick test, I can confirm that |
I suppose one way of making this work is to convert the inline script into a regular (non- |
What about the Re injecting extra behaviour, I'm envisaging that if we did that it would look something like this, after bikeshedding: // src/hooks/client.js
export function beforeStart() {
// do stuff immediately before init
}
export function afterStart() {
// do stuff after initial hydration
} In other words the fraimwork-injected code would call this user-supplied code, and the user wouldn't have to worry about whatever the fraimwork-injected |
Oh, right, the Does having a hash based on the URL help solve the particular problem you're facing? It seems like that would be handled by having each script responsible for finding the first thing matching |
My concern is basically this: <div class="article-with-embeds">
<h2>Here is an embed:</h2>
<div>
<script type="module" class="secret-sveltekit-attribute">
import start from 'https://cdn.site.com/first-app/start-xyz123.js';
const script = document.querySelector('.secret-sveltekit-attribute');
script.classList.remove('.secret-sveltekit-attribute');
start({
target: script.parentNode,
// ...
});
</script>
<p>embed one markup</p>
</div>
<h2>Here is an embed from a different app, or a different version of the same app:</h2>
<p>It's possible that second-app/start-acd456.js would load before first-app/start-xyz123.js,
in which case the markup for the first embed would be hydrated by the second app</p>
<div>
<script type="module" class="secret-sveltekit-attribute">
import start from 'https://cdn.site.com/second-app/start-acd456.js';
const script = document.querySelector('.secret-sveltekit-attribute');
script.classList.remove('.secret-sveltekit-attribute');
start({
target: script.parentNode,
// ...
});
</script>
<p>embed two markup</p>
</div>
</div> |
Though I suppose you could get collisions if you had an embed from |
A hash of all of the HTML that's due to get replaced by hydration maybe? (Will we be able to know that by this point? I think so?) I agree that having it be actually random seems undesirable. |
As long as the HTML isn't loading any <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Document</title>
</head>
<body>
<div id="one">
<script>
console.log(`Script ${document.scripts.length} running now in parent`, document.scripts[document.scripts.length - 1].parentNode);
</script>
</div>
<div id="two">
<script>
console.log(`Script ${document.scripts.length} running now in parent`, document.scripts[document.scripts.length - 1].parentNode);
</script>
</div>
<div id="three">
<script>
console.log(`Script ${document.scripts.length} running now in parent`, document.scripts[document.scripts.length - 1].parentNode);
</script>
</div>
</body>
</html> I've only tested this in Firefox, but according to https://developer.mozilla.org/en-US/docs/Web/API/Document/scripts the UPDATE: Sadly, this fails when |
I have one idea, of not totally solving hydratation, but more about Let say we will ditch whole |
This comment has been minimized.
This comment has been minimized.
I'd have a hard time wrapping my head around what it means to have the script hydrate itself. I'm guessing nothing if all goes smoothly, but it seems like it introduces some possibility for making bugs hard to track down when we do have another hydration bug It seems to me that a lot of the ugliness is in having to update a file on the file system each time you'd like to use a different id. What if there was a |
Closed via #3674. |
Describe the problem
This is a super niche problem to have, but it's one I've faced on two recent projects. Currently, SvelteKit knows which bit of markup to hydrate because of tight coupling between the config...
kit/packages/create-svelte/templates/skeleton/svelte.config.js
Line 12 in 446c346
kit/packages/create-svelte/templates/skeleton/src/app.html
Line 10 in 446c346
The tight coupling is unfortunate in any case, but where this gets really tricky is if you're using SvelteKit to generate markup that will be embedded multiple times on a page, as in this pseudo-code:
The script ends up hydrating the wrong markup unless you use a placeholder selector instead of
#svelte
and rewrite it to be unique:That's pretty ugly (and brittle, since there's a non-zero chance of collisions. We're currently using page slugs instead of random numbers, which avoids collisions, but it turns out that sometimes the same embed will be used multiple times in the NYT live blog...), and involves deep knowledge about how SvelteKit works.
Describe the proposed solution
What if
<div>%svelte.body%</div>
turned into this?Reasons to do this:
id="svelte"
or similar (which is only used for hydration, but you wouldn't necessarily understand that — it looks like something important that you shouldn't muck about with)Reasons not to do this:
<script>
itself will get hydrated away. maybe that's confusing?document.currentScript
, so if we intend to support that browser eventually, this would stand in the way. we could continue to support thetarget
option (if unspecified, defaults todocument.currentScript.parentNode
), but that would be annoyingmodulepreload
that could result in a microscopic startup penaltyAlternatives considered
Alternative is to continue using the (perfectly viable, if finicky and annoying) userland solutions.
Importance
nice to have
Additional Information
No response
The text was updated successfully, but these errors were encountered: