--- title: 02 Console Panel --- # Chrome DevTools — Console Panel A complete reference from first log message to advanced scripting, instrumentation, and live debugging. --- ## What the Console Is The Console Panel is a JavaScript REPL (Read-Eval-Print Loop) embedded directly in the browser. It serves three distinct roles simultaneously: 1. **Log viewer** — every `console.*` call from your page, service workers, and extensions appears here in real time. 2. **Interactive shell** — you can evaluate arbitrary JavaScript against the live page, mutate the DOM, call your own functions, and inspect variables without touching source files. 3. **Diagnostic surface** — network errors, CSP violations, deprecation warnings, and uncaught exceptions all land here with source links and full stack traces. Because it runs inside the page's JavaScript environment, code you type in the Console has the same access to `window`, `document`, and every global variable as your application code does. --- ## Opening the Console ### As the primary panel - **Menu** → More Tools → Developer Tools → Console tab - `Cmd+Option+J` (macOS) / `Ctrl+Shift+J` (Windows/Linux) — opens DevTools and lands directly on the Console panel ### As the Console Drawer The Drawer lets the Console share the screen with any other panel (Sources, Elements, Network, etc.). - `Escape` — toggles the Drawer open/closed while any other panel is active - When the Drawer is open, the Console tab appears at the bottom of the DevTools window; all functionality is identical to the full-panel view ### From the Elements panel Right-click any DOM node → **Inspect** → then press `Escape` to open the Drawer; `$0` in the Console will already reference the node you inspected. --- ## UI Layout ``` ┌──────────────────────────────────────────────────────────────────────────┐ │ Elements Console Sources Network Performance Memory Application │ ├──────────────────────────────────────────────────────────────────────────┤ │ 🚫 ⬇ ⚙ │ Filter │ Default levels ▼ │ top ▼ │ │ (clear) │ (text / regex search box) │ (log level menu) │(context)│ ├─────────────────────────────────────────────────────────────────────────-│ │ │ │ LOG AREA │ │ │ │ ▶ Object {name: "Alice", age: 30} VM42:1 │ │ [Error] Uncaught TypeError: x is not a function app.js:17 │ │ [Warning] Deprecated API usage vendor.js:204 │ │ Hello, world! app.js:3 │ │ │ │ (messages scroll upward, newest at bottom) │ │ │ ├──────────────────────────────────────────────────────────────────────────┤ │ > PROMPT (interactive JavaScript input) │ └──────────────────────────────────────────────────────────────────────────┘ ``` **Toolbar elements (left to right):** | Control | Purpose | |---|---| | Clear (🚫) | Clears visible log area (equivalent to `console.clear()`) | | Preserve log checkbox | Keep messages across page navigations | | Live Expressions (eye icon) | Pin a JS expression that auto-evaluates | | Filter input | Text or `/regex/` search across log text | | Log level dropdown | Show/hide by severity (Default, Verbose, Info, Warnings, Errors) | | Context selector | Switch JS execution context (top frame, iframes, workers) | --- ## All Console Methods ### `console.log` — general output The most common method. Accepts any number of arguments of any type. Objects are printed as interactive expandable trees. ```javascript console.log('Hello, world!'); // Hello, world! console.log('User:', { name: 'Alice', role: 'admin' }); // User: ▶ {name: "Alice", role: "admin"} // Multiple values on one line console.log(1, 'two', true, null, undefined, [3, 4]); // 1 "two" true null undefined ▶ [3, 4] // Template literal (no special Console support needed) const count = 42; console.log(`There are ${count} items.`); // There are 42 items. ``` :::caution Objects are passed by reference. If you log a mutable object and then modify it, expanding the log entry later shows the mutated state. Spread or JSON-serialize to capture a snapshot: ```javascript const state = { count: 0 }; console.log({ ...state }); // snapshot — safe state.count = 99; ``` ::: --- ### `console.info` — informational messages Identical to `console.log` in Chrome; shown with a blue (i) icon in some browsers. Filtered by the "Info" level selector. ```javascript console.info('Server responded in 120ms'); console.info('Feature flag "dark_mode" is enabled for this user'); ``` --- ### `console.warn` — warnings Prints with a yellow background and a ⚠ icon. Filtered by the "Warnings" level. ```javascript console.warn('localStorage is nearly full (%d / %d bytes used)', 4800000, 5000000); console.warn('Deprecated: use newApi() instead of oldApi()'); // Useful for surfacing non-fatal problems during development function divide(a, b) { if (b === 0) { console.warn('divide() called with b=0, returning Infinity'); } return a / b; } ``` --- ### `console.error` — errors Prints with a red background and a ✖ icon. Always includes a stack trace. Filtered by the "Errors" level. ```javascript console.error('Failed to load user profile'); console.error(new Error('Network timeout after 5000ms')); // Log an error object with extra context try { JSON.parse('not json'); } catch (err) { console.error('JSON parse failed:', err); } ``` --- ### `console.debug` — debug-level output Identical to `console.log` but hidden by the "Default" log level filter. Only visible when the level is set to "Verbose". Useful for high-frequency diagnostic logs you don't want cluttering the default view. ```javascript function processChunk(chunk, index) { console.debug('[processChunk] index=%d, size=%d', index, chunk.byteLength); } ``` --- ### `console.trace` — stack trace at call site Prints the current call stack without throwing an error. Invaluable for tracing which code path triggered a function. ```javascript function c() { console.trace('Where was c() called?'); } function b() { c(); } function a() { b(); } a(); // Output: // Where was c() called? // c @ VM1:1 // b @ VM1:2 // a @ VM1:3 // (anonymous) @ VM1:4 ``` ```javascript // Real-world use: find unexpected re-renders function render() { console.trace('render triggered'); // ... render logic } ``` --- ### `console.assert` — conditional logging Logs only when the first argument is falsy. Does nothing when the condition is truthy. Prints as an error (red) when triggered. ```javascript console.assert(1 === 1, 'Math is broken'); // nothing logged console.assert(1 === 2, 'One does not equal two'); // Assertion failed: One does not equal two // Practical: validate assumptions without throwing const MAX = 100; function setProgress(value) { console.assert(value >= 0 && value <= MAX, 'setProgress: value out of range', value); // ... proceed } setProgress(150); // Assertion failed: setProgress: value out of range 150 ``` ```javascript // Assert with object context const user = { id: 7, name: 'Bob' }; console.assert(user.id > 0, 'Expected positive user.id', { user }); ``` --- ### `console.table` — tabular display Renders arrays or objects as formatted tables. Optional second argument is an array of column names to display. ```javascript // Array of primitives console.table(['alpha', 'beta', 'gamma']); // ┌─────────┬──────────┐ // │ (index) │ Values │ // ├─────────┼──────────┤ // │ 0 │ "alpha" │ // │ 1 │ "beta" │ // │ 2 │ "gamma" │ // └─────────┴──────────┘ // Array of objects — each key becomes a column const users = [ { id: 1, name: 'Alice', role: 'admin' }, { id: 2, name: 'Bob', role: 'editor' }, { id: 3, name: 'Carol', role: 'viewer' }, ]; console.table(users); // Show only selected columns console.table(users, ['name', 'role']); // ┌─────────┬─────────┬──────────┐ // │ (index) │ name │ role │ // ├─────────┼─────────┼──────────┤ // │ 0 │ "Alice" │ "admin" │ // │ 1 │ "Bob" │ "editor" │ // │ 2 │ "Carol" │ "viewer" │ // └─────────┴─────────┴──────────┘ // Object keyed by string — keys become the index column const inventory = { apples: 5, bananas: 12, oranges: 3 }; console.table(inventory); ``` --- ### `console.group` / `console.groupCollapsed` / `console.groupEnd` — nested log groups Visually groups related log messages under a collapsible heading. `groupCollapsed` starts collapsed; `group` starts expanded. ```javascript console.group('User Authentication Flow'); console.log('1. Validating credentials...'); console.log('2. Fetching user record...'); console.group('Token Generation'); console.log('2a. Creating access token (expires 1h)'); console.log('2b. Creating refresh token (expires 30d)'); console.groupEnd(); // closes Token Generation console.log('3. Setting session cookie'); console.groupEnd(); // closes User Authentication Flow ``` ```javascript // Collapsed by default — useful for verbose but rarely-needed info async function fetchAll(urls) { const results = []; for (const url of urls) { console.groupCollapsed(`Fetching: ${url}`); const res = await fetch(url); const data = await res.json(); console.log('Status:', res.status); console.log('Data:', data); console.groupEnd(); results.push(data); } return results; } ``` ```javascript // Nested groups for hierarchical data function logTree(node, depth = 0) { console.group(node.name); if (node.children) { node.children.forEach(child => logTree(child, depth + 1)); } console.groupEnd(); } ``` --- ### `console.time` / `console.timeEnd` / `console.timeLog` — timing Measures wall-clock elapsed time between calls. Labels are strings that pair calls together. ```javascript // Basic timing console.time('data-load'); const response = await fetch('/api/data'); const data = await response.json(); console.timeEnd('data-load'); // data-load: 243.7ms // Intermediate checkpoints with timeLog console.time('pipeline'); const raw = await loadRawData(); console.timeLog('pipeline', 'raw data loaded'); // pipeline: 120ms raw data loaded const parsed = parseData(raw); console.timeLog('pipeline', 'data parsed'); // pipeline: 185ms data parsed const rendered = render(parsed); console.timeEnd('pipeline'); // pipeline: 210ms ``` ```javascript // Multiple independent timers run concurrently console.time('alpha'); console.time('beta'); // ... do work ... console.timeEnd('beta'); // beta: 50ms // ... more work ... console.timeEnd('alpha'); // alpha: 130ms ``` --- ### `console.count` / `console.countReset` — call counter Counts how many times a labeled counter has been incremented. ```javascript function handleClick(eventType) { console.count(eventType); // ... handle event } handleClick('click'); // click: 1 handleClick('click'); // click: 2 handleClick('keydown'); // keydown: 1 handleClick('click'); // click: 3 console.countReset('click'); handleClick('click'); // click: 1 (reset) ``` ```javascript // Default label is "default" for (let i = 0; i < 5; i++) { console.count(); } // default: 1 // default: 2 // default: 3 // default: 4 // default: 5 ``` --- ### `console.dir` / `console.dirxml` — structured object view `console.dir` forces object display as a JS property tree, even for DOM nodes (instead of showing HTML markup). `console.dirxml` displays DOM/XML nodes as markup trees. ```javascript const btn = document.querySelector('button'); console.log(btn); // shows the element as rendered HTML: