Skip to main content

File Structure

Knowledge Tooltip is a lightweight Chrome extension with no build tools or dependencies. All code is vanilla JavaScript.
manifest.json      Chrome extension configuration (Manifest V3)
background.js      Service worker that handles all external API calls
content.js         Content script injected into pages (UI, events, rendering)
styles.css         All extension styles (tooltip, tabs, RTL support)
popup.html         Extension popup page (settings UI)
popup.js           Popup logic (toggle, language, API key management)
icons/             Extension icons (16, 48, 128px)
landing-page/      Project landing page (hosted separately)
PRIVACY_POLICY.md  Full privacy policy
The entire extension runs in the browser with no backend server. All API calls are made directly to third-party services.

Architecture Overview

The extension uses Chrome’s message passing system to separate concerns and avoid CORS issues:

Three-Layer Architecture

  1. Content Script (content.js) - Runs on every webpage
  2. Service Worker (background.js) - Handles API calls
  3. Popup UI (popup.js) - Manages settings
This architecture is required because content scripts cannot make cross-origin requests due to CORS policies. The service worker acts as a proxy.

Core Files

manifest.json

The extension manifest defines permissions, scripts, and metadata:
manifest.json
{
  "manifest_version": 3,
  "name": "Knowledge Tooltip",
  "version": "2.0.0",
  "permissions": [
    "activeTab",
    "storage"
  ],
  "host_permissions": [
    "https://en.wikipedia.org/*",
    "https://ar.wikipedia.org/*",
    "https://api.openai.com/*"
    // ... other API domains
  ],
  "background": {
    "service_worker": "background.js"
  },
  "content_scripts": [
    {
      "matches": ["<all_urls>"],
      "js": ["content.js"],
      "css": ["styles.css"]
    }
  ]
}
Key sections:
  • permissions - Chrome APIs the extension can use
  • host_permissions - External domains for API calls
  • background - Service worker registration
  • content_scripts - Scripts injected into webpages

background.js

The service worker handles all external API calls. It receives messages from content.js and returns data. Structure:
  • Message router that listens for chrome.runtime.onMessage
  • Async functions for each API (Wikipedia, Wiktionary, Wikidata, OpenAI)
  • Error handling and response formatting
Example message flow:
background.js
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
  if (message.action === 'fetchWikipedia') {
    fetchWikipediaData(message.term, message.language)
      .then(data => sendResponse({ success: true, data }))
      .catch(error => sendResponse({ success: false, error: error.message }));
    return true; // Keep channel open for async response
  }
});
The service worker may become inactive after periods of inactivity. It automatically restarts when a message is received.

content.js

The content script runs on every webpage and manages the tooltip UI and user interactions. Responsibilities:
  • Detect text selection and show floating button
  • Build and render the tooltip UI
  • Handle tab switching and caching
  • Send API requests to background.js
  • Render API responses in the appropriate tab
  • Handle bilingual UI (English/Arabic)
Key components:
content.js
// State management
let tooltip = null;
let cache = new Map();
let isEnabled = true;
let preferredLanguage = 'auto';

// Tab definitions
const TABS = [
  { id: 'summary', label: 'Summary', labelAr: 'ملخص' },
  { id: 'define', label: 'Define', labelAr: 'تعريف' },
  { id: 'facts', label: 'Facts', labelAr: 'حقائق' },
  { id: 'ai', label: 'AI', labelAr: 'ذكاء' },
  { id: 'translate', label: 'Translate', labelAr: 'ترجمة', beta: true }
];
Message passing:
content.js
// Send request to background script
chrome.runtime.sendMessage(
  { action: 'fetchWikipedia', term: selectedText, language: 'en' },
  (response) => {
    if (response.success) {
      renderSummary(response.data);
    }
  }
);

styles.css

Contains all extension styles including:
  • Floating button styles
  • Tooltip container and backdrop
  • Tab navigation and content areas
  • Loading states and animations
  • RTL (right-to-left) support for Arabic
  • Responsive design
Key features:
  • CSS variables for consistent theming
  • Scoped styles to avoid conflicts with page styles
  • Animations for smooth transitions
  • RTL layout with [dir="rtl"] selectors
The extension popup provides a settings interface: Settings:
  • Enable/disable toggle
  • Language preference (auto-detect, English, Arabic)
  • OpenAI API key management (add/remove)
Storage:
  • Preferences stored in chrome.storage.sync (synced across devices)
  • API key stored in chrome.storage.local (never synced)
popup.js
// Save settings
await chrome.storage.sync.set({ enabled: true, language: 'auto' });

// Store API key locally only
await chrome.storage.local.set({ openaiKey: 'sk-...' });

// Broadcast changes to all tabs
const tabs = await chrome.tabs.query({});
tabs.forEach(tab => {
  chrome.tabs.sendMessage(tab.id, {
    action: 'toggleExtension',
    enabled: true
  });
});

Data Flow

User Selects Text

1

Selection Detection

User highlights text on a webpage. content.js detects the selection and shows a floating button.
2

User Clicks Button

User clicks the button. content.js creates the tooltip UI and automatically loads the Summary tab.
3

API Request

content.js sends a message to background.js requesting Wikipedia data:
chrome.runtime.sendMessage({
  action: 'fetchWikipedia',
  term: 'Albert Einstein',
  language: 'en'
});
4

Background Fetches Data

background.js receives the message, calls the Wikipedia API, and sends the response back:
const response = await fetch('https://en.wikipedia.org/api/...');
const data = await response.json();
sendResponse({ success: true, data });
5

Content Renders Result

content.js receives the data and renders it in the tooltip:
  • Summary with thumbnail and link
  • Caches result for future use
  • Handles errors gracefully

Tab Switching

When a user switches tabs:
  1. Check if data is cached for this tab
  2. If cached, render immediately
  3. If not cached, show loading state
  4. Send request to background.js for the appropriate API
  5. Render response and cache it
The extension caches up to 30 recent queries to minimize API calls and improve performance.

Extension APIs Used

chrome.runtime

  • chrome.runtime.sendMessage() - Send messages between scripts
  • chrome.runtime.onMessage - Listen for messages

chrome.storage

  • chrome.storage.sync - Synced preferences (enabled, language)
  • chrome.storage.local - Local-only secrets (API key)

chrome.tabs

  • chrome.tabs.query() - Get list of tabs
  • chrome.tabs.sendMessage() - Send messages to content scripts

External APIs

TabAPIEndpointKey Required
SummaryWikipedia REST APIen.wikipedia.org/api/rest_v1/No
SummaryWikipedia Search APIen.wikipedia.org/w/api.phpNo
DefineWiktionary REST APIen.wiktionary.org/api/rest_v1/No
DefineFree Dictionary APIapi.dictionaryapi.dev/api/v2/No
FactsWikidata Searchwww.wikidata.org/w/api.phpNo
FactsWikidata Entitieswww.wikidata.org/wiki/Special:EntityData/No
AIOpenAI Chatapi.openai.com/v1/chat/completionsYes
TranslateOpenAI Chatapi.openai.com/v1/chat/completionsYes
All API calls are made directly from the browser. There is no backend server.

Next Steps

Development Setup

Set up your local development environment

Contribution Guidelines

Learn how to contribute code

Build docs developers (and LLMs) love