You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Plasmo+React+MUI内容脚本按钮样式失效问题求助

解决Plasmo内容脚本中MUI组件无样式问题

由于Plasmo内容脚本通过getShadowHostId启用了Shadow DOM,而MUI默认将样式注入到主文档的head中,无法穿透Shadow DOM的样式隔离机制,导致组件样式不生效。以下是两种可靠的解决方式:

方法一:配置Emotion缓存指向Shadow DOM

MUI v5基于Emotion实现样式渲染,需将Emotion的样式缓存挂载到Shadow Root中,确保样式注入到Shadow DOM内部:

import { Button } from "@mui/material"
import type { PlasmoCSConfig } from "plasmo"
import * as React from "react"
import { createTheme, ThemeProvider } from "@mui/material/styles"
import { CacheProvider } from "@emotion/react"
import createCache from "@emotion/cache"

export const config: PlasmoCSConfig = {
  matches: ["*://*.google.com/*"]
}

export const getShadowHostId = () => "wmp-google-dialog-container"

// 创建指向Shadow Root的Emotion缓存
const createShadowEmotionCache = () => {
  return createCache({
    key: "mui-shadow",
    container: document.getElementById(getShadowHostId())?.shadowRoot
  })
}

export const getStyle = () => {
  const style = document.createElement("style")
  return style
}

// 自定义MUI主题(可选)
const theme = createTheme()

const GoogleTemplateDialog = () => {
  // 缓存仅初始化一次
  const cache = React.useMemo(createShadowEmotionCache, [])
  
  return (
    <CacheProvider value={cache}>
      <ThemeProvider theme={theme}>
        <div>
          <Button variant="contained" color="primary">
            Injected MUI Button
          </Button>
        </div>
      </ThemeProvider>
    </CacheProvider>
  )
}

export default GoogleTemplateDialog

方法二:手动注入MUI全局样式到Shadow DOM

如果不需要动态主题,可直接将MUI的基础CSS注入到Shadow DOM的样式标签中:

import { Button } from "@mui/material"
import type { PlasmoCSConfig } from "plasmo"
import * as React from "react"
// 以raw形式导入MUI基础样式
import muiBaseCss from "@mui/material/styles/cssBaseline.css?raw"

export const config: PlasmoCSConfig = {
  matches: ["*://*.google.com/*"]
}

export const getShadowHostId = () => "wmp-google-dialog-container"

export const getStyle = () => {
  const style = document.createElement("style")
  // 将MUI样式写入Shadow DOM的style标签
  style.textContent = muiBaseCss
  return style
}

const GoogleTemplateDialog = () => {
  return (
    <div>
      <Button variant="contained" color="primary">
        Injected MUI Button
      </Button>
    </div>
  )
}

export default GoogleTemplateDialog

注意:方法二仅能覆盖MUI的基础全局样式,组件的动态样式仍需借助方法一的Emotion缓存配置才能完全生效。

内容的提问来源于stack exchange,提问作者Jatin Thapar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 22:33:11