vite-plugin-tailwind-shadowdom
raw JSON → 1.1.1 verified Mon Apr 27 auth: no javascript
A Vite plugin that normalizes Tailwind CSS for Shadow DOM usage by fixing two key issues: converting `:root` to `:host` so CSS custom properties apply inside Shadow DOM, and unwrapping `@supports` blocks that mention `-webkit-hyphens` to avoid breakage. Current stable version is 1.1.1, released under MIT. It runs after Tailwind processes CSS, only targeting CSS imported with a query (e.g. `?inline`). Compatible with Vite 4.x-7.x and Tailwind CSS 3.x-4.x. Lightweight with no runtime dependencies beyond Vite as a peer dependency. Differentiators: specifically solves Tailwind + Shadow DOM compatibility, minimal configuration, and respects query-based imports to avoid altering global styles.
Common errors
error ERR_PNPM_NO_DEV_DEPENDENCIES_INSTALLED\nIn a CI environment, devDependencies may not be installed. ↓
cause pnpm install --prod only installs production dependencies, missing Vite and plugin.
fix
Use
pnpm install (without --prod) or add vite and the plugin as dependencies in package.json. error TypeError: tailwindShadowDOM is not a function ↓
cause Incorrect import syntax: default import used as named import.
fix
Correct:
import tailwindShadowDOM from 'vite-plugin-tailwind-shadowdom' error Uncaught TypeError: Failed to construct 'CSSStyleSheet': The document is not active. ↓
cause Using `adoptedStyleSheets` before the element is connected to DOM.
fix
Ensure
this.shadowRoot.adoptedStyleSheets = [sheet] is called in connectedCallback() or later. error The 'style' CSS module is not properly transformed; `-webkit-hyphens: none` still appears in output. ↓
cause CSS import does not have a query parameter (e.g. `?inline`), so plugin did not process it.
fix
Add
?inline to the import: import styles from './styles.css?inline' Warnings
gotcha Plugin only transforms CSS imported with a query (e.g. `?inline`). Regular CSS imports are left unchanged, so :root and @supports issues will still occur if you import without a query. ↓
fix Ensure your Shadow DOM styles are imported with a query parameter, e.g. `import styles from './styles.css?inline'`.
gotcha The plugin does not support `:host-context` or other Shadow DOM pseudo-classes beyond `:host`. You may need to manually adjust your CSS. ↓
fix If you rely on `:host-context`, consider using CSS parts or custom properties instead.
deprecated Older versions (pre-1.0.0) may not support Vite 5 or Tailwind CSS 4. Upgrade to 1.1.1 for full compatibility. ↓
fix Update to the latest version: `npm install vite-plugin-tailwind-shadowdom@latest -D`
gotcha The plugin modifies CSS output after Tailwind, so it may not work correctly if other CSS post-processing plugins reorder or transform the CSS further. ↓
fix Ensure the plugin runs after Tailwind in the Vite plugin chain. It is designed to run last, so no special ordering is needed.
gotcha The plugin only converts `:root` to `:host` within CSS imported with a query; it does not change `:root` in global stylesheets. If you have shared variables defined globally, they may not be available inside Shadow DOM. ↓
fix Redefine required custom properties inside the Shadow DOM styles or use CSS custom properties with `@property` to ensure inheritance.
Install
npm install vite-plugin-tailwind-shadowdom yarn add vite-plugin-tailwind-shadowdom pnpm add vite-plugin-tailwind-shadowdom Imports
- default wrong
const tailwindShadowDOM = require('vite-plugin-tailwind-shadowdom')correctimport tailwindShadowDOM from 'vite-plugin-tailwind-shadowdom' - tailwindShadowDOM wrong
import { tailwindShadowDOM } from 'vite-plugin-tailwind-shadowdom'correctimport tailwindShadowDOM from 'vite-plugin-tailwind-shadowdom' - Plugin type (TypeScript) wrong
import { Plugin } from 'vite-plugin-tailwind-shadowdom'correctimport type { Plugin } from 'vite'
Quickstart
// vite.config.ts
import { defineConfig } from 'vite';
import tailwindShadowDOM from 'vite-plugin-tailwind-shadowdom';
export default defineConfig({
plugins: [
tailwindShadowDOM()
]
});
// your-component.ts
import styles from './styles.css?inline';
class MyElement extends HTMLElement {
constructor() {
super();
this.attachShadow({ mode: 'open' });
}
connectedCallback() {
const sheet = new CSSStyleSheet();
sheet.replaceSync(styles);
this.shadowRoot.adoptedStyleSheets = [sheet];
}
}
customElements.define('my-element', MyElement);