Open In App

Cryptocurrency Tracker with Next.js and API

The cryptocurrency tracker is a web application built using NextJS that allows users to monitor the prices and other relevant information such as market cap, current price, total supply, and more for your favorite cryptocurrencies. The application provides a user-friendly interface for users to explore and track their favorite cryptocurrencies. Users can search for specific cryptocurrencies, and view detailed information about each cryptocurrency.

Output Preview: Let us have a look at how the final output will look like.



Prerequisites:

Approach to Create Cryptocurrency Tracker:

Steps to Create the Cryptocurrency tracker Application:

Step 1: Create a application of NextJS using the following command.



npx create-next-app cryptocurrency-tracker

Step 2: Navigate to project directory

cd cryptocurrency-tracker

Step 3: Install the necessary package in your project using the following command.

npm install bootstrap

Step 4: Create the folder structure as shown below and create the files in respective folders.

Project Structure:

project structure

The updated dependencies in package.json file will look like:

"dependencies": {
"axios": "^1.6.7",
"bootstrap": "^5.3.0",
"chart.js": "^4.4.2",
"next": "14.1.0",
"react": "^18",
"react-dom": "^18"
}

Example: Below are the components which describes the implementation of the Cryptocurrency tracker.




// page.js
 
import React from 'react'
import CrptoList from '../Components/CryptoList';
const page = () => {
    return (
        <div>
            <CrptoList />
        </div>
    )
}
 
export default page




// Components/CryptoList.js
 
'use client';
import React, { useState, useEffect } from 'react';
import 'bootstrap/dist/css/bootstrap.min.css';
import axios from 'axios';
import Link from 'next/link';
import Navbar from './Navbar';
 
const CryptoTracker = () => {
    const [data, setData] = useState([]);
    const [searchQuery, setSearchQuery] = useState('');
 
    useEffect(() => {
        const fetchData = async () => {
            try {
                const response = await axios.get(
                setData(response.data);
            } catch (error) {
                console.error('Error fetching data:', error);
            }
        };
        fetchData();
    }, []);
 
    const handleSearchChange = (event) => {
        setSearchQuery(event.target.value);
    };
 
    const filteredData = data.filter((crypto) => {
        return crypto.name.toLowerCase().includes(searchQuery.toLowerCase());
    });
 
    return (
        <>
            <Navbar />
            <div className="container">
                <h1 className="my-4 text-success">GeekForGeeks</h1>
                <input
                    type="text"
                    placeholder="Search crypto name"
                    className="form-control mb-4"
                    value={searchQuery}
                    onChange={handleSearchChange}
                />
                <table className="table">
                    <thead className="bg-dark">
                        <tr>
                            <th className="bg-info">Name</th>
                            <th className="bg-info">Symbol</th>
                            <th className="bg-info">Price</th>
                            <th className="bg-info">Market Cap</th>
                            <th className="bg-info">1h change</th>
                            <th className="bg-info">24h change</th>
                            <th className="bg-info">7D Change</th>
                        </tr>
                    </thead>
                    <tbody>
                        {filteredData.map((crypto) => (
                            <tr key={crypto.id}>
                                <td>
                                    <img
                                        src={crypto.image}
                                        alt={crypto.name}
                                        className="rounded-circle mr-2"
                                        style={{ width: '30px', height: '30px' }}
                                    />
 
                                    <Link href={`/crypto/${crypto.id}`}
                                        style={{
                                            textDecoration: 'none',
                                            color: 'inherit'
                                        }}>
                                        {crypto.name}
                                    </Link>
                                </td>
                                <td>{crypto.symbol.toUpperCase()}</td>
                                <td>₹{crypto.current_price.toFixed(2)}</td>
                                <td>₹{crypto.market_cap.toLocaleString('en-US')}</td>
                                <td style={{
                                    color: crypto.price_change_percentage_1h_in_currency < 0 ? 'red' : 'green'
                                }}>
                                    {Number(
                                        crypto.price_change_percentage_1h_in_currency
                                    ).toFixed(2)}%</td>
                                <td style={{
                                    color: crypto.price_change_percentage_24h_in_currency < 0 ? 'red' : 'green'
                                }}>
                                    {Number(
                                        crypto.price_change_percentage_24h_in_currency
                                    ).toFixed(2)}%</td>
                                <td style={{
                                    color: crypto.price_change_percentage_7d_in_currency < 0 ? 'red' : 'green'
                                }}>
                                    {Number(
                                        crypto.price_change_percentage_7d_in_currency
                                    ).toFixed(2)}%</td>
                            </tr>
                        ))}
                    </tbody>
                </table>
            </div>
        </>
    );
};
 
export default CryptoTracker;




// pages/crypto/[id].js
 
import React, {
    useState,
    useEffect
} from 'react';
import axios from 'axios';
import {
    useRouter
} from 'next/router';
import 'bootstrap/dist/css/bootstrap.min.css';
import Navbar from '@/Components/Navbar';
 
const CryptoDetails = () => {
    const router = useRouter();
    const { id } = router.query;
    const [cryptoData, setCryptoData] = useState(null);
 
    useEffect(() => {
        const fetchData = async () => {
            try {
                const response = await axios.get(
                    `https://api.coingecko.com/api/v3/coins/${id}`);
                setCryptoData(response.data);
            } catch (error) {
                console.error('Error fetching data:', error);
            }
        };
        if (id) {
            fetchData();
        }
    }, [id]);
 
    if (!cryptoData) {
        return <div className="container">Loading...</div>;
    }
 
    // Extract description up to the first period (.)
    const description = cryptoData.description.en.split('.')[0];
 
    return (
        <>
            <Navbar />
            <div className="container mt-5 d-flex justify-content-center">
                <div className="card">
                    <img src={cryptoData.image.small}
                        className="card-img-top img-fluid" alt=""
                        style={{ maxWidth: '200px' }} />
                    <div className="card-body">
                        <h1 className="card-title">{cryptoData.name}</h1>
                        <h5 className="card-text">{description}</h5>
                        <p className="card-text">
                            <b>Symbol:</b>
                            {cryptoData.symbol.toUpperCase()}
                        </p>
                        <p className="card-text">
                            <b>Rank:</b>
                            {cryptoData.market_cap_rank}
                        </p>
                        <p className="card-text">
                            <b>Market Cap:</b>
                            {cryptoData.market_data.market_cap.inr}
                        </p>
                        <p className="card-text">
                            <b>Current Price:</b>
                            {cryptoData.market_data.current_price.inr}
                        </p>
                        <p className="card-text">
                            <b>Total Supply:</b>
                            {cryptoData.market_data.total_supply}
                        </p>
                        <p className="card-text">
                            <b>Market Cap Change (24h):</b>
                            {cryptoData.market_data.market_cap_change_percentage_24h}%
                        </p>
                        <p className="card-text">
                            <b>High (24h):</b>
                            {cryptoData.market_data.high_24h.inr}
                        </p>
                        <p className="card-text">
                            <b>Low (24h):</b>
                            {cryptoData.market_data.low_24h.inr}
                        </p>
                        <p className="card-text">
                            <b>Total Volume (24h):</b>
                            {cryptoData.market_data.total_volume.inr}
                        </p>
                        <p className="card-text">
                            <b>Circulating Supply:</b>
                            {cryptoData.market_data.circulating_supply}
                        </p>
                    </div>
                </div>
            </div>
        </>
    );
 
};
 
export default CryptoDetails;




// Navbar.js
 
import Link from 'next/link';
 
const Navbar = () => {
    return (
        <nav className="navbar navbar-expand-lg
                         navbar-dark bg-dark">
            <div className="container">
                <Link className="navbar-brand" href="/">
                    CryptoTracker
                </Link>
                <button className="navbar-toggler"
                    type="button" data-bs-toggle="collapse"
                    data-bs-target="#navbarNav"
                    aria-controls="navbarNav"
                    aria-expanded="false"
                    aria-label="Toggle navigation">
                    <span className="navbar-toggler-icon"></span>
                </button>
                <div className="collapse navbar-collapse"
                    id="navbarNav">
                    <ul className="navbar-nav ms-auto">
                    </ul>
                </div>
            </div>
        </nav>
    );
};
 
export default Navbar;

Start your application using the following command.

npm run dev

Output: Naviage to the URL http://localhost:3000.


Article Tags :