Skip to content

Commit 61683b8

Browse files
authored
feat: Use rel="noopener noreferrer nofollow ugc" on user links (#215)
fix #214 - `+ ugc` 符合最新语义(Google 自 2019) 我调查了下其他的 - twikoo 是 noopener noreferrer nofollow ugc twikoojs/twikoo#907 - waline 是 ugc nofollow noopener noreferrer walinejs/waline#3531 - artalk 是 noreferrer noopener nofollow ArtalkJS/Artalk#1120 - valine 是 noopener 相关文档: - nofollow 和 ugc 一起用以保证兼容性:https://developers.google.com/search/blog/2019/09/evolving-nofollow-new-ways-to-identify?hl=zh-cn#can-i-use-more-than-one-rel-value-on-a-link - 几个用于出站链接的 rel 值(sponsored,ugc,nofollow)介绍:https://developers.google.com/search/docs/crawling-indexing/qualify-outbound-links?hl=zh-cn --- 没有把链接的 target / rel 处理放进 packages/comment-widget/src/utils/html.ts 的 cleanHtml(),而是放在了渲染期 packages/comment-widget/src/comment-content.ts。 给评论正文里的 <a> 统一补 target="_blank" 和 rel="noopener noreferrer nofollow ugc" 作为渲染策略,区分于清洗逻辑。如果要在清洗的时候就做这个 rel 修改,有以下问题: - 首先数据库要额外保存 rel,要修改默认 sanitize-html 策略(附:sanitize-html 默认给 a 允许的是:href、name、target。) - 之前数据不带 rel 的已有数据,在渲染时也不能自带加上新 rel。
1 parent 76345cb commit 61683b8

4 files changed

Lines changed: 25 additions & 4 deletions

File tree

packages/comment-widget/src/base-comment-item.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ export class BaseCommentItem extends LitElement {
6262
class="item-author font-medium text-sm text-text-1 hover:underline"
6363
target="_blank"
6464
href=${ifDefined(this.userWebsite)}
65-
rel="noopener noreferrer"
65+
rel="noopener noreferrer nofollow ugc"
6666
>
6767
${this.userDisplayName}
6868
</a>

packages/comment-widget/src/comment-content.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,16 @@ export class CommentContent extends LitElement {
99
@property({ type: String })
1010
content: string = '';
1111

12+
private applyLinkAttributes() {
13+
const anchors =
14+
this.shadowRoot?.querySelectorAll<HTMLAnchorElement>('.content a');
15+
16+
anchors?.forEach((anchor) => {
17+
anchor.target = '_blank';
18+
anchor.rel = 'noopener noreferrer nofollow ugc';
19+
});
20+
}
21+
1222
protected override firstUpdated(_changedProperties: PropertyValues) {
1323
super.firstUpdated(_changedProperties);
1424
const codeElements = this.shadowRoot?.querySelectorAll('pre>code');
@@ -38,6 +48,13 @@ export class CommentContent extends LitElement {
3848
);
3949
}
4050

51+
protected override updated(_changedProperties: PropertyValues) {
52+
super.updated(_changedProperties);
53+
if (_changedProperties.has('content')) {
54+
this.applyLinkAttributes();
55+
}
56+
}
57+
4158
private extractLanguageFromCodeElement(codeElement: Element): string | null {
4259
const supportedPrefixes = ['language-', 'lang-'];
4360

packages/comment-widget/src/comment-editor.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,12 +95,11 @@ export class CommentEditor extends LitElement {
9595

9696
async createEditor() {
9797
const { Editor } = await import('@tiptap/core');
98-
const { Placeholder } = await import('@tiptap/extensions');
98+
const { CharacterCount, Placeholder } = await import('@tiptap/extensions');
9999
const { StarterKit } = await import('@tiptap/starter-kit');
100100
const { CodeBlockShiki } = await import(
101101
'tiptap-extension-code-block-shiki'
102102
);
103-
const { CharacterCount } = await import('@tiptap/extensions');
104103

105104
this.loading = false;
106105

@@ -111,6 +110,11 @@ export class CommentEditor extends LitElement {
111110
heading: false,
112111
link: {
113112
openOnClick: false,
113+
defaultProtocol: 'https',
114+
HTMLAttributes: {
115+
target: '_blank',
116+
rel: 'noopener noreferrer nofollow ugc',
117+
},
114118
},
115119
codeBlock: false,
116120
}),

packages/comment-widget/src/user-avatar.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ export class UserAvatar extends LitElement {
6767

6868
override render() {
6969
if (this.href) {
70-
return html`<a class="avatar" href="${this.href}" target="_blank" rel="noopener noreferrer">
70+
return html`<a class="avatar" href="${this.href}" target="_blank" rel="noopener noreferrer nofollow ugc">
7171
${this.renderAvatarContent()}
7272
</a>`;
7373
}

0 commit comments

Comments
 (0)