划词翻译会导致用了 react SSR(Server-side rendering) 的网站无法正常运行
基本信息
划词翻译版本: 9.6.0 浏览器版本: Microsoft Edge 版本 111.0.1661.51 (正式版本) (arm64) 操作系统: MacOS
重现问题的步骤
- npx [email protected] 按流程创建remix基础模板
- npm run dev 启动dev环境
预期行为
remix网站成功,且无报错

实际行为
报错

补充信息
从报错信息上看确实是划词翻译导致的这个问题,因为划词翻译会在 <html>下插入一个 <div>(也就是翻译面板、翻译按钮之类的界面),理论上这不符合 HTML 标准,这就导致了 react 报错 Did not expect...
类似的,在 react 中渲染 <p><div></div></p> 也会引起这个报错。
但如果改成插入到 <body> 下,又会引起其它问题。划词翻译并不属于网页自身的内容,插入到 body 下会让少部分网页误将在划词翻译界面上的操作给捕获了(比如点了一下翻译按钮导致网页跳到了一个新页面)
这个问题理论上没法从划词翻译侧解决,因为为了要显示翻译结果,划词翻译就必须插入 dom 元素,而这就会导致 initial UI does not match what was rendered on the server.
上次看到这个报错好像是因为 #1609 ,不过我刚又试了下,发现 #1609 的问题已经没有了,也许 remix 有什么设置可以解决这个问题。
已确认是由于划词翻译在 html 下插入了一个 div 导致使用了 Server-side rendering 的网站发现客户端和服务端 html 结构不一样导致的。
如果划词翻译延迟一段时间(比如一秒后)再将 div 插入 html 就不会有这个问题,但是这个插入的具体时机很难把握。。
以 https://radar.cloudflare.com/ 这个网站为例,经过多次测试,发现划词翻译最少需要在 100 毫秒后插入到 dom 才能确保不会报错,但我不确定在其他 Server-side rendering 的网站是不是也可以用 100 毫秒作为插入的时机。
https://github.com/remix-run/remix/issues/1077
remix中也有反馈,不止本插件有问题,但是除了关闭扩展,没有提到其他修复方案
使用hydrate暂时解决,link: https://github.com/facebook/react/issues/24430
import { RemixBrowser } from "@remix-run/react";
import { startTransition, StrictMode } from "react";
+import { hydrate } from "react-dom";
import { hydrateRoot } from "react-dom/client";
startTransition(() => {
- hydrateRoot(
- document,
- <StrictMode>
- <RemixBrowser />
- </StrictMode>
- );
+ hydrate(<RemixBrowser />, document);
});