# FluentRead Background Script Explained: How background.ts Powers the Extension

> Discover how FluentRead's background.ts script orchestrates context menus, tab states, message routing, and Microsoft Translator authentication to power your reading experience.

- Repository: [ThinkStu/fluentread](https://github.com/bistutu/fluentread)
- Tags: internals
- Published: 2026-02-26

---

**The FluentRead background script ([`background.ts`](https://github.com/bistutu/fluentread/blob/main/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`](https://github.com/bistutu/fluentread/blob/main/background.ts) file in the [bistutu/fluentread](https://github.com/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`](https://github.com/bistutu/fluentread/blob/main/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:

```typescript
// 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:

```typescript
// 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:

```typescript
// 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](https://github.com/bistutu/fluentread) codebase:

- **[`entrypoints/service/_service.ts`](https://github.com/bistutu/fluentread/blob/main/entrypoints/service/_service.ts)** – Registry of all translation services; the background script forwards requests here based on `config.service` selection
- **[`entrypoints/utils/config.ts`](https://github.com/bistutu/fluentread/blob/main/entrypoints/utils/config.ts)** – Holds runtime configuration including the selected translation provider and target language preferences
- **[`entrypoints/utils/constant.ts`](https://github.com/bistutu/fluentread/blob/main/entrypoints/utils/constant.ts)** – Defines constant IDs such as `CONTEXT_MENU_IDS` used 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`](https://github.com/bistutu/fluentread/blob/main/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`](https://github.com/bistutu/fluentread/blob/main/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`](https://github.com/bistutu/fluentread/blob/main/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`](https://github.com/bistutu/fluentread/blob/main/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.