FluentRead Background Script Explained: How background.ts Powers the Extension
The FluentRead background script (background.ts) acts as the central orchestrator that manages context menus, tracks per-tab translation states, routes messages between content scripts and translation APIs, and handles Microsoft Translator authentication.
The background.ts file in the bistutu/fluentread repository serves as the persistent background script for this browser extension. Running either in a background page or service worker depending on the browser, it maintains the single source of truth for translation state across all open tabs while bridging the gap between the user interface and external translation services.
Core Responsibilities of the FluentRead Background Script
Context Menu Management
The background script creates and maintains the FluentRead context menu that appears when users right-click on web pages. In the main() function (around lines 60-84), it initializes the top-level "FluentRead" menu along with sub-items for Full-page translate and Restore original.
The updateContextMenus function dynamically enables or disables these menu items based on whether the current tab has an active translation. This ensures users cannot attempt to restore original text on a page that hasn't been translated, or translate a page that is already in translated state.
Per-Tab Translation State Tracking
FluentRead maintains a translation state map (translationStateMap) defined at line 6 of background.ts. This Map<number, boolean> structure maps each browser tab ID to a boolean indicating whether that tab currently displays translated content.
The background script consults this map whenever users switch tabs (onActivated), complete page loads (onUpdated), or close tabs (onRemoved). This persistent state management ensures the context menu always reflects the correct translation status regardless of how users navigate between tabs or reload pages.
Message Routing and API Coordination
The background script listens for browser.runtime.onMessage events starting at line 61, acting as the central router between content scripts, the popup interface, and translation services.
For input-box translations (triggered when users translate selected text), the script calls translateWithMicrosoftInBackground. This dedicated Microsoft Translator client runs in the background to bypass Firefox's CORS restrictions that would otherwise block direct API calls from content scripts.
For standard full-page translations, the background script forwards requests to the selected service via the _service map (_service[config.service]), delegating to the appropriate translation provider based on user configuration.
Microsoft Translator Token Management
The background script provides two critical helper functions for Microsoft Translator integration:
refreshMicrosoftTokenInBackgroundfetches a fresh JWT fromhttps://edge.microsoft.com/translate/authtranslateWithMicrosoftInBackgrounduses that token to call the Microsoft Translator Edge endpoint, returning the translated text
These helpers isolate CORS-prone network calls from content scripts, ensuring reliable translation functionality across Chrome, Firefox, and Edge while handling authentication token lifecycle management automatically.
Tab Lifecycle Synchronization
Starting at line 41, the background script registers listeners for tabs.onActivated, tabs.onUpdated, and tabs.onRemoved. These listeners ensure the translationStateMap and context menu status remain synchronized with the browser's actual tab state.
When a user switches to a different tab, the onActivated listener triggers updateContextMenus to show the correct menu state for that specific tab. When a page finishes loading (onUpdated with status: 'complete'), the script verifies whether the tab should maintain its translated state or reset to original.
Technical Implementation Examples
Creating Context Menu Items
The background script initializes the FluentRead menu structure during startup:
// Inside background.ts → main()
browser.contextMenus.create({
id: 'fluentread-parent',
title: 'FluentRead',
contexts: ['page', 'selection']
});
browser.contextMenus.create({
id: 'fluentread-translate',
title: 'Full-page translate',
parentId: 'fluentread-parent',
contexts: ['page']
});
Handling Input Box Translation Requests
When content scripts send translation requests for selected text, the background script processes them through the Microsoft Translator pathway:
// Message listener in background.ts
browser.runtime.onMessage.addListener(async (message, sender) => {
if (message.type === 'inputBoxTranslation') {
const result = await translateWithMicrosoftInBackground(
message.text,
message.targetLang
);
return { success: true, translatedText: result };
}
});
Managing Per-Tab Translation State
The background script maintains state consistency across browser navigation:
// Tab activation handler
browser.tabs.onActivated.addListener(async (activeInfo) => {
const isTranslated = translationStateMap.get(activeInfo.tabId) || false;
updateContextMenus(activeInfo.tabId, isTranslated);
});
// State update function
function updateContextMenus(tabId: number, isTranslated: boolean) {
browser.contextMenus.update('fluentread-translate', {
enabled: !isTranslated
});
browser.contextMenus.update('fluentread-restore', {
enabled: isTranslated
});
}
Integration with FluentRead Architecture
The background script coordinates with several other components in the bistutu/fluentread codebase:
entrypoints/service/_service.ts– Registry of all translation services; the background script forwards requests here based onconfig.serviceselectionentrypoints/utils/config.ts– Holds runtime configuration including the selected translation provider and target language preferencesentrypoints/utils/constant.ts– Defines constant IDs such asCONTEXT_MENU_IDSused throughout the background script for menu management
This architecture ensures the background script remains focused on orchestration while delegating specific translation logic to dedicated service modules and configuration utilities.
Summary
- The FluentRead background script (
background.ts) serves as the central orchestrator for the browser extension, running persistently to manage cross-tab functionality. - It maintains a
translationStateMap(aMap<number, boolean>) that tracks which tabs are currently translated, enabling accurate context menu states across browser navigation. - The script creates and manages context menus ("FluentRead", "Full-page translate", "Restore original") through the
updateContextMenusfunction, dynamically enabling items based on tab state. - It handles message routing between content scripts and translation APIs, including special CORS-bypassing logic for Microsoft Translator via
translateWithMicrosoftInBackground. - Tab lifecycle listeners (
onActivated,onUpdated,onRemoved) ensure state synchronization when users switch tabs, reload pages, or close tabs.
Frequently Asked Questions
What is the background script in FluentRead?
The background script in FluentRead is a TypeScript file (background.ts) that runs in a persistent background page or service worker, depending on the browser. It acts as the central coordinator for the extension, managing context menus, tracking translation states per tab, routing messages between content scripts and translation APIs, and handling authentication tokens for Microsoft Translator.
How does FluentRead track which tabs are translated?
FluentRead uses a translationStateMap defined in background.ts (line 6), which is a Map<number, boolean> that stores the translation status for each tab ID. When a user translates a page, the map updates to true for that tab ID. The background script consults this map whenever tabs are activated, updated, or removed to ensure context menus display the correct options (either "Full-page translate" or "Restore original").
Why does the background script handle Microsoft Translator requests separately?
The background script provides special handling for Microsoft Translator through translateWithMicrosoftInBackground to bypass CORS restrictions in Firefox and other browsers. Content scripts cannot directly call the Microsoft Translator Edge endpoint (https://edge.microsoft.com/translate/auth) due to browser security policies. By moving these network requests to the background script—which has broader permissions—the extension can fetch JWT tokens and perform translations reliably across all supported browsers.
What happens when a user switches between tabs in FluentRead?
When a user switches tabs, the tabs.onActivated listener in background.ts triggers immediately. This listener retrieves the translation state for the newly activated tab from translationStateMap and calls updateContextMenus to adjust the context menu items accordingly. If the tab is translated, the "Restore original" option becomes enabled and "Full-page translate" becomes disabled, ensuring the UI always matches the current page state.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →