Skip to main content
The news page aggregates the latest cryptocurrency news articles in Spanish from the CryptoCompare API and renders them as a vertical card feed.

Data loading

News is fetched via keepNews() from cache.js when the News page mounts:
news.jsx
import { keepNews } from "../services/cache";

useEffect(() => {
  let isMounted = true;

  async function loadNews() {
    setLoading(true);
    setError("");
    try {
      const response = await keepNews();
      const newsList = Array.isArray(response?.Data) ? response.Data : [];

      const normalizedNews = newsList.map((item) => ({
        id: item.id || item.guid || item.url,
        title: item.title,
        description: item.body,
        source: item.source_info?.name || item.source,
        imageUrl: item.imageurl,
        publishedAt: item.published_on
          ? new Date(item.published_on * 1000).toISOString()
          : "",
        url: item.url,
      }));

      if (isMounted) setNews(normalizedNews);
    } catch {
      if (isMounted)
        setError("No se pudieron cargar las noticias. Inténtalo de nuevo.");
    } finally {
      if (isMounted) setLoading(false);
    }
  }

  loadNews();
  return () => { isMounted = false; };
}, []);
keepNews() calls the CryptoCompare news endpoint:
GET https://min-api.cryptocompare.com/data/v2/news/?lang=ES
Results are cached in localStorage under the key getNewsCrypto for 5 minutes. Navigating away and back to the news page within that window will render from cache without an additional network request.

CryptoNewsCard component

Each article is rendered by CryptoNewsCard in src/components/cryptoNews.jsx. The component accepts the following props:
props.title
string
required
Article headline. Displayed clamped to 2 lines.
props.description
string
Article body text. Displayed clamped to 3 lines.
props.source
string
Publication source name (e.g. "CoinDesk"). Falls back to "Fuente desconocida" when absent.
props.imageUrl
string
URL of the article cover image. Falls back to an Unsplash crypto image when absent.
props.publishedAt
string
ISO 8601 date string. Formatted for display using es-ES locale (dd MMM yyyy).
props.url
string
required
Link to the full article. Opens in a new tab.

Page states

The News page handles four conditional UI states driven by loading, error, and news.length:
ConditionUI shown
loading === trueText message: "Cargando noticias..." in a bordered card
!loading && errorRed bordered card with message: "No se pudieron cargar las noticias. Inténtalo de nuevo."
!loading && !error && news.length > 0Grid of CryptoNewsCard article cards
!loading && !error && news.length === 0Neutral card: "No hay noticias disponibles ahora mismo."
These states are rendered as independent conditional blocks in JSX, not as mutually exclusive branches — multiple conditions can render simultaneously if the state combination allows it (e.g., the empty message is an additional check after the main grid render).
CryptoCompare’s free tier has rate limits. If many users hit the API simultaneously the fetch may fail. The 5-minute cache reduces the chance of hitting rate limits during normal usage.

Build docs developers (and LLMs) love