把 Sidegloss 接入你的网站
一个零依赖的脚本:引入后,读者在你的页面上双击英文句子即可看到整句翻译、点词释义和朗读;登录后还能把句子和单词收进自己的生词本。
快速开始
<script src="/sidegloss.js"></script>
<script>
Sidegloss.init({ source: 'en', target: 'zh-CN', trigger: 'dblclick' });
</script>
生产环境建议固定版本号并启用子资源完整性校验(SRI)。带版本号的地址会被长期缓存:
加载中…
支持 UMD:<script> 引入后挂在 window.Sidegloss,CommonJS 环境下 module.exports 同样可用。重复注入同一版本不会产生两套监听。
产品原名 EchoLingo:旧地址 /echolingo-sdk.js、全局对象 window.EchoLingo 和 echolingo:* 事件都继续可用,已接入的网站不用改代码。
配置项
Sidegloss.init(options) 或 Sidegloss.setOptions(options):
| 选项 | 默认值 | 说明 |
|---|---|---|
source | 'en' | 源语言。为 en 时会跳过拉丁字母占比过低的句子;auto 时任何语言都可翻译,朗读语言取自检测结果 |
target | 'zh-CN' | 目标语言 |
trigger | 'dblclick' | 'dblclick' 双击取整句;'selection' 划选文本(触屏上选区稳定后自动打开);'manual' 只通过 API 打开 |
exclude | '' | 额外的 CSS 选择器,命中的元素不触发(内置已排除输入框、按钮、代码块、媒体等) |
service | 官方服务 | 账号与生词本服务地址;设为 false 关闭登录和收藏。也可在 script 标签上写 data-service |
style | {} | 卡片样式默认值 {theme, fontSize, width, radius, serif},theme 可选 paper / sepia / slate / night;读者登录后以其个人设置为准 |
endpoint | Google gtx | 翻译接口地址,可换成自己的代理(需返回相同格式) |
fetch | null | 自定义 fetch 函数 |
translate | null | 自定义翻译函数,设置后完全绕过 Google,见下文 |
speak | null | 自定义朗读函数 (text, {language, signal, rate, pitch, volume, voiceURI}) => Promise |
speech | {enabled:true, rate:0.95, …} | 浏览器语音参数;enabled:false 隐藏朗读按钮。浏览器不支持语音时按钮会自动隐藏 |
dictionary | true | 是否允许点击单词查词 |
zIndex | 2147483647 | 卡片层级 |
width | 450 | 卡片宽度(px),范围 280–900 |
labels | {} | 覆盖界面文案,键名见 Sidegloss._internal.LABELS;错误文案的键名为 error_ + 错误码 |
API
init(options) | 启动并绑定事件监听;重复调用等同于 setOptions |
open(text, {x, y}) | 手动打开翻译卡片,返回是否成功 |
openAt(x, y) | 取页面坐标处的整句并打开 |
close() | 关闭卡片 |
translate(text, {source, target, signal}) | 仅翻译,返回 Promise<{translation, detected}>;不会因卡片关闭而取消 |
lookup(word, {source, target, signal}) | 查词,返回释义、例句、相关表达 |
speak(text, language) / stopSpeaking() | 朗读 / 停止 |
voices(language) | 列出浏览器语音(按自然度排序) |
isActive() / destroy() | 是否已启动 / 卸载并移除全部监听、界面,停止朗读和请求 |
utils | 底层工具:sentenceAt、sentenceNear、wordTokens、renderPreview 等 |
登录与生词本
卡片底部默认带有“登录”按钮,句子和单词释义旁各有一颗 ☆。读者第一次点击时会弹出 Sidegloss 官网的登录窗口,通过 Clerk 完成登录(Google 账号或邮箱)后,凭据只保存在你网站的 localStorage 里,因此每个网站需要单独登录一次;读者可以在个人中心随时移除某个网站的授权。
login() / logout() | 登录(需在用户点击中调用,否则弹窗会被拦截)/ 退出 |
user() | 当前读者 {user, settings},未登录为 null |
refreshUser() | 向服务端刷新资料与样式设置 |
request(path, init) | 以当前读者身份调用服务端接口,例如 request('/api/vocab') |
saveSettings(settings) | 保存读者设置,如 {style: {theme: 'night'}} |
不需要登录与收藏时:Sidegloss.init({ service: false })。
事件
SDK 在 document 上派发 CustomEvent,detail 携带数据:
sidegloss:open{text, x, y}、sidegloss:close{text}sidegloss:translated{text, result}、sidegloss:lookup{word, result}sidegloss:login{user}、sidegloss:logout、sidegloss:session{reason, signedIn}sidegloss:saved{item}、sidegloss:removed{type, text, id}
使用自己的翻译服务
Google 的 gtx 接口允许跨域,但有频率限制(触发 429 后 SDK 会冷却 60 秒)。直连被网络或页面安全策略拦截时,SDK 会自动改用 Sidegloss 服务的翻译代理。生产环境建议提供 translate 钩子接自己的后端:
Sidegloss.init({
translate: async ({ text, source, target, dictionary, signal }) => {
const r = await fetch('/api/translate', { method: 'POST', signal, body: JSON.stringify({ text, source, target, dictionary }) });
const data = await r.json();
// 可以直接返回字符串,或返回对象:
// { translation, detected, dictionary:[{pos, terms:[]}], definitions:[{pos, meaning, example}], examples:[], synonyms:[] }
return dictionary ? data : data.translation;
}
});
钩子有 14 秒超时保护,超时或卡片关闭时会通过 signal 通知你中止请求。钩子的文本长度上限放宽到 20000 字符。
注意事项
- 请求层自带缓存(180 条)、去重、并发上限 4、超时 14 秒;关闭卡片会取消未完成的界面请求。
- 界面渲染在 Shadow DOM 中,不受页面样式影响;样式通过可构造样式表注入,页面启用严格 CSP 或 Trusted Types 时同样可用。
- 页面 CSP 的
connect-src需要允许translate.googleapis.com(或你的代理)以及生词本服务的域名。 - 朗读依赖浏览器
speechSynthesis,不同系统音色不同;可用speak钩子接入自己的 TTS。