如何在 Twitter 中优雅地分享你的网页链接

本文最后更新于:2024年8月11日 上午

背景

Twitter 卡片可以让人在 Twitter 上分享链接时展示更丰富的内容,它不仅可以显示网页的标题、描述、图片等信息,还能让分享的链接更加有趣,也更容易引起别人的注意。像是这样

1723320023566.jpg

近日,吾辈开发了一个名为 GitHub Critic 的小工具,用于分析 GitHub 用户并提供建设性的有趣的批评建议。这个项目的灵感来自于推友宝玉的一条推文。在将这个工具分享到 Twitter 后,吾辈意识到仅仅分享一个链接可能不够吸引人,因此吾辈开始探索如何利用 Twitter 卡片来更好地展示这个项目。

介绍

首先吾辈尝试问 Claude 怎么做,它说明了基本的格式和在 Nextjs 中实现的方法。主要是涉及到网页中特定的 meta 标签,例如

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<head>
<!-- 卡片类型 -->
<meta name="twitter:card" content="summary" />
<!-- 网站的 Twitter 用户名 -->
<meta name="twitter:site" content="@rxliuli" />
<!-- 创建者的 Twitter 用户名 -->
<meta name="twitter:creator" content="@dotey" />
<!-- 网页的标题 -->
<meta name="twitter:title" content="GitHub Critic" />
<!-- 网页的代表图片 -->
<meta
name="twitter:image"
content="'https://github-critic.rxliuli.com/logo.png'"
/>
<!-- 网页的描述 -->
<meta
name="twitter:description"
content="GitHub Critic 是一个用来分析你的 GitHub 并提出批评建议的小工具"
/>
</head>

只要在网页中添加了这些 meta 标签,然后在 Twitter 上分享链接时就会显示卡片信息,如下图所示

1723317957091.jpg

两个有用的链接

  • Twitter Card Validator: 用来验证卡片信息是否正确,但不能预览,预览的话可以在 Twitter 网页版输入链接(但不发布)即可预览
  • Twitter Cards: 官方文档

其事除了 summary 之外,还有其他几种类型,例如 Summary Card with Large Image、App Card、Player Card 等,但由于吾辈只需要分享简单的文本信息,因此只使用了 summary 类型。

实现

在 Nextjs 中,我们可以利用 generateMetadata 函数来动态生成 meta 信息。这个函数在服务端执行,允许我们根据路由参数或其他数据源来生成元数据。以下是一个具体的实现示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
export async function generateMetadata({
params,
}: {
params: { username: string }
}) {
// 获取缓存信息
const initialAnalysis = (await kv.get(params.username)) as
| UserAnalysis
| undefined
// 生成 meta 信息
return {
title: `GitHub Critic for ${params.username}`,
description:
initialAnalysis?.analysis.commentary.slice(0, 160) ??
`Check out the GitHub Critic for ${params.username}`,
twitter: {
// 此处没有重复生成 title/description,因为 twitter 会自动使用网页中的 title/description meta 标签
card: 'summary',
site: '@rxliuli',
createor: `@${params.username}`,
images:
initialAnalysis?.user.image ??
'https://github-critic.rxliuli.com/logo.png',
} as Metadata['twitter'],
}
}

测试 Twitter 卡片是一个挑战,因为它需要公网可访问的 URL。虽然我最初尝试了 GitHub PR + Vercel Preview 的方式,但这个流程相对较慢。为了所见即所得,吾辈转而使用 Cloudflare Tunnel 将本地服务器暴露到公网,有点类似于内网穿透,但免费而简单。

问题

在实际测试时,吾辈还遇到了一个奇怪的 Nextjs 的问题,服务端组件引用的客户端组件中使用了 location 对象导致整个页面都无法渲染,而且这个问题仅在生产模式出现(fuck)。

这是服务端路由组件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// page.tsx
export default function Page() {
return (
<div>
<Head>
<title>GitHub Critic</title>
<meta
name="description"
content="GitHub Critic 是一个用来分析你的 GitHub 并提出批评建议的小工具"
/>
</Head>
<main>
<h1>GitHub Critic</h1>
<p>Check out the GitHub Critic for your GitHub</p>
{/* 此处引用了客户端组件 */}
<ClientAnalyze />
</main>
</div>
)
}

然后在客户端中使用了 location 对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
'use client'
// 构建分享链接
function twitterShareUrl(username: string) {
const u = new URL('https://twitter.com/intent/tweet')
// 此处使用了 location 对象
u.searchParams.set('url', `${location.origin}/${username}`)
u.searchParams.set('text', `GitHub Critic for ${username}`)
u.searchParams.set('via', 'rxliuli')
return u.toString()
}

export default function ClientAnalyze(props: { username: string }) {
// 其他代码...
return (
<div>
<Link href={twitterShareUrl(username)} target={'_blank'}>
<Twitter className={'h-4 w-4'} />
</Link>
</div>
)
}

不得已修改了客户端组件,使用环境变量替代了 location 对象。参考 Testing Twitter Cards,但这个回答提到在生产环境添加环境变量 API_URL 没有用,还是需要添加一个 BASE_URL 环境变量。

修改 nextjs 配置文件

1
2
3
4
5
6
7
8
/** @type {import('next').NextConfig} */
const nextConfig = {
env: {
baseUrl: process.env.BASE_URL || process.env.VERCEL_URL,
},
}

export default nextConfig

修改客户端组件

1
2
3
4
5
6
7
8
9
// 构建分享链接
function twitterShareUrl(username: string) {
const u = new URL('https://twitter.com/intent/tweet')
// 使用环境变量替代 location 对象
u.searchParams.set('url', `${process.env.baseUrl}/${username}`)
u.searchParams.set('text', `GitHub Critic for ${username}`)
u.searchParams.set('via', 'rxliuli')
return u.toString()
}

这个问题突出了 Nextjs 中服务端组件与客户端组件的割裂,甚至在客户端组件中使用 location 对象时都需要特别注意。每天学会一个 Nextjs 小知识,今天你学废了吗?

总结

实现 Twitter 分享链接显示卡片比吾辈想象中简单的多,之需要在网页中添加 meta 标签即可。希望这篇文章能帮助你尝试将你的网站添加分享到 Twitter 的支持。


如何在 Twitter 中优雅地分享你的网页链接
https://blog.rxliuli.com/p/aee93d389f7d4171b011c199f1f6c5ca/
作者
rxliuli
发布于
2024年8月10日
许可协议