Need help with your JSON?
Try our JSON Formatter tool to automatically identify and fix syntax errors in your JSON. JSON Formatter tool
Firefox Add-on Development for JSON Formatting
As developers, we often encounter raw JSON data displayed directly in the browser — whether it's an API response, a configuration file, or data from a web service. The browser's default display is typically a single, unformatted block of text, making it difficult to read, understand, and debug. This is where a simple browser add-on can be incredibly useful.
This article guides you through the process of creating a basic Firefox add-on that automatically formats JSON content displayed in a browser tab, making it structured, readable, and perhaps even syntax-highlighted. We'll focus on the modern Manifest V3 specification.
Why Build a JSON Formatter Add-on?
- Improved Readability: Turn a single line of JSON into a structured, indented format.
- Easier Debugging: Quickly spot errors or understand the data structure.
- Time Saving: Avoid copying and pasting JSON into external formatters or editors.
- Customization: Tailor the formatting or add features like collapsing sections.
Firefox Add-on Fundamentals (Manifest V3)
Firefox add-ons are built using Web Extensions APIs, which are largely compatible with Chrome Extensions APIs. Manifest V3 is the current standard, focusing on security and performance by shifting away from some background script capabilities towards service workers and stricter permissions.
Key components for our JSON formatter add-on will include:
- Manifest File (`manifest.json`): This is the blueprint of your add-on. It contains metadata (name, version, description), permissions, and defines which scripts or pages the add-on uses.
- Content Scripts: JavaScript files that run in the context of a specific web page. They can read and modify the DOM of the pages they are injected into. This is our primary tool for finding and formatting the JSON displayed on a page.
- Permissions: Declared in the manifest, these grant the add-on the ability to perform certain actions (e.g., access tabs, modify pages).
Core Strategy: Injecting a Content Script
How do we detect if a page is displaying raw JSON and then modify it? The most straightforward approach for simply formatting JSON that's already *displayed* in the browser (typically within a <pre>
tag or as the sole content of the body) is to use a Content Script.
The content script will be configured to run on pages that match certain URL patterns (e.g., URLs ending in `.json` or specific API endpoints). Once injected into a page, the script will:
- Examine the page's content (the DOM).
- Identify elements that likely contain the raw JSON text (like the
<body>
or<pre>
tag). - Extract the text content.
- Attempt to parse the text as JSON.
- If successful, format the parsed JSON data.
- Replace the original unformatted content in the DOM with the new formatted content.
The Manifest File (`manifest.json`)
This file tells Firefox about your add-on. For our formatter, we need to declare the add-on's name, version, manifest version, and crucially, the content scripts and necessary permissions.
Here's a basic example:
{
"manifest_version": 3,
"name": "Simple JSON Formatter",
"version": "1.0",
"description": "Formats raw JSON displayed in browser tabs.",
"permissions": [
"activeTab",
"scripting"
],
"content_scripts": [
{
"matches": [
"<all_urls>"
],
"js": [
"content-script.js"
],
"run_at": "document_idle"
}
],
"icons": {
"48": "icons/json-48.png",
"96": "icons/json-96.png"
}
}
Let's break down the key parts:
"manifest_version": 3
: Specifies the add-on manifest standard."name"
,"version"
,"description"
: Standard add-on metadata."permissions"
:"activeTab"
: Grants temporary access to the currently active tab when the user interacts with the add-on (like clicking a browser action icon), although not strictly needed if the script runs automatically on page load."scripting"
: Required in MV3 to inject content scripts programmatically or declare them statically in the manifest.
"content_scripts"
: Defines the scripts to inject into web pages."matches": ["<all_urls>"]
: This is a broad pattern, injecting the script into all HTTP and HTTPS pages. You might want to narrow this down (e.g., to URLs ending in `.json`) depending on your needs, but starting broad allows checking more pages."js": ["content-script.js"]
: The path to your content script file(s)."run_at": "document_idle"
: Injects the script after the DOM is ready and resources are loaded. Other options include `document_start` and `document_end`.
"icons"
: Paths to icons for your add-on.
Note: Using <all_urls>
requires careful content script implementation to avoid interfering with normal web pages that do *not* contain JSON.
The Content Script (`content-script.js`)
This script will contain the logic to find, parse, and format the JSON.
A simple script might look for a <pre>
element (which browsers often use to display raw response bodies) or check the entire document body.
// content-script.js
function formatJson() {
let jsonText = null;
let targetElement = null;
// Check if the page content is just plain text, likely JSON
// This often appears inside a PRE tag, or as the only content in the BODY
const preElement = document.querySelector('body > pre');
if (preElement) {
jsonText = preElement.textContent;
targetElement = preElement;
} else if (document.body && document.body.children.length === 0 && document.body.textContent.trim().startsWith('{') || document.body.textContent.trim().startsWith('[')) {
// Check if body has no children and looks like JSON
jsonText = document.body.textContent;
targetElement = document.body;
} else {
// If it's not a raw JSON page displayed simply, don't do anything
return;
}
if (!jsonText) {
return; // No text found
}
try {
const jsonObj = JSON.parse(jsonText);
// Use JSON.stringify for basic indentation
// The third argument (2 here) is the number of spaces for indentation
const formattedJson = JSON.stringify(jsonObj, null, 2);
// Create a new PRE element to hold the formatted JSON
const formattedPre = document.createElement('pre');
formattedPre.textContent = formattedJson; // Set the formatted text
// Optional: Add some basic styling or a class for CSS
formattedPre.style.cssText = 'outline: 1px solid #ccc; padding: 10px; margin: 10px; background-color: #f4f4f4;';
formattedPre.className = 'json-formatter'; // Add a class for potential external CSS
// Replace the original content with the formatted content
// This is a simple replacement; a more complex formatter might build a DOM tree
if (targetElement) {
// Clear existing content
while (targetElement.firstChild) {
targetElement.removeChild(targetElement.firstChild);
}
// Append the new formatted content
targetElement.appendChild(formattedPre);
} else {
// Fallback if targetElement is null (shouldn't happen with checks above)
document.body.innerHTML = ''; // Clear body
document.body.appendChild(formattedPre); // Add formatted
}
console.log('JSON formatted successfully.');
} catch (e) {
console.error('Failed to parse or format JSON:', e);
// Optional: Display an error message on the page
// Or revert the content if it was modified before catching the error
}
}
// Run the formatter when the script is loaded
formatJson();
This script performs a basic check for <pre>
tags or a body that looks like raw JSON, attempts parsing, and replaces the content with a nicely indented string using JSON.stringify(obj, null, 2)
.
Enhancements for the Content Script
A simple JSON.stringify
is functional, but you can go further:
- Syntax Highlighting: Integrate a small client-side syntax highlighter library (be mindful of add-on size). You would parse the JSON, then pass the resulting object/string to the highlighter library, and inject its generated HTML into the page.
- Collapsible Sections: For large JSON objects/arrays, create a DOM structure that allows users to collapse and expand sections. This requires building the HTML tree manually based on the parsed JSON object, rather than just using
JSON.stringify
. - Error Display: If
JSON.parse
fails, clearly indicate on the page that the content is not valid JSON and show the error. - Handling MIME Types: Instead of
<all_urls>
, you could try to detect theContent-Type
header using thewebRequest
API (in a background script) and only inject the content script if the type is `application/json`. However, the `webRequest` API has limitations in MV3 regarding blocking/modifying requests, so modifying the DOM via content scripts after the page loads is often simpler for display purposes.
Be cautious about using large external libraries in content scripts as they can impact page performance and add-on size. Lightweight, specialized libraries are best.
Development and Debugging
Developing Firefox add-ons is straightforward:
- Save your
manifest.json
andcontent-script.js
files (and any icons) in a folder. - Open Firefox. Navigate to
about:debugging#/runtime/this-firefox
. - Click "Load Temporary Add-on..." and select any file inside your add-on's folder (like
manifest.json
). - Your add-on will be installed temporarily until you close Firefox.
- Open a new tab and navigate to a URL that displays raw JSON (e.g., a public API endpoint like https://jsonplaceholder.typicode.com/todos/1).
- Check if the JSON is formatted. You can use the Browser Console (F12 or Cmd+Option+J) and switch to the "Extensions" tab to see console logs from your content script.
This temporary loading method is essential for rapid iteration and debugging.
Understanding Permissions
The "permissions"
field in the manifest is crucial."scripting"
is needed to inject scripts. "activeTab"
is a common permission that grants access to the current tab only when the user invokes the extension (like clicking a browser action). If your script should run automatically on matching pages without user interaction (as in our example using `content_scripts` declared in the manifest), "scripting"
along with "matches"
in the `content_scripts` section is sufficient and more appropriate than relying solely on `activeTab`.
Always request the minimum permissions necessary for your add-on to function. Broad permissions like <all_urls>
or access to sensitive APIs require careful consideration and clear justification to users.
Conclusion
Building a Firefox add-on to format JSON is a practical introduction to browser extension development using the modern Manifest V3 standard. It involves defining the add-on's capabilities in the manifest file and writing content scripts to interact with web page content. While a basic formatter is relatively simple, the functionality can be significantly enhanced with syntax highlighting, collapsible sections, and more robust content detection. This project provides a solid foundation for developing more complex browser tools.
Need help with your JSON?
Try our JSON Formatter tool to automatically identify and fix syntax errors in your JSON. JSON Formatter tool