Read Frog Firefox Compatibility: Configuration Guide for Optimal Performance

To ensure optimal compatibility and performance of Read Frog on Firefox, developers must adjust the extension manifest to omit unsupported permissions like offscreen, implement a custom Content Security Policy, add browser_specific_settings.gecko metadata, and gate Text-to-Speech features that rely on unsupported Web Speech APIs.

Read Frog is an open-source browser extension built with the WXT framework that provides advanced reading capabilities across multiple browsers. When targeting Firefox, the codebase in mengxi-ream/read-frog requires specific conditional adjustments to handle Firefox's stricter Manifest V3 implementation and missing APIs. This guide details the exact configurations needed for seamless Firefox operation.

Manifest Configuration Adjustments for Firefox

The wxt.config.ts file generates the extension manifest dynamically based on the target browser. For Firefox compatibility, three critical modifications are required.

Removing Offscreen Permission

Firefox does not support the offscreen API used in Chrome for DOM parsing in service workers. The configuration conditionally excludes this permission when building for Firefox:

// wxt.config.ts – permission configuration
permissions: [
  "storage",
  "tabs",
  "alarms",
  "cookies",
  "contextMenus",
  "identity",
  "scripting",
  "webNavigation",
  ...(browser !== "firefox" ? ["offscreen"] : []),   // ← Firefox-specific exclusion
],

Source: wxt.config.ts#L35-L36

Custom Content Security Policy

Firefox Manifest V3 enables upgrade-insecure-requests by default, which can interfere with extension functionality. Read Frog overrides the CSP to remove this directive and explicitly allow WebAssembly execution:

// wxt.config.ts – Firefox CSP override
...(browser === "firefox" && {
  content_security_policy: {
    extension_pages:
      "script-src 'self' 'wasm-unsafe-eval'; object-src 'self';",
  },
}),

Source: wxt.config.ts#L50-L55

Gecko Browser Specific Settings

Firefox requires a browser_specific_settings.gecko block containing a stable extension ID and minimum version constraint:

// wxt.config.ts – Gecko metadata
browser_specific_settings: {
  gecko: {
    id: "{bd311a81-4530-4fcc-9178-74006155461b}",
    strict_min_version: "109.0",
  },
},

Source: wxt.config.ts#L56-L59

Feature Gating for Firefox Limitations

Firefox lacks support for the Web Speech API used by Read Frog's Text-to-Speech (TTS) functionality. The codebase uses runtime environment checks to disable these features on Firefox.

Disabling Text-to-Speech Components

The TTS page is conditionally removed from the navigation routes in the options sidebar:

// src/entrypoints/options/app-sidebar/nav-items.ts
...(import.meta.env.BROWSER === "firefox" 
  ? [] 
  : [{ path: "/tts", component: TextToSpeechPage }]
),

Source: nav-items.ts#L24-L25

Hiding UI Elements Conditionally

The SpeakButton component is hidden in the selection toolbar when running on Firefox:

// src/entrypoints/selection.content/selection-toolbar/index.tsx
const isFirefox = import.meta.env.BROWSER === "firefox";

return (
  <div>
    {/* Other toolbar buttons */}
    {!isFirefox && <SpeakButton />}
  </div>
);

Source: selection-toolbar.tsx#L60-L53

The IS_FIREFOX constant is also defined in the command palette for consistent feature toggling across the extension:

// src/entrypoints/options/command-palette/search-items.ts
const IS_FIREFOX = import.meta.env.BROWSER === "firefox";

Source: search-items.ts#L9-L10

Selection Handling Workarounds

Firefox exhibits unique behavior where text selection is cleared when focus moves to dropdown elements. Read Frog implements specific guards to maintain toolbar visibility during these interactions.

Preventing Selection Loss on Dropdown Focus

The selection toolbar tracks dropdown state using a dropdownOpenRef to prevent premature hiding:

// src/entrypoints/selection.content/selection-toolbar/index.tsx
const dropdownOpenRef = useRef(false);

const handleSelectionChange = () => {
  const selection = window.getSelection();
  if (!selection || selection.toString().trim().length === 0) {
    // Firefox clears selection on dropdown focus → keep toolbar if open
    if (!dropdownOpenRef.current) {
      setIsSelectionToolbarVisible(false);
    }
  }
};

Source: selection-toolbar.tsx#L92-L100

Build and Distribution Requirements

Security and packaging requirements differ for Firefox distribution, particularly regarding environment variable handling.

Environment Variable Validation

The build process includes a Vite plugin that validates no API keys are accidentally bundled into the production code:

// wxt.config.ts – build-time validation
if (apiKeyVars.length > 0) {
  throw new Error(
    `Found WXT_*_API_KEY environment variables that may be bundled...`
  );
}

Source: wxt.config.ts#L77-L86

When creating distribution ZIP files for the Firefox Add-ons store, ensure the WXT_GOOGLE_CLIENT_ID environment variable is properly configured for OAuth functionality.

Summary

  • Manifest adjustments in wxt.config.ts require omitting the offscreen permission, overriding the default CSP to remove upgrade-insecure-requests, and adding the browser_specific_settings.gecko block with a stable ID and minimum version.
  • Feature gating uses import.meta.env.BROWSER === "firefox" checks to disable Text-to-Speech components in nav-items.ts and hide the SpeakButton in the selection toolbar.
  • Selection handling implements dropdownOpenRef guards in selection-toolbar/index.tsx to prevent the toolbar from disappearing when Firefox clears text selection on dropdown focus.
  • Build security relies on the check-api-key-env Vite plugin to prevent bundling sensitive credentials, which is critical for passing Firefox Add-ons store review.

Frequently Asked Questions

Why does Read Frog disable Text-to-Speech on Firefox?

Firefox does not currently support the Web Speech API's speech synthesis functionality that Read Frog uses for Text-to-Speech features. According to the source code in src/entrypoints/options/app-sidebar/nav-items.ts, the TTS page route is conditionally excluded when import.meta.env.BROWSER === "firefox" evaluates to true, preventing users from accessing unsupported functionality.

What is the minimum Firefox version required for Read Frog?

Read Frog requires Firefox version 109.0 or higher. This constraint is defined in the strict_min_version field within the browser_specific_settings.gecko block in wxt.config.ts. This version requirement ensures compatibility with the Manifest V3 features that Read Frog relies upon.

How does Read Frog handle the missing offscreen API in Firefox?

The extension conditionally omits the offscreen permission from the manifest when building for Firefox. In wxt.config.ts, the permissions array uses the spread operator with a ternary condition: ...(browser !== "firefox" ? ["offscreen"] : []). This ensures Firefox builds do not request unsupported permissions while Chrome builds retain the offscreen functionality needed for DOM parsing in service workers.

Why is a custom Content Security Policy needed for Firefox compatibility?

Firefox's Manifest V3 implementation enables upgrade-insecure-requests by default in the Content Security Policy, which can interfere with extension functionality. Read Frog overrides this in wxt.config.ts by specifying a custom content_security_policy that removes the upgrade directive and explicitly allows WebAssembly execution via 'wasm-unsafe-eval'. This ensures consistent behavior across browsers while maintaining security boundaries.

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 →