Cricket API for React and Next.js — Live Scores in Your Web App
Step-by-step guide to integrating live cricket scores into your React or Next.js web app using CricLive API. Includes hooks, SSR, and real-time polling examples.
Why React and Next.js Developers Need a Cricket API
Whether you are building a cricket score widget, a full sports portal, or a fantasy cricket platform, you need reliable, real-time cricket data. CricLive API gives you structured JSON data that works perfectly with React's component model and Next.js's server-side rendering.
This guide covers everything: a custom React hook for live scores, Next.js SSR integration, and a real-time polling component that updates automatically.
Getting Started
Sign up at cricketliveapi.com/register — free, no credit card. You will get your API key instantly.
Install the HTTP client:
npm install axios
# or
yarn add axios
Custom React Hook — useLiveScores
Create a reusable hook that fetches live scores and auto-refreshes every 10 seconds:
// hooks/useLiveScores.js
import { useState, useEffect, useCallback } from 'react';
import axios from 'axios';
const API_KEY = process.env.NEXT_PUBLIC_CRICLIVE_API_KEY;
const BASE_URL = 'https://cricketliveapi.com/api/v1';
export function useLiveScores(refreshInterval = 10000) {
const [matches, setMatches] = useState([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
const [lastUpdated, setLastUpdated] = useState(null);
const fetchScores = useCallback(async () => {
try {
const { data } = await axios.get(`${BASE_URL}/live-scores`, {
headers: { Authorization: `Bearer ${API_KEY}` },
});
setMatches(data.data || []);
setLastUpdated(new Date());
setError(null);
} catch (err) {
setError('Failed to fetch live scores');
} finally {
setLoading(false);
}
}, []);
useEffect(() => {
fetchScores();
const interval = setInterval(fetchScores, refreshInterval);
return () => clearInterval(interval);
}, [fetchScores, refreshInterval]);
return { matches, loading, error, lastUpdated, refetch: fetchScores };
}
Live Score Component
// components/LiveScores.jsx
import { useLiveScores } from '../hooks/useLiveScores';
export default function LiveScores() {
const { matches, loading, error, lastUpdated } = useLiveScores(10000);
if (loading) return (
<div className="flex items-center justify-center p-8">
<div className="animate-spin rounded-full h-8 w-8 border-b-2 border-green-500"></div>
</div>
);
if (error) return (
<div className="text-red-500 p-4">{error}</div>
);
if (matches.length === 0) return (
<div className="text-gray-500 p-4">No live matches right now.</div>
);
return (
<div className="space-y-4">
{lastUpdated && (
<p className="text-xs text-gray-400">
Updated: {lastUpdated.toLocaleTimeString()}
</p>
)}
{matches.map((match) => (
<MatchCard key={match.match_id} match={match} />
))}
</div>
);
}
function MatchCard({ match }) {
return (
<div className="bg-white rounded-xl shadow-sm border border-gray-100 p-4">
<div className="flex justify-between items-start">
<div>
<h3 className="font-semibold text-gray-900">{match.teams}</h3>
<p className="text-green-600 font-bold text-lg mt-1">{match.score}</p>
<p className="text-gray-500 text-sm mt-1">{match.venue}</p>
</div>
<span className={`px-2 py-1 rounded-full text-xs font-medium ${
match.status === 'live'
? 'bg-red-100 text-red-600'
: 'bg-gray-100 text-gray-600'
}`}>
{match.status === 'live' ? '🔴 LIVE' : match.status}
</span>
</div>
<p className="text-xs text-gray-400 mt-2">{match.format} · {match.series}</p>
</div>
);
}
Next.js — Server-Side Rendering (SSR)
For better SEO and faster initial load, fetch cricket data server-side with getServerSideProps:
// pages/cricket.js
import axios from 'axios';
import LiveScores from '../components/LiveScores';
export async function getServerSideProps() {
try {
const { data } = await axios.get(
'https://cricketliveapi.com/api/v1/live-scores',
{
headers: {
Authorization: `Bearer ${process.env.CRICLIVE_API_KEY}`,
},
}
);
return {
props: {
initialMatches: data.data || [],
},
};
} catch (error) {
return {
props: { initialMatches: [] },
};
}
}
export default function CricketPage({ initialMatches }) {
return (
<main className="max-w-2xl mx-auto p-6">
<h1 className="text-2xl font-bold mb-6">Live Cricket Scores</h1>
<LiveScores initialData={initialMatches} />
</main>
);
}
Next.js App Router (Next.js 13+)
Using the new App Router with React Server Components:
// app/cricket/page.tsx
import { Suspense } from 'react';
async function getLiveScores() {
const res = await fetch('https://cricketliveapi.com/api/v1/live-scores', {
headers: { Authorization: `Bearer ${process.env.CRICLIVE_API_KEY}` },
next: { revalidate: 30 }, // Revalidate every 30 seconds
});
const data = await res.json();
return data.data || [];
}
export default async function CricketPage() {
const matches = await getLiveScores();
return (
<main className="max-w-2xl mx-auto p-6">
<h1 className="text-2xl font-bold mb-6">Live Cricket Scores</h1>
<Suspense fallback={<div>Loading...</div>}>
{matches.map((match: any) => (
<div key={match.match_id} className="border rounded-lg p-4 mb-4">
<h2 className="font-semibold">{match.teams}</h2>
<p className="text-green-600 font-bold">{match.score}</p>
</div>
))}
</Suspense>
</main>
);
}
Environment Variables Setup
# .env.local (Next.js)
CRICLIVE_API_KEY=your_api_key_here
NEXT_PUBLIC_CRICLIVE_API_KEY=your_api_key_here
# .env (React / Vite)
VITE_CRICLIVE_API_KEY=your_api_key_here
Available Endpoints for React/Next.js Apps
GET /api/v1/live-scores — All live matches
GET /api/v1/match/{id}/scorecard — Full scorecard
GET /api/v1/match/{id}/commentary — Ball-by-ball commentary
GET /api/v1/fantasy/points/{id} — Fantasy points
GET /api/v1/player/{id}/stats — Player statistics
GET /api/v1/series/{id}/schedule — Match schedule
Start Building Today
Get your free API key at cricketliveapi.com/register — 500 free calls/day, no credit card required.