Open In App

Cryptocurrency Tracker with Next.js and API

Last Updated : 07 Mar, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

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.

Screenshot-(485)

Prerequisites:

Approach to Create Cryptocurrency Tracker:

  • Setup the Project by Creating a new NextJS project Install the necessary libraries.
  • W will utilize useState and useEffect hooks to manage component state and side effects. For example, use useState to manage the cryptoData state and useEffect to fetch data from the API.
  • We will be using CoinGecko Api to fetch real time. we will make API requests using Axios to get cryptocurrency prices, market cap, and other relevant information.
  • Start building the frontend by Creating components for displaying cryptocurrency lists with some information.
  • Define dynamic routes to display the detail information regarding specific Crypto.
  • Implement Search functionality to allow user to look for specific crypto.

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:

Screenshot-(487)

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.

Javascript




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


Javascript




// 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;


Javascript




// 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;


Javascript




// 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.

gfg_crypto_tracker



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads