Hi, when I do new MyComponent({target: document.getElementById('someId')}) then the new component gets added to the element instead of replacing it.
I would love to have a way to replace the target, f.x new MyComponent({target: document.getElementById('someId'), replace: true}). This would give my users a better experience in situations where I'm adding Svelte components to content that they already see in their browser.
This conversation may still be relevant.
https://github.com/sveltejs/svelte/issues/537
function mountReplace(Component, options) {
const frag = document.createDocumentFragment();
const component = new Component({ ...options, target: frag });
options.target.parentNode.replaceChild(frag, options.target);
return component;
}
// usage
mountReplace(MyComponent, { target, data });
Also I didn't tested the latest version but the last time I tried I couldn't render the target content as a default <slot> in my component. I expect all children in a target DOM to become children of my component in a slotted spot.
This is a funny one :) I ran into this while trying to set up hot reloading for svelte.
The slot functionality relies on you being in the Svelte context. So you will need to wrap your component that contains the slot in a small svelte "app" and mount that.
That's not quite true — there is an API for slots, though I think we haven't got round to documenting it. You can do this:
const thing = new Thing({
target,
slots: {
default: someDomNodeOrFragment,
foo: someOtherDomNodeOrFragment
}
});
If you're compiling your components with hydratable: true and instantiating them with hydrate: true, it will reuse whatever DOM is currently in the target (and discard the rest). This is designed for rehydrating server-rendered components, so if that's what your goal is then it's what I'd recommend.
Otherwise, using a helper to clear out the existing DOM is the best way forward — it's not something we should add to Svelte itself, since it's extra code for something that most people won't need.
OK, that's super useful. Thanks for setting me straight. Sorry @constgen for poor information.
Closing this, as I don't think there's anything else that needs to happen. Comment if you think otherwise.
@Conduitry maybe add a note containing the mountReplace function above in the docs?
For future reference.
there is an API for slots
Seems like this API was for Svelte v2.
For v3, there is this open PR and this issue which mentions a workaround using the private API.
Most helpful comment
That's not quite true — there is an API for slots, though I think we haven't got round to documenting it. You can do this:
If you're compiling your components with
hydratable: trueand instantiating them withhydrate: true, it will reuse whatever DOM is currently in the target (and discard the rest). This is designed for rehydrating server-rendered components, so if that's what your goal is then it's what I'd recommend.Otherwise, using a helper to clear out the existing DOM is the best way forward — it's not something we should add to Svelte itself, since it's extra code for something that most people won't need.