{"id":12575,"library":"vue-shadow-dom","title":"Vue Shadow DOM Integration","description":"vue-shadow-dom is a JavaScript library providing robust Shadow DOM support for Vue 3 applications, currently stable at version 4.2.0. It allows developers to leverage the browser's native Shadow DOM capabilities directly within Vue components, enabling strict encapsulation of styles and markup. The library achieves this through the provision of a Vue plugin, a `v-shadow` directive, and dedicated `<shadow-root>` and `<shadow-style>` components. While there isn't a stated fixed release cadence, updates tend to align with major Vue ecosystem changes or feature enhancements. A key differentiator is its direct, declarative API for Shadow DOM usage, avoiding complex manual DOM manipulations, and its comprehensive support for various module environments including ESM, CommonJS, and UMD builds, catering to both bundler-driven and browser-only setups. Notably, versions 2.0 and above are specifically designed for Vue 3, while v1.x targets Vue 2.","status":"active","version":"4.2.0","language":"javascript","source_language":"en","source_url":"https://github.com/2A5F/shadow","tags":["javascript","vue","vue-shadow-dom","shadow-dom","vue shadow dom","shadow dom","vue-component","vue-components","vue component","typescript"],"install":[{"cmd":"npm install vue-shadow-dom","lang":"bash","label":"npm"},{"cmd":"yarn add vue-shadow-dom","lang":"bash","label":"yarn"},{"cmd":"pnpm add vue-shadow-dom","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Peer dependency, required for Vue 3 applications (>=v2.0 of this library).","package":"vue","optional":false}],"imports":[{"note":"This is the default export representing the Vue plugin instance. For CommonJS environments, `const shadow = require('vue-shadow-dom')` can be used directly or specific CJS build paths like `'vue-shadow-dom/dist/shadow.cjs.cjs'`.","wrong":"import { shadow } from 'vue-shadow-dom'","symbol":"shadow","correct":"import shadow from 'vue-shadow-dom'"},{"note":"Used for TypeScript users to type the exposed `shadow_root` property when accessing the native ShadowRoot instance from a `<shadow-root>` component ref.","symbol":"ShadowRootExpose","correct":"import type { ShadowRootExpose } from 'vue-shadow-dom'"}],"quickstart":{"code":"import { createApp, ref, defineComponent } from 'vue';\nimport shadow, { type ShadowRootExpose } from 'vue-shadow-dom';\n\nconst MyShadowComponent = defineComponent({\n  template: `\n    <div style=\"border: 1px solid blue; padding: 10px; margin: 20px;\">\n      <h2>Component Host</h2>\n      <p>Content outside the shadow root. Styles here will leak unless encapsulated.</p>\n      <shadow-root ref=\"shadowRef\" tag=\"section\" abstract>\n        <template #default>\n          <shadow-style>\n            p { color: green; font-weight: bold; }\n            h3 { color: darkred; }\n            button { background-color: lightblue; padding: 8px; border: none; cursor: pointer; }\n          </shadow-style>\n          <h3>Shadow Root Content</h3>\n          <p>This paragraph should be green and bold inside the shadow DOM.</p>\n          <button @click=\"logShadowRoot\">Log Shadow Root</button>\n        </template>\n      </shadow-root>\n      <p>This paragraph is outside the shadow root.</p>\n    </div>\n  `,\n  setup() {\n    const shadowRef = ref<ShadowRootExpose | null>(null);\n\n    const logShadowRoot = () => {\n      if (shadowRef.value && shadowRef.value.shadow_root) {\n        console.log('Shadow Root Instance:', shadowRef.value.shadow_root);\n        // You can interact with the native ShadowRoot object directly\n        const pElement = shadowRef.value.shadow_root.querySelector('p');\n        if (pElement) {\n          console.log('Paragraph inside shadow root:', pElement.textContent);\n        }\n      } else {\n        console.warn('ShadowRoot instance not available yet.');\n      }\n    };\n\n    return { shadowRef, logShadowRoot };\n  },\n});\n\nconst app = createApp(MyShadowComponent);\napp.use(shadow);\napp.mount('#app');\n\n// To run this, you would typically have an index.html like:\n// <div id=\"app\"></div>","lang":"typescript","description":"Demonstrates initializing the `vue-shadow-dom` plugin, using the `<shadow-root>` component with custom tag and abstract prop, applying encapsulated styles with `<shadow-style>`, and accessing the native ShadowRoot instance via a ref for direct DOM interaction."},"warnings":[{"fix":"For Vue 2 projects, you must install `vue-shadow-dom@1` using `npm i vue-shadow-dom@1`. Always verify your project's Vue version aligns with the compatible library version.","message":"Version 2.0 and higher of `vue-shadow-dom` are exclusively built for Vue 3. Attempting to use these versions with Vue 2 applications will result in runtime errors due to significant API changes.","severity":"breaking","affected_versions":">=2.0.0"},{"fix":"Carefully consider the implications of `abstract`. If you need sibling content to render alongside the shadow root or to be styled by global styles, avoid using `abstract`. The default behavior without `abstract` creates an intermediate `div` for the shadow root, allowing siblings to coexist.","message":"Using the `abstract` prop on `<shadow-root>` attaches the shadow root directly to the host element. This makes other external sibling HTML tags within the same host element unavailable or unrenderable inside the Shadow DOM, which can lead to unexpected layout or missing content.","severity":"gotcha","affected_versions":">=2.0.0"},{"fix":"Consult the 'Files' section in the `vue-shadow-dom` README. Ensure you are importing the correct build artifact for your specific environment: `shadow.esm-bundler.mjs` for packaging tools, `shadow.esm-browser.mjs` for browser ESM, `shadow.global.js` for UMD, and `shadow.cjs.cjs` or the main `vue-shadow-dom` package for Node.js CommonJS.","message":"Importing the incorrect distribution file (e.g., a bundler-specific ESM build directly in a browser without a module loader, or a UMD build in a modern bundler setup) can cause module resolution failures or runtime errors.","severity":"gotcha","affected_versions":">=1.0.0"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"After creating your Vue application with `createApp()`, ensure you register the plugin by calling `app.use(shadow)` before mounting the application, e.g., `const app = createApp(MyRootComponent); app.use(shadow); app.mount('#app');`","cause":"The `vue-shadow-dom` plugin has not been correctly registered with the Vue application instance, meaning its components and directives are not globally available.","error":"Failed to resolve component: shadow-root"},{"fix":"Confirm that your application entry point uses `createApp()` to initialize your Vue 3 application. If you are targeting Vue 2, you must use `vue-shadow-dom@1` and its corresponding initialization method for Vue 2 plugins.","cause":"This error typically indicates that `app` is not a valid Vue 3 application instance. This can happen if you are using Vue 2's `new Vue()` API instead of Vue 3's `createApp()` or if `app` is otherwise undefined.","error":"TypeError: app.use is not a function"}],"ecosystem":"npm"}