Today we'll be building a simple chrome extension which is based on web technologies. It uses HTML, CSS and JavaScript and once, we build it, it will track live Bitcoin prices!
Here's how it will look like:
Here's the source code.
Part 1: Prerequisites
You should have a beginner understanding of:
- HTML
- CSS
- JavaScript
If you're having trouble, feel free to ask me or anyone in the Hack Club Slack!
Part 2: Setup
For writing our code, we'll be using Repl.it but later, we'll need to download it inorder to test our extension.
To get started, go to this HTML starter code.
Part 3: Building the project
1) The Manifest
If there is something which is really important for any chrome extension, then it is the manifest.json
file. Without it, we can't create any extensions. So let's first create our manifest.json
file!
First, click on 'Add file'
.
Then, name your file as manifest.json
.
Let's now start writing the json. First, we need to create an empty object ({}
). Then, inside that, we'll first create a name
key, then the manifest_version
and so on.
{
"name": "BitEx",
"manifest_version": 2,
"version": "1.0",
"description": "Chrome Extension which tracks Bitcoin prices",
"browser_action": {
"default_name": "BitEx",
"default_icon": "icon.png",
"default_popup": "index.html"
},
"permissions": []
}
Explanation: The manifest_version
will be 2 according to chrome's documentation as manifest_version
1 was deprecated in Chrome 18. The version
is your extension's version. If you roll out updates to your extension, the version number increases.
Now, we are going to have our extension's icon in the main Google Chrome toolbar and also have a popup UI for our extension, therefore we will use the browser_action
.
If you want to create an icon that isn't always visible, use a page action
instead of a browser action
.
Next, the browser_action
will need the default_name
, default_icon
and the default_popup
values for our extension to work. (Although these values are optional but for our case, we need them.)
NOTE: You can download the icon which I used here.
We don't need any permissions for our extension so we'll keep it as empty.
And with this, we finish building our manifest!
2) HTML
Let's start building the UI for our extension. Building an extension's UI is no different than building a website! So let's start writing the HTML!
<body>
<div>
<h1 class="title">Bitcoin Price Tracker</h1>
<img src="./bitcoin.png" alt="bitcoin logo">
<div class="bitcoin">Loading...</div>
</div>
<script src="index.js"></script>
</body>
NOTE: Download bitcoin.png
from here and simply drag and drop it into your repl!
We simply create a div
element containing a heading, an image and also another div
which will display Loading...
for now.
You should see something like this in your preview window:
What mess have we created! It definitely needs some styles! Let's add CSS in the next section!
3) CSS
Let's start by importing a few fonts, then adding styles to each elements!
@import url('https://fonts.googleapis.com/css2?family=Sansita+Swashed:wght@300;400;500;600;700&display=swap');
@import url('https://fonts.googleapis.com/css2?family=Merriweather:wght@300;400;700&display=swap');
body {
min-width: 450px;
background-color: #f4f4f4ee;
color: #0e0e0e;
text-align: center;
}
h1 {
font-family: 'Sansita Swashed', cursive;
font-size: 28px;
letter-spacing: 1px;
}
img {
display: block;
margin: 0 auto;
width: 76px;
}
Explanation: First, we import two fonts namely, Sansita Swashed
and Merriweather
from fonts.google.com. Then, the HTML body
has a minimum width of 450px, a background color, a text color and all the text is aligned to center
.
Similarly, the heading tag uses the font family Sansita Swashed
and has a font size of 28px. There is also a letter spacing set to 1px.
The bitcoin logo image is set to display: block
so that we can align it to center using margin: 0 auto
. As it was a very large image, we also set its width to 76 pixels.
Let's also set some styles to the <p>
tag with the class of bitcoin
.bitcoin {
font-family: 'Merriweather', serif;
font-size: 22px;
}
Here, we simply set its font family to Merriweather
and its font size is set to 22px.
Yay! Now we have a far better UI compared to what we had earlier!
4) JavaScript
Now we will use JavaScript to fetch the realtime Bitcoin prices and then to show it on the browser screen instead of showing Loading...
all the time. First, navigate to your index.js
file and let's start writing!
const div = document.querySelector(".bitcoin");
const url =
"https://api.coingecko.com/api/v3/coins/markets?vs_currency=usd&ids=bitcoin%2Cbitcoincash%2Cethereum%2Clitecoin%2Cbinancecoin%2Cripple&order=market_cap_desc&per_page=100&page=1&sparkline=false&price_change_percentage=24h";
let data;
We select the div
tag with the class of bitcoin
using querySelector()
and assign it to the div
variable. The querySelector()
method returns the first element that matches a specified CSS selector(s) in the document.
Learn more about querySelector()
.
Then, we assign the API URL from where the data will be fetched to the variable url
. We also create a data
variable where we'll store the fetched data later.
Now, let's fetch the data from that url
.
async function fetchData() {
try {
const res = await fetch(url);
data = await res.json();
} catch (err) {
console.error(err);
}
}
Explanation: We first create an async function
and then by using the try-catch
blocks, the response we receive is stored inside the res
variable. Then, after converting this response to json
format, it is then stored into the data
variable. As usual, the fetch
API returns a promise and to handle that promise, we used the async-await
syntax.
If there's any error, it will simply get console logged.
Learn more about async-await
.
[ { id: 'bitcoin',
symbol: 'btc',
name: 'Bitcoin',
image: 'https://assets.coingecko.com/coins/images/1/large/bitcoin.png?1547033579',
current_price: 19327.06,
market_cap: 357299782216,
market_cap_rank: 1,
fully_diluted_valuation: 404286280236,
total_volume: 41738893348,
high_24h: 19832.27,
low_24h: 18338.09,
price_change_24h: -257.1378091,
price_change_percentage_24h: -1.31299,
// ...
last_updated: '2020-12-01T15:05:30.303Z',
price_change_percentage_24h_in_currency: -1.3129860318628117 },
{
// ...
}
We get an array of data about various cryptocurrencies! From this, we'll make use of the current_price
value and the price_change_percentage_24h
value of Bitcoin!
Now, let's create a function which will extract these values and add them to the DOM!
Also an important thing to keep in mind is that the price_change_percentage_24h
can be negative or positive. So we'll need to check that and display it in a green color or a red color accordingly.
function showPrices() {
if (data[0].price_change_percentage_24h > 0) {
// Gentle Reminder: We are using backticks below and not quotes.
div.innerHTML =
`<p>1 BTC = $${data[0].current_price}</p>
<p class="increased">
<span>
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 15l7-7 7 7" />
</svg>
</span>
${data[0].price_change_percentage_24h}%
</p>`;
}
}
Explanation: We simply check if the price_change_percentage_24h
is greater than 0 or not. If this is true, we start to add various <p>
tags inside the <div>
tag.
NOTE: Using backticks (``) allows you to inject HTML elements in the DOM using JavaScript, and that's exactly what we do in the above code.
In the first <p>
tag, we render bitcoin's current price. Next, we create a <p>
tag with a class of increased
in which we create a <span>
containing a 'chevron up'
svg and next to it, we show the price change percentage.
Similarly, we will add an else
condition which will do the rendering if the price_change_percentage_24h
is negative.
function showPrices() {
if (data[0].price_change_percentage_24h > 0) {
// ...
} else {
div.innerHTML =
`<p>1 BTC = $${data[0].current_price}</p>
<p class="decreased">
<span>
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7" />
</svg>
</span>
${data[0].price_change_percentage_24h}%
</p>`;
}
}
Explanation: Everything seems similar here, except the class of the <p>
element is now as decreased
and the svg we now use is 'chevron down'
.
Now let's call this function once all the data is fetched.
async function fetchData() {
try {
const res = await fetch(url);
data = await res.json();
showPrices(); // Calling the showPrices() function!
} catch (err) {
console.error(err);
}
}
And lastly, call the fetchData()
function at the very last line of the document!
Your JavaScript code so far:
const div = document.querySelector(".bitcoin");
const url =
"https://api.coingecko.com/api/v3/coins/markets?vs_currency=usd&ids=bitcoin%2Cbitcoincash%2Cethereum%2Clitecoin%2Cbinancecoin%2Cripple&order=market_cap_desc&per_page=100&page=1&sparkline=false&price_change_percentage=24h";
let data;
async function fetchData() {
try {
const res = await fetch(url);
data = await res.json();
showPrices();
} catch (err) {
console.error(err);
}
}
function showPrices() {
if (data[0].price_change_percentage_24h > 0) {
div.innerHTML = `<p>1 BTC = $${data[0].current_price}</p>
<p class="increased">
<span>
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 15l7-7 7 7" />
</svg>
</span>
${data[0].price_change_percentage_24h}%
</p>`;
} else {
div.innerHTML = `<p>1 BTC = $${data[0].current_price}</p>
<p class="decreased"><span><svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7" />
</svg></span>${data[0].price_change_percentage_24h}%</p>`;
}
}
fetchData();
If you RUN
this code, you should see something like this!
We haven't yet implemented the CSS for the classes increased
and decreased
due to which we don't see the green/red color for the price change percentage. Let's do that finally!
5) CSS, again
Head back to style.css
again and let's add styles for those 2 classes.
.increased {
padding: 4px;
color: #4dbb79;
}
.decreased {
padding: 4px;
color: #f56565;
}
The increased
class gets a greenish color and similarly, the decreased
class gets a reddish color!
Now if you RUN
the code, you'll see that everything works perfectly as we expected!
And now its finally time to turn this into an extension!
6) Adding your extension to Chrome
First we'll need to download our code. For this, simply click on the 3 vertical dots on the left and select the option Download as zip
.
Once you have download the zip file. Extract it. It will then give you a folder of your repl's name with our code inside!
Next, navigate to chrome://extensions
in your chrome browser. You'll see a list of all your installed extensions!
On the top right corner, make sure you have Developer mode
turned on. If not, make sure you turn it on!
Now you'll see 3 new options popped up! Click on the Load unpacked
option and select the folder containing your code!
And there we go! We successfully installed our extension into our chrome browser! Now you'll be able to see your extension's icon in the chrome toolbar!
Part 4: The End
Yay! We successfully built a wonderful chrome extension which tracks Bitcoin prices!
If you have a developer account, feel free to publish it on the chrome web store! Here's how.
Here are some helpful links:
Here are some tasks for you:
-
Create an extension which shows the current prices for top 5 cryptocurrencies.
Example -
Want to censor/highlight any words on websites you browse? You can create an extension for that too!
Example where it highlights the wordHack Club
on websites. -
Create a chrome extension which displays the historical data for Bitcoin using this API.
Example -
Create a chrome extension which shows the past prices of any cyptocurrency of any given date(s)!
-
Add a feature which alerts you if there is a big price drop!
Now that you have finished building it, you should share your beautiful creation with other people! (I can't wait to see you ship this!)
You probably know the best ways to get in touch with your friends and family, but if you want to share your project with the worldwide Hack Club community there is no better place to do that than on Slack.
- In a new tab, open and follow these directions to signup for our Slack.
- Then, post the link to the
#ship
channel to share it with everyone and also ping me!
PS. I'm @fayd
on slack.