
Алексей Баранов
Добавляем рекомендации постов и блок "Поделиться в соц. сетях"
Изучал различные блоги, аналогичные моему и решил добавить блок "Поделиться в соц. сетях", а так же простейший механизм рекомендаций статей. Вот что из этого вышло...
Результат
Добавляем рекомендации постов
Тут всё просто, я решил захардкодить в 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:
Заблокированный результат
Не очень конечно, думаю что с блокировщиками рекламы тоже предстоит разобраться со временем.
На этом всё! 🎉
Подписывайтесь на мой Youtube канал, Telegram и на сообщество Вконтакте 🙂
В живую результат статьи можно увидеть ниже 🙂



