The Firefox DevTools Console is more than a place to log messages. It supports live JavaScript execution, multi-line expressions, DOM inspection, and CSS experiments. This guide covers the features that save the most time.
Basic Console Methods
// Logging
console.log('Basic message');
console.info('Informational');
console.warn('Warning — yellow highlight');
console.error('Error — red highlight with stack trace');
console.debug('Debug — only visible in DevTools (not user-facing)');
// Groups
console.group('User Auth');
console.log('Checking token...');
console.log('Token valid');
console.groupEnd();
console.groupCollapsed('Expanded by default'); // Starts collapsed
Formatting Output
// %s: string substitution
console.log('Hello %s, you have %d messages', 'Alice', 5);
// %o: object (interactive inspection)
console.log('User: %o', userObject);
// %c: CSS styling
console.log('%cImportant!', 'color: red; font-weight: bold; font-size: 16px;');
console.log('%c✓ Test passed', 'color: #10B981; font-weight: bold;');
// Tables
console.table([
{ name: 'Alice', age: 30, role: 'admin' },
{ name: 'Bob', age: 25, role: 'user' },
]);
// Shows a sortable table in DevTools
// Nested table with selected columns
console.table(users, ['name', 'email']); // Only show name and email columns
Timing and Performance
// Time a block of code
console.time('data-load');
const data = await fetchData();
console.timeEnd('data-load'); // Prints: data-load: 245ms
// Timestamps
console.timeStamp('important-event'); // Adds a marker in the Performance timeline
// Count calls
function processItem(item) {
console.count('processItem called');
// ...
}
// Output: processItem called: 1, processItem called: 2, ...
console.countReset('processItem called'); // Reset counter
Assertions
// Only logs if condition is false
console.assert(user.id > 0, 'User ID should be positive', user);
console.assert(response.ok, 'Response was not ok:', response.status);
Stack Traces
// Log current stack trace at any point
console.trace('Called from here');
// Error objects include stack automatically
console.error(new Error('Something went wrong'));
Multi-Line JavaScript in the Console
Firefox supports multi-line input in the console:
- Press Shift+Enter to add a new line without executing
- Press Enter to run the multi-line expression
// In console:
const users = [
{ name: 'Alice', score: 95 },
{ name: 'Bob', score: 73 },
{ name: 'Carol', score: 88 },
];
const top = users
.filter(u => u.score > 80)
.sort((a, b) => b.score - a.score);
console.table(top);
Or click the expand icon to open the multi-line editor.
Console in Context
You can run code in the context of any iframe:
- In the Console toolbar, there's a dropdown to switch execution context
- Switch to an iframe's context to access its DOM, variables, and network
Useful for debugging embedded third-party widgets.
Top-Level Await
Firefox console supports top-level await (no async wrapper needed):
// In console:
const res = await fetch('/api/config');
const config = await res.json();
config.features // Inspect directly
// Load a module dynamically in the console
const { format } = await import('https://esm.sh/date-fns');
format(new Date(), 'yyyy-MM-dd');
The $ Shortcuts
Firefox console provides jQuery-like shortcuts:
// $ aliases
$('h1') // document.querySelector('h1')
$$('.cards') // document.querySelectorAll('.cards') — returns Array, not NodeList
$0 // Currently selected element in the Inspector
$1, $2, ... // Previously selected elements (history)
$_ // Result of last expression evaluated
// inspect()
inspect($0) // Highlight element in the Inspector
Copy to Clipboard
copy('text to clipboard');
copy($0); // Copy element as HTML
copy(JSON.stringify(bigObject, null, 2)); // Pretty-print JSON to clipboard
Monitor Functions
// Log every call to a function
monitor(someFunction);
// Console: someFunction called with arguments: [arg1, arg2]
// Stop monitoring
unmonitor(someFunction);
// Monitor events on an element
monitorEvents(document.body, ['click', 'keypress']);
// Unmonitor
unmonitorEvents(document.body);
Getting Elements from the Console
// Get the element currently selected in the Inspector
const el = $0;
// Interact with it
el.style.border = '2px solid red';
el.getBoundingClientRect();
el.textContent;
Network Requests from the Console
// Fire a fetch request and inspect the result
const resp = await fetch('/api/users');
const data = await resp.json();
data.length; // How many users?
// POST from console for quick API testing
const result = await fetch('/api/login', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ email: 'test@example.com', password: 'test123' })
}).then(r => r.json());
console.log(result);
Console Persistence
By default, the console clears when you navigate. To keep logs across navigation:
- Click the Settings gear in DevTools
- Enable "Persist Logs"
- Console output is preserved across page loads
Useful for debugging redirect flows and form submissions.
Filtering and Search
- Click the funnel icon to filter by log level (logs, warnings, errors, info, debug)
- Type in the filter box to search log messages by text
- Use regex in the filter:
/error.*api/imatches messages containing "error" and "api" - Click the "Errors" badge in the browser toolbar to jump directly to console errors
Breakpoint Logging (Logpoints)
Instead of adding console.log to your code, set logpoints in the Debugger:
- Open Debugger
- Right-click a line number
- "Add log" (Firefox 105+)
- Enter an expression to log when that line executes
The log appears in the Console without modifying your source code.
Top comments (0)