Skip to content

Latest commit

 

History

12 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Newsdata.io logo

Newsdata.io React.js Client

npm version npm downloads CI React License OpenAPI

Official React hooks SDK for the Newsdata.io News API. Drop-in useLatestNews, useArchiveNews, useCryptoNews, useMarketNews, useNewsCount, … hooks plus a <NewsDataProvider> to share one client. Built on the same proven core as the Node client — validation, typed errors, retries with exponential backoff — and ships first-class TypeScript definitions.

Zero runtime dependencies, no build step, React 18+ as a peer dependency.

Installation

npm install newsdataapi
# react is a peer dependency
npm install react

Quickstart

import { NewsDataProvider, useLatestNews } from 'newsdataapi';

function Headlines() {
  const { data, error, isLoading } = useLatestNews({
    q: 'bitcoin',
    country: ['us', 'gb'],
    language: 'en',
  });

  if (isLoading) return <p>Loading…</p>;
  if (error) return <p>Error: {error.message}</p>;

  return (
    <ul>
      {data.results.map((article) => (
        <li key={article.article_id}>
          <a href={article.link}>{article.title}</a>
        </li>
      ))}
    </ul>
  );
}

export default function App() {
  return (
    <NewsDataProvider apiKey={process.env.REACT_APP_NEWSDATA_API_KEY}>
      <Headlines />
    </NewsDataProvider>
  );
}

Hooks

Hook Endpoint Notes
useLatestNews(params) /1/latest Real-time news
useArchiveNews(params) /1/archive Historical news
useNewsSources(params) /1/sources Available sources (single page)
useCryptoNews(params) /1/crypto Cryptocurrency news
useMarketNews(params) /1/market Market / financial news
useNewsCount(params) /1/count Aggregate counts (requires from_date, to_date)
useCryptoCount(params) /1/crypto/count Aggregate crypto counts
useMarketCount(params) /1/market/count Aggregate market counts
useNewsStream(registrationId) wss://ws.newsdata.io/ws/event Real-time stream (below)

Every hook has the same shape:

const { data, error, isLoading, refetch } = useLatestNews(params, options);
  • data — the API response (null until the first fetch resolves)
  • error — a typed NewsdataError (null on success)
  • isLoadingtrue while a request is in flight
  • refetch() — re-run the request; returns the underlying Promise

options

useLatestNews(params, { enabled: false })  // skip the request until enabled

options.enabled (default true) defers fetching — handy when params aren't ready (e.g. waiting on user input).

Parameter values

Values can be a single string or an array of strings (sent comma-joined), and parameter names are case-insensitive — qInTitle and qintitle are equivalent:

useLatestNews({ country: ['us', 'gb'], language: 'en', size: 20 });

Inline param objects are safe — the hook compares by value, not reference, so re-renders only re-fetch when the values change.

Real-time news (WebSocket)

useNewsStream opens a real-time connection for a registered query and accumulates the matching articles. Register the query first — the returned registration_id identifies it from then on:

import { useEffect, useState } from 'react';
import { useNewsDataClient, useNewsStream } from 'newsdataapi';

function BitcoinTicker() {
  const client = useNewsDataClient();
  const [registrationId, setRegistrationId] = useState(null);

  useEffect(() => {
    client.websocketRegister({ q: 'bitcoin', language: 'en' })
      .then(({ results }) => setRegistrationId(results.registration_id));
  }, [client]);

  // A falsy id defers connecting until registration resolves.
  const { articles, error, isConnected } = useNewsStream(registrationId);

  if (error) return <p>Stream error: {error.message}</p>;

  return (
    <>
      <p>{isConnected ? 'live' : 'connecting…'}</p>
      <ul>
        {articles.map((a) => <li key={a.article_id}>{a.title}</li>)}
      </ul>
    </>
  );
}

The hook returns { articles, latest, error, isConnected }. Articles accumulate newest first and are capped at maxArticles (default 100) so a long-lived stream can't grow without bound. The connection opens on mount, closes on unmount, and reconnects through a capped exponential backoff.

const { articles, latest } = useNewsStream(registrationId, {
  enabled: true,      // defer connecting when false
  maxArticles: 100,   // cap on retained articles
  reconnect: true,    // auto-reconnect on transient drops
});

error is set for a permanent rejection — bad API key or unknown registration_id, exhausted API credits, or too many simultaneous devices — which surfaces as NewsdataWebSocketAuthError and is not retried.

The server always accepts the handshake and then closes with code 1008 when the connection is refused, carrying one of three reasons: invalid credentials or registration not found, api limit reached, or device limit reached (more than 5 devices on one registration_id). Every other close code — including 1013 (send timeout, meaning the client read too slowly) — is transient and reconnects.

Each delivered article consumes 1 API credit per connected device.

Transient drops reconnect silently and leave error null.

Managing registered queries goes through the client: websocketRegister(params), websocketFetch(), and websocketDelete(registrationId). Registering an identical query twice rejects with a NewsdataApiError whose statusCode is 409; the existing id is at err.responseBody.results.registration_id.

Outside React, use the same NewsDataApiWebSocket class the hook wraps:

import { NewsDataApiWebSocket } from 'newsdataapi';

const ws = new NewsDataApiWebSocket(client);
for await (const response of ws.stream(registrationId)) {
  console.log(response.results);
}

Provider

Two ways to wire it up:

// 1. Let the provider construct the client.
<NewsDataProvider apiKey="..." options={{ timeout: 10_000, maxRetries: 3 }}>
  <App />
</NewsDataProvider>

// 2. Or pass your own pre-built client (full control over its lifecycle).
import { NewsDataApiClient } from 'newsdataapi';
const client = new NewsDataApiClient(apiKey);

<NewsDataProvider client={client}>
  <App />
</NewsDataProvider>

Anywhere inside the provider you can grab the client directly:

import { useNewsDataClient } from 'newsdataapi';

function ExportButton() {
  const client = useNewsDataClient();
  return <button onClick={() => client.archiveApi({ q: 'x' }).then(save)}>Export</button>;
}

Errors

All hook errors are instances of the typed hierarchy from the core SDK:

import {
  NewsdataValidationError, NewsdataAuthError, NewsdataRateLimitError,
  NewsdataApiError, NewsdataNetworkError,
} from 'newsdataapi';

if (error instanceof NewsdataRateLimitError) {
  console.log('retry after', error.retryAfter, 'seconds');
}
NewsdataError                       (catch-all base)
├── NewsdataValidationError         (.param)
├── NewsdataApiError                (.statusCode, .responseBody)
│   ├── NewsdataAuthError           (401 / 403)
│   ├── NewsdataRateLimitError      (429; .retryAfter)
│   └── NewsdataServerError         (5xx)
├── NewsdataNetworkError            (.cause)
└── NewsdataWebSocketError          (real-time stream)
    └── NewsdataWebSocketAuthError  (policy-violation close 1008)

Validation errors are thrown before the request is sent (no API quota spent) — e.g. setting q and qInTitle together, an unsupported parameter for that endpoint, or missing from_date/to_date on a count endpoint.

Direct client access

You can also use the underlying client without React — same surface as newsdata-nodejs-client:

import { NewsDataApiClient } from 'newsdataapi';

const client = new NewsDataApiClient(apiKey, { timeout: 10_000 });

// scroll: follow nextPage cursors and merge.
const merged = await client.latestApi({ q: 'news', scroll: true, maxResult: 200 });

// paginate: async generator, one page at a time.
for await (const page of client.latestApi({ q: 'news', paginate: true, maxPages: 5 })) {
  console.log(page.results.length);
}

Development

npm install
npm test          # node:test, 34 tests, no API key required

Related libraries

Official Newsdata.io clients across languages and runtimes:

Also see free news datasets for ML / NLP work.

License

MIT

About

Official React hooks SDK for the Newsdata.io News API — useLatestNews, useCryptoNews, useMarketNews & more with validation, retries, and typed errors.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages