Добавление предпросмотра ссылок в ваше React-приложение значительно улучшает взаимодействие пользователей, создавая более профессиональный и привлекательный интерфейс. Это делается, например, в таких приложениях, как Slack, Notion и Twitter.
Почему предпросмотры ссылок — это сложно
Для генерации предпросмотра необходимо получить URL и разобрать его метатеги (Open Graph, Twitter Cards и т. д.). На первый взгляд это просто, но возникают сложности, такие как:
- CORS-проблемы: браузеры не позволяют загружать произвольные URL из клиентского JavaScript-приложения.
- Производительность: получение внешних URL на каждом рендере отрицательно сказывается на UX.
- Ограничение скорости: некоторые сайты могут блокировать ваш скрейпер.
Единственным реальным решением — использование бэкенд-прокси.
Создание собственного бэкенд-прокси
Вы можете создать небольшую точку доступа на Node.js, которая будет получать URL на стороне сервера и разбирать метатеги. Вот пример кода для сервера:
const express = require('express');
const axios = require('axios');
const cheerio = require('cheerio');
const app = express();
app.get('/api/preview', async (req, res) => {
const { url } = req.query;
if (!url) return res.status(400).json({ error: 'url required' });
try {
const { data } = await axios.get(url, {
headers: { 'User-Agent': 'Mozilla/5.0' },
timeout: 8000,
});
const $ = cheerio.load(data);
const get = (selector) => $(selector).attr('content') || '';
res.json({
title: get('meta[property="og:title"]') || get('meta[name="twitter:title"]') || $('title').text(),
description: get('meta[property="og:description"]') || get('meta[name="description"]'),
image: get('meta[property="og:image"]') || get('meta[name="twitter:image"]'),
favicon: `${new URL(url).origin}/favicon.ico`,
});
} catch (err) {
res.status(500).json({ error: 'Failed to fetch URL' });
}
});
app.listen(3001); Теперь ваш компонент React может вызывать ваш собственный бэкенд:
import { useState, useEffect } from 'react';
export function LinkPreview({ url }) {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
fetch(`/api/preview?url=${encodeURIComponent(url)}`)
.then((r) => r.json())
.then((d) => {
setData(d);
setLoading(false);
});
}, [url]);
if (loading) return ;
if (!data?.title) return null;
return (
{data.image && (
)}
{data.title}
{data.description && ({data.description})}
{data.favicon &&
}{new URL(url).hostname}
);
} Преимущества для разработчиков
Добавление предпросмотров ссылок улучшает пользовательский опыт, делает приложение более профессиональным и удобным. Это особенно актуально для разработчиков, стремящихся сделать свой продукт более конкурентоспособным.
Перспективы
Следующим шагом может стать интеграция с популярными API для повышения функциональности предпросмотров.