Puter.js `puter.ui.socialShare()` 完全指南:为你的 App 集成多平台社交分享对话框
puter.ui.socialShare() 是 Puter 的客户端 JavaScript SDK(puter.js)中 puter.ui 模块提供的一个 UI 方法:它会在用户面前弹出一个"社交分享"对话框,让用户把一个链接一键分享到 X(原 Twitter)、WhatsApp、Facebook、LinkedIn、Reddit、Telegram 等多个社交平台,并附赠"复制链接"能力。本文以官方 API 文档 socialShare.md 为主体,结合 SDK 端 UI.js 与 GUI 宿主端 IPC.js、socialLink.js 的实现,带你完整掌握该 API 的语法、参数语义、调用链路与底层细节。
一、功能定位:适用于哪些 App?
Puter 的 UI API 手册为每个方法都声明了适用平台。socialShare 的 frontmatter 中标注为:
platforms: [apps]
也就是说,它面向在 Puter 中运行的应用(Apps)。这类应用运行在 Puter 桌面环境提供的 iframe 沙箱里,通过 puter.js SDK 与宿主 GUI 通信。当你的应用需要"把当前页面、一个文件链接或一段内容分享给好友/社交网络"时,直接调用 puter.ui.socialShare(),宿主会自动渲染一个带社交平台图标的弹出层(Popover),无需你自己去对接每一个社交平台的分享接口。
二、语法
官方文档定义了三种调用形态(参数从简到繁):
puter.ui.socialShare(url)
puter.ui.socialShare(url, message)
puter.ui.socialShare(url, message, options)
最小化调用只需要一个 url;要预填发帖内容就传 message;要控制对话框弹出的屏幕位置,再补一个 options 对象。方法整体为异步风格,返回一个 Promise(详见下文"返回值与消息链路")。
三、参数详解
url(必填)
要分享的链接地址,类型为字符串。这是唯一必填参数。在宿主端 IPC.js 中,处理器只有在 event.data.url !== undefined 时才响应,因此调用时必须带上一个真实有效的 URL。
message(可选)
用于预填社交平台发布框的文本(例如一句话推荐语)。官方文档特别指出:只有部分社交平台支持预填。这一限制与各平台官方分享链接的能力边界一致——详见下文"哪些平台会带上 message"。
options(可选)
一组键值对,用于配置分享对话框的位置,当前支持两个数值项:
| 选项 | 类型 | 默认值 | 含义 |
|---|---|---|---|
left |
Number | 0 |
对话框距窗口(屏幕)左边缘的距离 |
top |
Number | 0 |
对话框距窗口(屏幕)上边缘的距离 |
SDK 端 JSDoc 将 options 标注为 { left?: number, top?: number }(见 UI.js),默认值均为 0。不过"默认 0"只代表 SDK 端不传值的语义,宿主端对默认值有另一套"跟随父窗口"的处理策略,详见下文"弹出位置的内部计算"。
四、一个可直接运行的完整示例
结合语法与参数语义,下面是一个真实应用中的典型调用:
// 分享一个应用页面链接
puter.ui.socialShare('https://puter.com/app/my-app');
// 带一条推荐语,让支持预填的平台(如 X / WhatsApp / Telegram)带上文案
puter.ui.socialShare(
'https://puter.com/app/my-app',
'Check out this awesome app I made on Puter!'
);
// 进一步指定对话框弹出的位置(相对宿主窗口)
puter.ui.socialShare(
'https://puter.com/app/my-app',
'Check out this awesome app I made on Puter!',
{
left: 200,
top: 120,
}
);
由于方法返回 Promise,在需要串行编排(例如记录用户已点击"分享")时,也可以这样写:
try {
await puter.ui.socialShare('https://puter.com/app/my-app', '分享给好友');
// 对话框已展示并交由用户操作,这里可做后续业务处理
} catch (err) {
// SDK 层不抛错,宿主层不响应的异常情况不会进入此分支
}
需要提醒:官方文档强调 message 的预填仅部分平台支持,因此不要把 message 当作"每个平台都能 100% 预填正文"的保证;url 才是所有平台都会带上的核心内容。
五、内部原理:一次分享的完整消息链路
要理解这个"简单"的 API 背后发生了什么,需要顺着 puter.js 与 Puter 宿主 GUI 的消息通道走一遍。
1. SDK 端:封装一次 postMessage 调用
SDK 端实现位于 src/puter-js/src/modules/UI.js:
socialShare (url, message, options, callback) {
return new Promise((resolve) => {
this.#postMessageWithCallback('socialShare', resolve, { url, message, options });
});
};
它把 url、message、options 三个字段连同消息名 socialShare 打包,通过 SDK 内部私有的 #postMessageWithCallback 通道发给宿主窗口,并返回 Promise。注意函数签名中还保留了第四个形参 callback,但 JSDoc 明确说明它是 vestigial(退化遗留物):永远不会被调用,请勿依赖它做回调逻辑。
2. GUI 宿主端:处理消息并渲染对话框
宿主 GUI 的消息分发器在 src/gui/src/IPC.js 中捕获该消息(前提是 event.data.url !== undefined),随后做三件事:
- 计算对话框弹出位置;
- 调用
socialLink({ url, title: message, description: message })生成各平台分享链接; - 用
UIPopover弹出面板,绘制"可复制链接输入框 + 各平台按钮"。
3. 分享链接生成器:socialLink()
宿主把 url 与 message 注入一个通用分享链接生成器 socialLink.js。该工具返回一个以平台名为键、以完整分享 URL 为值的对象,覆盖 30 余种平台/服务(含 X/Twitter、WhatsApp、Facebook、LinkedIn、Reddit、Telegram、Pinterest、Tumblr、VK、微博、邮件等),且所有参数均经过 fixedEncodeURIComponent 做严格 URL 编码,避免特殊字符破坏链接。
4. 哪些平台会带上 message?
GUI 端以 title: message、description: message 的映射关系喂给 socialLink,最终反映到各平台 URL 的查询参数上(依据 socialLink.js 的返回模板):
| 对话框中的平台 | 生成的分享 URL 模式 | 是否携带 message 相关参数 |
|---|---|---|
| X(Twitter) | https://twitter.com/intent/tweet?url=…&text=… |
是(text,即标题+描述) |
https://api.whatsapp.com/send?text=… |
是(text) |
|
| Telegram | https://t.me/share/url?url=…&text=… |
是(text) |
https://reddit.com/submit?url=…&title=… |
是(title) |
|
http://www.facebook.com/sharer.php?u=… |
否(仅 url) |
|
https://www.linkedin.com/sharing/share-offsite/?url=… |
否(仅 url) |
可见官方文档中"message 只在部分平台支持"的措辞与源码实现完全吻合:对话框按钮所覆盖的六个平台中,X、WhatsApp、Telegram、Reddit 的链接会携带文本类参数,而 Facebook、LinkedIn 的官方分享入口只接收 URL。至于这些参数最终是否真的被平台用于预填输入框,取决于各平台服务端行为,宿主端只负责按官方分享接口构造链接。
六、弹出位置的内部计算
这是 options 与官方文档最值得深入的一处。虽然 SDK 端声称 left/top 默认是 0,但宿主端有一套相对父窗口定位的补偿逻辑(IPC.js):
- 无论是否传值,宿主都会先取得应用窗口的当前位置
window_position; - 传入
left:取绝对值后叠加窗口left,即abs(left) + window_position.left; - 未传
left:直接采用窗口的left(视觉上跟随窗口左缘); - 传入
top:取绝对值后叠加window_position.top + 30; - 未传
top:直接采用window_position.top + 30(窗口顶缘往下偏移 30px); - 最后两者均
parseFloat归一为数值。
也就是说,options.left / options.top 实际表达的是相对所属应用窗口左上角的偏移量,而不是屏幕绝对坐标;宿主会自动把它换算成绝对位置。同时,面板通过 UIPopover({ ..., position: 'bottom', height: 100 }) 以"位于锚点下方"的方式弹出,因此最终呈现效果是:分享面板出现在调用方应用窗口的底部附近,与窗口保持约 30px 的间距。这正是"默认 0"与"实际跟随窗口"两者差异的来源。
七、对话框里都有什么?
从 IPC.js 的 HTML 拼接逻辑可以还原对话框完整构成:
- 链接复制区:一个只读文本输入框(预填待分享的
url)+ 一个复制按钮。点击复制按钮通过navigator.clipboard.writeText(url)写入剪贴板,同时图标短暂切换为对勾,约 1 秒后恢复为复制图标; - 平台图标区:一行社交图标按钮,分别是 X(Twitter)、WhatsApp、Facebook、LinkedIn、Reddit、Telegram,均以
target="_blank"新窗口打开对应分享 URL,图标来自window.icons['logo-*.svg']图标集; - 标题文案:使用
i18n('share_to')做国际化(多语言)文案,提示语随界面语言变化。
这六个平台与 socialLink 支持的 30+ 平台相比是经过挑选的精简集合,覆盖了当前主流社交分享渠道,同时保证对话框不至于拥挤。如果你的应用需要更多平台,只能自行基于 socialLink 思路扩展或使用其他分享方案。
八、适用环境与注意事项
- 仅限 Apps:该 API 在 puter.js 中标记为
platforms: [apps],面向在 Puter 应用沙箱内运行的 App;完整 UI 方法族(puter.ui.*,包括 notify、prompt、showOpenFilePicker 等)在 src/docs/src/UI/ 手册与 UI.md 中可一并查阅。 - url 是唯一硬性前提:宿主端只在
url !== undefined时响应,漏传 url 将导致消息不被处理。 - message 并非处处生效:它是"尽力而为"的预填文本,平台支持度参差(详见上文表格),不要用它承载关键业务语义。
- 返回值语义:SDK 返回 Promise,但它更像一个"已送达"信号——宿主弹出面板后由用户自主操作(复制或跳转第三方站点),SDK 不接收用户在第三方平台上的最终分享结果。
- callback 是遗留参数:第四个参数永远不会被调用,请使用 Promise 风格(
await/.then)。 left/top是相对量:它们表示相对应用窗口的偏移并被取绝对值;不传时对话框会自动跟随窗口左下沿弹出,日常使用通常无需关心位置参数。
九、小结
puter.ui.socialShare() 把"对接多家社交平台分享接口 + 弹出交互面板 + 复制链接"三件繁琐事收敛成一个方法调用,是 puter.js UI API 中典型的"宿主托管 UI"代表。从本文可以看到:方法参数(url / message / options)语义清晰;SDK 端 UI.js 通过 postMessage 桥接宿主;宿主端 IPC.js 完成定位换算与面板渲染,并借助 socialLink.js 批量生成各平台分享链接。如果你想为基于 Puter 构建的应用快速加上社交传播能力,只需一行 puter.ui.socialShare(url, message) 即可。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0631
MiniCPM5-2BMiniCPM5-2B 是一款面向端侧、本地部署和资源受限场景的 2B 稠密 Transformer,能够达到同尺寸开源模型 SOTA 水平。Markdown00
video-shotcraftAI宣传片skill,使用 Remotion 制作电影级产品视频:提供106 张镜头配方卡和可复用的视频魔板。适用于 Claude Code 与 Codex以及所有其他智能体Markdown00
HivisionIDPhotos⚡️HivisionIDPhotos: a lightweight and efficient AI ID photos tools. 一个轻量级的AI证件照制作算法。Python09
DragonOSDragonOS is an operating system developed from scratch using Rust, with Linux compatibility. It is designed for **Serverless** scenarios. 使用Rust从0自研内核,具有Linux兼容性的操作系统,面向云计算Serverless场景而设计。Rust00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00