React: Как реализовать компонент LinkPreview, который автоматически подтягивает заголовок и картинку по ссылке?
Компонент LinkPreview в React позволяет автоматически отображать превью ссылки — заголовок страницы, описание и изображение (Open Graph). Рассмотрим полную реализацию.
## Почему нельзя парсить напрямую из браузера?
Из-за политики CORS браузер не позволяет делать fetch на сторонние сайты и читать их HTML. Поэтому нужен серверный прокси.
## Шаг 1: Серверный прокси (Node.js + Express)
Создайте простой сервер, который принимает URL, скачивает HTML и извлекает мета-теги:
js
const express = require(‘express’);
const axios = require(‘axios’);
const cheerio = require(‘cheerio’);
const cors = require(‘cors’);
const app = express();
app.use(cors());
app.get(‘/api/link-preview’, async (req, res) => {
const { url } = req.query;
try {
const { data } = await axios.get(url, { timeout: 5000 });
const $ = cheerio.load(data);
const title =
$(‘meta[property=»og:title»]’).attr(‘content’) ||
$(‘title’).text();
const image =
$(‘meta[property=»og:image»]’).attr(‘content’) || »;
const description =
$(‘meta[property=»og:description»]’).attr(‘content’) ||
$(‘meta[name=»description»]’).attr(‘content’) || »;
res.json({ title, image, description, url });
} catch (e) {
res.status(500).json({ error: ‘Не удалось получить данные’ });
}
});
app.listen(4000);
## Шаг 2: React-компонент LinkPreview
jsx
import React, { useState, useEffect } from ‘react’;
const LinkPreview = ({ url }) => {
const [preview, setPreview] = useState(null);
const [loading, setLoading] = useState(false);
const [error, setError] = useState(null);
useEffect(() => {
if (!url) return;
setLoading(true);
setError(null);
fetch(`http://localhost:4000/api/link-preview?url=${encodeURIComponent(url)}`)
.then(res => res.json())
.then(data => {
setPreview(data);
setLoading(false);
})
.catch(() => {
setError(‘Ошибка загрузки превью’);
setLoading(false);
});
}, [url]);
if (loading) return
;
if (error) return
;
if (!preview) return null;
return (
{preview.image && (
)}
{preview.description}
);
};
export default LinkPreview;
## Шаг 3: Использование
jsx
## Дополнительные улучшения
— **Дебаунс**: если URL вводится вручную, добавьте задержку перед запросом через `useDebounce`.
— **Кэширование**: сохраняйте результаты в `localStorage` или `Map`, чтобы не дублировать запросы.
— **Готовые библиотеки**: `react-link-preview`, `link-preview-js` — если не хочется писать с нуля.
— **Skeleton-загрузка**: используйте компонент-скелетон вместо текста «Загрузка».
Таким образом, компонент LinkPreview в React строится из двух частей: серверного прокси для обхода CORS и React-компонента, который запрашивает данные и отображает карточку ссылки.
