Изучали различные блоги, аналогичные нашему и решили добавить блок "Поделиться в соц. сетях", а так же простейший механизм рекомендаций статей. Вот что из этого вышло...
Результат
Добавляем рекомендации постов
Тут всё просто, мы решили захардкодить в frontmatter каждой статьи массив со ссылками на другие статьи, схожие по тематике.
Только вместо ссылок мы использовали slug постов.
recommendations: ["collabic", "vk-feed"]У нас уже был компонент PostPreview для отображения описания поста. Он используется на главной странице. Поэтому мы просто переиспользовали его.
В компоненте поста, мы получаем список данных о рекомендованных постах:
const recommendations = post.recomendations.map((s) => getPostBySlug(s));И передаём их в компонент PostPreview, который рендерим после тела статьи:
{recommendations.map((r) => (
<PostPreview
key={r.slug}
title={r.title}
coverImage={r.coverImage}
date={r.date}
slug={r.slug}
excerpt={r.excerpt}
/>
))}В результате блок рекомендаций выглядит следующим образом:
Блок рекомендаций
Добавляем блок "Поделиться в соц. сетях"
Для кнопок соц. сетей мы использовали готовое решение - пакет react-share.
Установим его:
npm i react-shareДалее всё просто, импортим оттуда кнопки и иконки:
"use client";
import { TelegramIcon, TelegramShareButton } from "react-share";И передаём в них базовые данные о посте:
const ICON_SIZE = 40;
<TelegramShareButton url={url} title={post.title}>
<TelegramIcon
size={ICON_SIZE}
className="rounded-3xl grayscale hover:grayscale-0"
/>
</TelegramShareButton>С кнопками соц. сетей всё просто. Но нам хотелось ещё добавить возможность использовать нативный механизм "поделиться" на мобильных устройствах и просто удобно копировать ссылку на статью на десктопах.
Поэтому мы решил сделать свою кнопку.
С разметкой там всё просто, поэтому остановлюсь только на интересном, а именно на использовании navigator.share API.
Сначала подготовим данные:
const shareData = {
title: post.title,
text: post.description,
url: post.url,
};Затем вызовем navigator.share:
const handler = async () => {
try {
await navigator.share(shareData);
} catch (e) {
// Тут нужен фоллбек на копирование ссылки
writeToClipboard(post.url);
}
};Нужно учитывать что navigator.share может быть недоступен по множеству причин, поэтому я добавил фоллбек на запись ссылки в clipboard.
Но и запись в clipboard может быть недоступен по множеству причин, поэтому и это надо учитывать.
const writeToClipboard = async (text: string) => {
try {
await navigator.clipboard.writeText(text);
} catch (error) {
console.error((error as Error).message);
}
};
Результат
А вот так этот блок выглядит при включенном Ad Block:
Заблокированный результат
Не очень конечно, думаем что с блокировщиками рекламы тоже предстоит разобраться со временем.
На этом всё! 🎉
В живую результат статьи можно увидеть ниже 🙂




