Coding a chrome extension in 11 hours!
Tags: webdev, javascript, programming, opensource
Published: 2024-02-05 13:30:00

Last week, I decided to develop a [Chrome extension](https://chromewebstore.google.com/detail/emoji-menu/giigikccmmlipmbjglfppcbcllnafimi). My primary motivation was to build an extension from scratch to improve my knowledge and fill some gaps. I had the knowledge to work on extensions due to my contribution to open-source projects like [OpenSauced](https://github.com/open-sauced/ai/pulls?q=is%3Apr+author%3A%40me+sort%3Aupdated-desc+is%3Aclosed) and [Refined-GitHub](https://github.com/refined-github/refined-github/pulls?q=is%3Apr+author%3A%40me+sort%3Aupdated-desc+is%3Aclosed). My only issue was that I needed to learn how to make an extension from scratch. Not knowing how to make a Chrome extension from scratch ignited the fire of this journey! In this blog, I am sharing the process I had during that week to build a Chrome extension and learn the technology behind it.

My initial plan was simple: have a continuous system that I would follow during the next few days. I did not know what I would do, but I decided to have at least one hour a day for this project. I should not pass this one hour no matter what will happen. This rule was the best decision I had, leading me to even code at midnight when no one was there.

Besides that, I decided to [livestream my experience](https://www.youtube.com/playlist?list=PL5RA-ZnFo9FPpmkiHs4sS_8sC7tnxHTMY), which was helpful to have a feeling of being an accountability partner and building the accountability system that I needed, even though I would expect no one to watch it. Yet, to my surprise, I gained a friend through that stream and had a few people joining it during that week.

## The blog structure

In this blog, I am writing a coverage of the engineering and thought process of every day I worked on this extension.  After covering the engineering process as a newbie, I write a few thoughts about the experience and how I would have done that differently based on the knowledge I gained during this journey. At the end of the paragraphs, I am adding two  links: 

- one for the live stream related to that day
- The other link is for the version of the emoji extension on GitHub.

## The skills

To build a Chrome extension, you need to know about web development in general. Web development basics mean JavaScript, HTML, CSS, and Web APIs. Besides that, you will need to learn the extension API. If you have the former, it's straightforward to acquire the latter based on your experience and learn it while building your Chrome extension, which I have done during this journey.

## The idea:

I don't know how the idea crossed my mind. I believe it's related to my frequent use of GitHub and improving writing skills over time, like using emojis on issue writing and seeing the impact of emoji-full issues, which made me think about the value of emojis and how to use them in other places. GitHub shows emojis to select from when you write a colon (:), and it allows you to choose from them. Some other companies adopted this, but I did not find it in [Dev.](http://dev.to/)to or Twitter, which is why I thought of working on it. It mostly came when I wanted to update an article I published on [dev.](http://dev.to/)to with some emojis but could not add them effortlessly.

GitHub In-text emoji picker: 


![GitHub In-text emoji picker](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9brh1df4iatbvyd8zaaf.png)


## Day 1 (90 minutes): Getting started

At this point, I knew the idea but needed to figure out how to start. Therefore, I chose the official documentation to follow and see what I could do from there. I followed the official documentation because it would make the engineering and coding easier for you and let you know your blind spots and how to cover them later.

Initially, I just used one of the [tutorials](https://developer.chrome.com/docs/extensions/get-started/tutorial/scripts-activetab) that Google provided. I chose that tutorial specifically since it's the closest to my end project. The first step was to read the tutorial without applying it to understand the result and a few concepts. Then, I used that tutorial on my machine and ran it. The reason to apply the tutorial first is to make sure that It's working and nothing is broken.

After ensuring everything worked well, I started working on a simple version of the extension. In this version, I wanted to ensure that I was adding an emoji to the text area from the extension. The emoji was predefined, and I had no complex logic here. Simplicity ensures I have the extension working well with the minimum version.

After getting that logic working, I next wanted a menu to select the emojis from it. I started with a simple menu that I made in HTML, tested it on a page, and then used that as my reference to the webpage. I only wanted to see the menu on screen without any expectations. After getting that to work, I used event listeners to get the text from the menu and write it in the text area to see if it worked. With this, I ended the day after adding the code to GitHub and uploading it there.

With this development, I was sure of three things about the extension:

- It's working,
- It adds emojis to the text area.
- I can see the static emoji menu
- It's getting the emojis from the menu.

With that, all I felt was that the extension was almost ready. I needed minor improvements after that, yet my expectations needed to be corrected.

Here is the result that I got from day 1: 


![The first menu](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4zs37xh8i66bb5d7pjtj.png)


Reflection: 

Looking back at the code I have written and the logic I had, I am using the default HTML tags inside my CSS file to customize my emoji menu. This approach could be better since it would change all the elements on the page and have a weird view. Here is an example from [Dev.to](http://Dev.to) 

Besides that, I am using a background script to inject the CSS file and the JS code, which I could have done directly by using content scripts instead of injecting it with a background file. The content scripts file will allow you to inject the code immediately without the need to do that manually.

- [V0.0.0](https://github.com/a0m0rajab/Emoji-Menu/releases/tag/V0.0.0)
- [Livestream](https://www.youtube.com/live/TJ_9LqiDiQs?si=nfSLt_W0nd7DzJ6S)

## Day 2 (80 minutes): exploring emoji search APIs

After my development on day 1, I was ready to consume an API to use it in the extension. I used something available online instead of working on my API backend project to save time. If an Emoji API provider were unavailable, I would have needed to work on that, too! I started by quickly searching on such an API, then checked the options and used one: https://emoji-api.com/. The reasons to use that API are:

- It's free,
- It has a search feature.
- Simple and well-documented.

I used the API and explored it through Postman, which makes things easier than just going through, writing a related code, and using it. Using Postman helps me understand what's happening in the API endpoints without struggling to write the code.

After ensuring I had the access key to the API and it was working, I worked on adding this to the extension. The basic idea I thought about was to have a search bar in the HTML menu and use it to search for emojis. The reason here is that I wanted to ensure that the API was working well, and I wanted to use something other than a regex parser from the text area. Narrowing down the development scope helps minimize my engineering land and make it focused and precise.


![The menu with search input](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/i9gk3ompttpc2j1p2nux.png)



At this point, I made a simple HTML page to test the design of the menu that I would like to have and see the results. Since the Chrome extensions are another web page, I applied the logic on this page to transfer my knowledge to the extension code. The HTML page did not work with the API due to the CORS policy; for that reason, I decided to make minor tweaks to improve the UI of the menu.


![The before and after style of the menu](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u7aqx688v7hcl0fosoyb.png)



Reflection: 

If I redo this, I would use a JavaScript library with emojis instead of looking for an API. This would make it better for the user and keep the extension independent from third-party APIs and from the internet. 

- [v0.0.1](https://github.com/a0m0rajab/Emoji-Menu/releases/tag/V0.0.1)
- [Livestream](https://www.youtube.com/live/id40PS7VCyY?si=WwrHHmhy8uc9U3k1)

## Day 3 (105 Minutes): implementing the emoji search API

On this day, I started by having my test page. The test page will help me check the extension on isolation from other websites. The reason was that when I used the extension with [Dev.to](http://dev.to/) test on the previous day, there was an issue in triggering [Dev.to](http://dev.to/) own events and publishing the comments by mistake. Having my test page would prevent such problems.


![The menu in the textarea](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g6p9eo5ltiakq8gnljjg.png)


Today, I discovered that I could use the API without getting a CORS by utilizing the service workers of the Chrome extension. I implemented that logic and fetched the emojis from the API, and at the same time, I had minimal parsing logic to get the colons from the text area and then use that. I used the previous logic as an initial scaffold to improve the work.

As for the parsing, I have used ChatGPT to ask for a way to parse the text after the colons, which gave me a good result, and I have used it in the project after minor tweaking.

After getting the parsing and the results I wanted, I made minor improvements to the code while getting the results from the API.

- [v0.0.2]([https://github.com/a0m0rajab/Emoji-Menu/releases/tag/V0.0.](https://github.com/a0m0rajab/Emoji-Menu/releases/tag/V0.0.1)2)
- [Livestream](https://www.youtube.com/live/qr-EMQAhS9s?si=QNRSGcHhOaYPYhXB)

## Day 4 (80 minutes): UX improvements

On this day, I improved the previous minor errors, like the search, the parsing, and the multiple menu lists injected into the code, mainly improving the previous logic and polishing things. One of the significant improvements I made today was replacing the text used for searching with the related emojis.

The main improvement here was exploring the option of having the emoji menu under the written text; this would allow a better UX/UI experience for the user. The initial experiments with ChatGPT help did not work and stopped at this point.

- [v0.0.3](https://github.com/a0m0rajab/Emoji-Menu/releases/tag/V0.0.3)
- [Livestream](https://www.youtube.com/live/TiwCfyksqqQ?si=Ymn15FNfj2WFCHnt)

## Day 5 (60 minutes): Minor Fixes and exploring

On this day, I started fixing the names in the extension using RegEx. I decided to use the https://regexr.com/ website and write my own, then compare it with what ChatGPT would show me. Then, I improved the event handling for the menu when someone clicks on the emoji or the text itself. Ultimately, I worked on the CSS to improve the visibility of the emoji names in the text provided.


![A gif showing the extension](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b22uszla3gt1zg5272u4.gif)


The next challenge was adding the menu on the place of the text instead of letting it float randomly. This challenge allowed me to research and see what options we could use. I found two exciting resources: one was by [Dan Dascalescu](https://stackoverflow.com/questions/29709/how-do-i-get-the-x-y-pixel-coordinates-of-the-caret-in-text-boxes), and the other was by [Amjad Masaad](https://stackoverflow.com/questions/56985866/get-x-y-coordinates-of-cursor-while-typing-in-text-area?rq=3), the founder of Replit. I read their codes and decided to use them the next day.

In the remaining time, I just went to fix a minor issue in the text parsing, which was related to not detecting the spaces after the command and showing the menu even after having a space. With that, I called it a day and just went to work.

- [v0.0.4](https://github.com/a0m0rajab/Emoji-Menu/releases/tag/V0.0.4)
- [livestream](https://www.youtube.com/live/oG5u8WsJhVE?si=ca-mnyzLeyTi3qZ5)

## Day 6 (120 minutes): Adding Menu Under Cursor

Today, I just added the emoji menu after the cursor, which was a straightforward experience by looking at Dan and Amjad's solutions. After getting the position of the menu correct and adding an improved version of the text parser, I get the latest text after the colons. I decided to search and see how to publish the Chrome extension to the Chrome store.

At this point, I decided to test the latest improvements that I had in the extension on [Dev.to](http://dev.to/) since I have been testing it on the test page that I created, I figured out that I need to improve my event handling in the extension and have it for the whole window instead of just adding one to each element. Then, I tried to use the extension on Twitter and found out that they used a div for everything they have in the UI, which is why the extension broke.

I ended the day by having the issues I needed to work on for the next day, enabling the extension on Twitter and pushing the extension to the market.

- [v0.0.5](https://github.com/a0m0rajab/Emoji-Menu/releases/tag/V0.0.5)
- [Livestream](https://www.youtube.com/live/ReRnqeq7q8U?si=jRN6pfKGjykjwP36)

## Day 7 (65 minutes): Publishing Day

Today, I went through the publishing process on Google Store, which was lengthy due to the legal parts and the requirements I needed to explain the extension's purpose to Google, the functions' purposes, etc.

After that, I started to discover Twitter and see what I could do to enable the extension on Twitter and run it on their website; this will be a great addition to the extension since it will allow the tech community on Twitter to use emojis more. The Twitter div logic was different, which made me go to a fully exploring and inspecting mode for the day to see what I could do to enable the extension on Twitter.

- [v0.0.6](https://github.com/a0m0rajab/Emoji-Menu/releases/tag/V0.0.6)
- [Livestream](https://www.youtube.com/live/KLXIhO4w1Y4?si=plVWGLCCjSf6q1tA)

## Day 8 (70 minutes): Handling Twitter

On Twitter, I faced an issue with the extension: not showing the extension on top of Twitter buttons. I have tried multiple options but am still trying to get what I wanted. I wrote a question on StackOverflow about the issue to get help from the community. At this point, I was unaware of HTML's stacking context logic. Still, I guessed the development: if I always had the extension attached to the body, it would never be hidden behind anything, making me have to refactor the code to run the add menu.

One of the things I did today was enable the extension to use elements that are not text areas and show the emoji menu even when you scroll the screen; this would make things stable for users. With that, I ended the day.

- [v0.0.7](https://github.com/a0m0rajab/Emoji-Menu/releases/tag/V0.0.7)
- [Livestream](https://www.youtube.com/live/94bsQiYnhPg?si=xDpctuLl-yr9lP03)

## Future development:

With all of that, I still feel that the extension needs some improvement to be fully ready for a launch. This development would be: 

- Handling twitter logic,
- Having a better UI
- Replacing the emoji API with a JavaScript library
- Moving to npm

## Lessons:

From this experiment, I learned the value of having a semi-strict routine. Such a routine would help you to achieve more and gain a better experience. Besides that, I learned how to build a Chrome extension from scratch and what I can do in the future. I hope that you enjoyed the article. 


If you want to try the chrome extension feel free to download it from this [link](https://chromewebstore.google.com/detail/emoji-menu/giigikccmmlipmbjglfppcbcllnafimi). 

Let me know in the comments if you have had such an experiment! and remember to follow me on Twitter.