Tiny Project I: DailyBread

Soliudeen Ogunsola
Soliudeen Case Studies
5 min readJun 1, 2024

--

The Chrome new tab extension I designed and built for personal use.

The idea of this project is to build a Chrome browser extension that shows whenever I open a new tab in my browser.

I worked on this project based on a few reasons:

I get to see the current day, date, and time directly in my browser tab because it might sound funny, but whenever I am focused on executing tasks, sometimes I lose track of the days of the week.

To have a centralized list of the essential apps I use frequently for my day-to-day activities and management of personal and work tasks. It allows me to access the essential apps or services I use frequently faster than having to type the URL every single time or load my browser history.

I want to pick up coding again for the nth time to enhance and complement my product design and management skills. Not many people know this, but I started out with HTML & CSS in 2014, got introduced to Android app development with Java and XML using Android Studio and NetBeans IDE in 2017, went back to frontend development a few months later, and eventually focused fully on product design in 2018.

I do write minor code for fixes to projects’ codebases sometimes, but I want to start building passion projects again whenever I have the time. With my design and product skills combined with a background in engineering and new innovation in generative AI (LLMs), I can now start to work on personal ideas from discovery to delivery again.

Design

It was easy to design the UI on Figma; the slightly more difficult part was finding and inserting the brand logos.

I had some UI elements from other projects I was involved in and reused them for this one. I used Iconify Design icon sets for the app/brand logos and the Phosphor icon pack for other icons like search and double caret.

DailyBread — Chrome New Tab Extension UI

Development

I built the entire project with HTML, CSS, and JavaScript, as it felt like the right option to achieve what I wanted.

File Directory

This is what the directory or folder structure for the project looks like in VS Code.

dailybread/
├── assets
├── index.html
├── script.js
└── styles.css

I have tried lots of IDEs or code editors in my journey, but I still go back to VS Code. I also enjoyed using Replit/CodeSandbox because I don’t have to install any dependencies locally, but I found some extensions that enable me to bring the same experience into VS Code, which was awesome.

HTML & CSS

This part was fun, and some of the code snippets can be found below.

Date & Time

The date and time elements show their current values and are updated every second/minute.

<div class="time-container">
<span id="time">00:00</span>
<span id="date">Day Month Year</span>
</div>

Search Bar

The search bar would allow anyone to enter what they want to search for and toggle or switch between the available search providers like Google Search, Perplexity AI, and Exa AI.

 <div class="search-container">
<img src="assets/search.svg" alt="Search" class="search-icon">
<input type="text" id="searchInput" placeholder="Search...">
<div class="search-provider">
<span id="searchProvider">Google</span>
<img src="assets/arrow.svg" alt="Arrow" class="arrow-icon">
</div

Apps

I added a grid of apps I use daily, allowing me to easily access them from the tab. Each of the apps is inside a 60×60 container, with the icons being 24×24.

<div class="apps-section">
<h2 class="apps-title">Apps</h2>
<div class="app-container">
<a href="https://www.deeja.co/" target="_blank" class="app-icon-container">
<img src="assets/app/deeja.svg" alt="Deeja" class="app-icon">
</a>
<!-- Add more apps here -->
</div>
</div>

I added a :hover pseudo-class selector that targets the app-icon element when the user hovers over it with the mouse cursor.

.app-icon:hover {
transform: scale(1.1);
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);
}

JavaScript

I wrote JavaScript functions that do the following:

Update the time and date using the user’s local time and date, set the time to a 24-hour format, and show the date to include the day of the week, the day, month, and year.

function updateTimeAndDate() {
const now = new Date();
const options = { hour12: false, hour: '2-digit', minute: '2-digit' };
const timeString = now.toLocaleString([], options);
const monthNames = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
const month = monthNames[now.getMonth()];
const day = now.getDate();
const year = now.getFullYear();
const dayOfWeek = now.toLocaleString([], { weekday: 'long' });
const dateString = `${dayOfWeek}, ${day} ${month} ${year}`;
document.getElementById('time').textContent = timeString;
document.getElementById('date').textContent = dateString;
}

Update the time and date every second.

setInterval(updateTimeAndDate, 1000);

Search the data/query the user entered into the search input field.

function handleSearchInput(event) {
if (event.key === "Enter") {
const searchQuery = event.target.value.trim();
const searchProvider = document.getElementById("searchProvider").textContent;
if (searchQuery) {
let searchUrl;
if (searchProvider === "Google") {
searchUrl = `https://www.google.com/search?q=${encodeURIComponent(searchQuery)}`;
} else if (searchProvider === "Perplexity") {
searchUrl = `https://www.perplexity.ai/search?q=${encodeURIComponent(searchQuery)}`;
} else if (searchProvider === "Exa.ai") {
searchUrl = `https://www.exa.ai/search?q=${encodeURIComponent(searchQuery)}`;
}
if (searchUrl) {
window.open(searchUrl, "_blank");
}
}
}
}

Handle the behaviour of switching between the search providers when the user clicks on the search provider text.

 const searchProvider = document.getElementById("searchProvider");
const searchProviders = ["Google", "Perplexity", "Exa.ai"];
let currentProviderIndex = 0;
searchProvider.addEventListener("click", () => {
currentProviderIndex = (currentProviderIndex + 1) % searchProviders.length;
searchProvider.textContent = searchProviders[currentProviderIndex];
});

Attach the event listener for the search input once the DOM is fully loaded.

document.addEventListener('DOMContentLoaded', function() {
const searchInput = document.getElementById('searchInput');
searchInput.addEventListener('keydown', handleSearchInput);
});

Bugs and Fixes

I used Claude, ChatGPT, and Perplexity AI as my copilots to find answers to bugs or issues I encountered and get them fixed.

Packaging the Files

Loading an unpacked extension into the Chrome developer mode requires some configurations, such as creating a manifest file and an icon directory, among others.

Manifest JSON file

The manifest.json code looks like this:

{
"manifest_version": 3,
"name": "DailyBread",
"version": "1.0",
"description": "Start your day with essential apps on your browser tab.",
"chrome_url_overrides": {
"newtab": "index.html"
},
"permissions": [],
"icons": {
"16": "icons/icon16.png",
"32": "icons/icon32.png",
"48": "icons/icon48.png",
"128": "icons/icon128.png"
}
}

Icons

I created an icon directory/folder and resized the project icons to 16×16, 32×32, 48×48, and 128×128.

icons/
├── icon16.png
├── icon32.png
├── icon48.png
└── icon128.png

Publishing to Chrome Web Store

It’s all fun and games until I realized that I have to pay $5 to register as a Chrome extension developer.

I eventually paid for the account, compressed the project folder into a ZIP file, filled out the required information to submit the extension for review, and it finally got published in less than 24 hours of submission.

Here’s the link to my DailyBread extension on the Chrome web store. You can install or add it to your Chrome browser today.

Demo

I recorded a short demo to show how it works.

DailyBread Chrome Extension Demo

Hi, thanks for reading this piece! I’m Soliudeen Ogunsola. If you find this article interesting and want to connect with me, you can follow me on X (formerly known as Twitter) or check me out on LinkedIn.

--

--