-
-
Notifications
You must be signed in to change notification settings - Fork 6.3k
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
Ability to append style
/script
elements inside of a shadow-root
#11855
Comments
is this feature in plan? |
There is an open PR that should address this issue #12206. I added it with higher priority to discuss the addition of a new option. Let's use this issue to track the feature. |
This is the workaround I used. Run this code in the connectedCallback: const styleTag = document.createElement("style");
styleTag.innerHTML = <link-to-css>;
this.shadowRoot.appendChild(styleTag); |
@RogierdeRuijter Can you expand on what you mean by the connectedCallback? Is the connectedCallback part of Vue? In my use case I'm not using web components but rather, I am mounting my app inside a shadow DOM to use that as a micro front end. |
@seahindeniz Do you have any updates on this issue? I feel that this is a crucial part of building Microfrontends with Vue. ShadowDOM is probably the best and least hacky way to encapsulate styles within micro-frontends. |
Hi @Oumar96, I totally agree with you and unfortunately no solution so far |
This comment was marked as spam.
This comment was marked as spam.
This comment was marked as spam.
This comment was marked as spam.
This comment was marked as spam.
This comment was marked as spam.
@gs-rpal Could you share the vite config file instead of the screenshot? |
+1, it would be great to have this option as some kind of vite's configuration or plugin. @gs-rpal please share that config 🙏 ❤️ |
The only workaround for this for now is to query the document for
const styleElements = document.documentElement.querySelectorAll('..... select all the <link>s and <style>s you want ...')
const sheets = Array.from(styleElements).map(el => el.sheet)
// Apply the desired style sheets to your custom element (via the shadow root):
this.shadowRoot.adoptedStyleSheets = [...sheets] If you cannot support const styleElements = document.documentElement.querySelectorAll('..... select all the links and styles you want ...')
const styleClones = Array.from(styleElements).map(el => el.cloneNode(true))
// Append clones of the desired style elements to your custom element (via the shadow root):
this.shadowRoot.prepend(...styleClones) Note
|
i would also like the element that are created to be not document.createElement but shadowroot.createElement... current way is copy whole internals to add a custom renderer in place... this would help with custom element registery where there is already a proposal for and a polyfill vue is just not made for webcomponents.. could be oke for mfe stuff if it fixes lot of these issues there many more on like not syncing the attributes if you use a custom element as a root its not ready for most of the newer browser api's sorry for the rant .. vue just needs to give webcomponents some serious love to be atlease useable for mfe stuff there currently only properly suited for spa things for singlar webcomponents since vue creates a vue app even if you make a button its about 800% slower then something like lit and 10 times more heavy on memory usage. |
This is the |
yea true |
FYI I’ve created a plugin that does just what I was looking for. Please try it out and let’s see whether it fits your use cases too. I’m pretty sure it’s very specific to my specific usage scenarios, so it’ll not fit anyone’s needs, but nothing stops us from using it as a starting point for a more adaptable plugin. Link here: |
@gs-rpal Any updates? Could you share the config file? |
Hello, this feature would be really great to support injection into Shadow roots! Is there already a nice workaround for this? |
Hi, probably my solution I linked above can help you with style injection into shadow roots: https://www.npmjs.com/package/vite-plugin-shadow-style |
Hello @hood thanks for your comment, but somehow for the dev mode it deactivates the shadow root and for build mode it gives me the warning:
A question to the "vite" team: is it possible to add a feature where it is possible to configure where to inject the styles? Right now only "head" is possible... vite/packages/vite/src/node/plugins/importAnalysisBuild.ts Lines 125 to 137 in bb79c9b
|
I also tried the solution from @gs-rpal but it only seems to work for dev mode. |
Hello guys, is there any progress for this feature? Thank you 🙏 |
worked for me! But need create Shadow Dom in Vue and after this code put in ShadowRoot your css code
|
I would need this feature so bad for my current project! |
Something else to consider is SSR Declarative Shadow DOM. Link tags will be hoisted to the head ignoring the template and waiting for client code to append the tags results in FOUC. |
Is there any updates on this? I ended up importing the styles using |
FYI it is impossible to add fonts and icons to shadow dom via The workaround is to use |
my currently working solution (both with in import { defineConfig } from "vite";
import cssInjectedByJsPlugin from "vite-plugin-css-injected-by-js";
export function defineConfig(() => {
const globalStylesIdentifier = "__myStylesIdentifier";
return {
plugins: [
cssInjectedByJsPlugin({
injectCode: (cssCode, _options) => {
return (
`try{` +
`var s = document.createElement('style');` +
`s.appendChild(document.createTextNode(${cssCode}));` +
`window.${globalStylesIdentifier} = window.${globalStylesIdentifier} || []; window.${globalStylesIdentifier}.push(s);` +
`}catch(e){` +
`console.error('${globalStylesIdentifier}', e);` +
`}`
);
},
dev: {
enableDev: true,
removeStyleCodeFunction: function removeStyleCode(_id) {
// The 'id' corresponds to the value of the 'data-vite-dev-id' attribute found on the style element. This attribute is visible even when the development mode of this plugin is not activated.
},
},
})
]
};
}; in const myShadowDomRoot = myDiv.shadowRoot;
if (myShadowDomRoot) {
const styles = window.__myStylesIdentifier || [];
while (styles.length) {
myShadowDomRoot.prepend(styles.pop() || "");
}
}
|
Description
Vue started to support mounting app inside of a shadow-root element within this PR.
With the following code, I can mount my Vue app under a shadow-root node
However, Vite loads style/script elements under the document head element because of the following function and since style elements are getting appended outside of the shadow-root scope, style definitions are not getting applied to HTML elements under the shadow-root.
vite/packages/vite/src/node/plugins/importAnalysisBuild.ts
Lines 63 to 119 in 356ddfe
As a use case, I need to mount a multiple apps to DOM under a shadow-root to avoid scope related collisions.
Suggested solution
Mentioned function can support different parent element to append style/script elements
Alternative
No response
Additional context
No response
Validations
The text was updated successfully, but these errors were encountered: