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:

  • refreshMicrosoftTokenInBackground fetches a fresh JWT from https://edge.microsoft.com/translate/auth
  • translateWithMicrosoftInBackground uses 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:

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 (a Map<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 updateContextMenus function, 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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →