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

MDX嵌入Video标签触发Minified React错误#418求助

问题

使用rspress.js静态站点生成器编写MDX文档时,本地环境(localhost)中嵌入的短视频可正常显示,但部署到服务器后无法加载。Chrome开发者工具提示Minified React错误#418,核心原因是Hydration失败:服务端渲染的HTML与客户端DOM不匹配,将在客户端重新生成DOM树。

MDX代码示例

* **New link** (or edge). Click on the arrow button and then drag from one factor to another to link them. If you wish, you can have two links between a pair of factors: one for each direction.

    <video width={640} height={360} muted loop autoPlay playsInline>
      <source src={normalizeImagePath("/images/create-link-nodes.mp4")} type="video/mp4" />
    </video>

注:normalizeImagePath是rspress提供的路径处理函数,同文件内的<img>标签使用该函数可正常显示,路径问题可能性较低。

浏览器解析后的HTML

<li class="[&amp;:not(:first-child)]:mt-2">
<p class="my-4 leading-7"><strong class="font-semibold">New link</strong> (or edge). Click on the arrow button and then drag from one factor to another to link them. If you wish, you can have two links between a pair of factors: one for each direction.</p>
<video width="640" height="360" muted="" loop="" autoplay="" playsinline=""><source src="/doc/help/doc_build/images/create-link-nodes.mp4" type="video/mp4"/></video>
</li>

问题根源与解决方法

根源分析

问题出在React服务端渲染(SSR)与客户端Hydration的属性匹配差异:

  1. 属性大小写不匹配:MDX中使用的React驼峰式属性(autoPlay、playsInline),在服务端渲染时会被转换为HTML原生的小写属性(autoplay、playsinline),但客户端Hydration时会严格校验属性的大小写,导致不匹配触发错误。
  2. 布尔属性的渲染差异:React中的布尔属性(如muted、loop)在服务端会被渲染为带空字符串的属性(muted=""),而客户端期望的是纯布尔属性形式,进一步加剧Hydration不匹配。

解决方案

方案1:统一使用HTML原生属性格式

将MDX中video标签的驼峰属性改为HTML原生的小写形式,布尔属性直接保留属性名即可:

* **New link** (or edge). Click on the arrow button and then drag from one factor to another to link them. If you wish, you can have two links between a pair of factors: one for each direction.

    <video width={640} height={360} muted loop autoplay playsinline>
      <source src={normalizeImagePath("/images/create-link-nodes.mp4")} type="video/mp4" />
    </video>

方案2:客户端挂载后再渲染视频(绕过SSR校验)

如果方案1无效,可以通过React的useEffect钩子,等待客户端挂载完成后再渲染视频,避免服务端与客户端的属性校验冲突:

import { useEffect, useState } from 'react';

const VideoPlayer = ({ src, width, height }) => {
  const [isClient, setIsClient] = useState(false);

  useEffect(() => {
    setIsClient(true);
  }, []);

  if (!isClient) return null;

  return (
    <video width={width} height={height} muted loop autoplay playsinline>
      <source src={normalizeImagePath(src)} type="video/mp4" />
    </video>
  );
};

* **New link** (or edge). Click on the arrow button and then drag from one factor to another to link them. If you wish, you can have two links between a pair of factors: one for each direction.

    <VideoPlayer src="/images/create-link-nodes.mp4" width={640} height={360} />

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 10:27:50