The Console Tab
Where JavaScript errors are reported, where your console.log() statements appear, and how to read a stack trace to find exactly what broke and where.
The Console tab is where your app talks to you. Every error, every warning, every piece of information you deliberately log — it all appears here. If something is broken, the Console usually tells you exactly what broke and where.
Why First: The Form That Does Nothing
You built a document submission form for your CA practice's client portal. Client fills it in, clicks Submit. Nothing happens. No success message. No error message. The page just sits there.
Where do you look?
Open DevTools. Click Console.
Nine times out of ten, there is a red error message sitting there telling you exactly what went wrong. Maybe Cannot read properties of undefined (reading 'id') — which means the user object isn't loaded yet when the form tried to read it. Maybe Failed to fetch — the network request never reached Supabase. Maybe a Zod validation error — the data shape was wrong.
The answer was there the whole time. You just needed to know where to look.
The Excel Analogy
In Excel, when you have a formula error like #VALUE! or #REF!, Excel tells you something went wrong but not much more. You click the cell and see the broken formula.
The Console is like if Excel printed a detailed explanation of every formula error in a dedicated panel — with the exact cell address, the exact step in the formula that failed, and a description of what went wrong. It is more informative than anything Excel has, and once you learn to read it, it is invaluable.
The Color System: What Each Color Means
When you open the Console, you will see messages in different colors:
Red — Errors
Something broke. JavaScript threw an exception, a network request failed, or a required resource couldn't load. These are the messages that demand your attention first.
Yellow — Warnings
Something is technically working but doing so in a way that might cause problems. Missing React key props, deprecated APIs, performance hints. Important but not urgent.
Blue/White — Info & Logs
Your console.log() statements, informational messages from libraries, browser notices. These are the messages you put there deliberately to understand what's happening.
Gray — Verbose
Extremely detailed debug output, usually from browser internals. Hidden by default. You rarely need these.
Reading a Stack Trace
When an error appears in the Console, it looks something like this:
This looks intimidating at first. Here is how to read it:
Line 1: The error type and message. TypeError: Cannot read properties of undefined (reading 'map') — this tells you a JavaScript error occurred, specifically that something was undefined when you tried to call .map() on it. Translation: your data hasn't loaded yet but your code is trying to loop through it.
The stack below: Where the error happened. Read from top to bottom. The top line is where it broke. at JobList (JobList.tsx:47:23) means the error happened inside the JobList component, in the file JobList.tsx, at line 47, column 23.
Clicking the file name and line number: In the Console, file references are clickable links (they appear as blue underlined text). Click JobList.tsx:47 and DevTools jumps directly to that line of code in the Sources tab. You are looking at the exact line that caused the crash.
The first line in your own file is the one that matters. The long list of React internal files below your component (react-dom.development.js, etc.) is React's own code running your component. Ignore everything that isn't your file. Click the link to your own file, look at that line, and that is where you start debugging.
Using console.log() Strategically
console.log() is the simplest debugging tool available, and it is more useful than it appears.
Basic Usage
Inside any component or function, you can log any value:
Open the Console and you will see jobs data: undefined (before data loads) and then jobs data: Array(12) (after it loads). This tells you whether the data is arriving at all and what shape it has.
What You Can Log
You can log anything:
console.table() — The Best Tool for Supabase Results
When you have an array of objects (which is exactly what Supabase queries return), console.table() formats them as a table in the Console — with column headers and rows. It is dramatically more readable than the default array display.
The Console will show a table with one row per application and one column per field. You can see all the data at a glance and sort by any column by clicking the header. This is extremely useful when checking if your Supabase query returned the right data.
console.error() — When You Want Red
console.error() logs in red, just like a real error. Use it when you want something to stand out:
This is useful for flagging "this state should be impossible" situations so they stand out visually in the Console.
console.group() — Organizing Related Logs
When you have many related log statements, group them:
These appear in the Console as a collapsible group, keeping related debug output together.
Filtering Console Messages
When your app is running, the Console fills up quickly with messages from React, Supabase, your code, and browser internals. You need to filter.
At the top of the Console, you will see filter options:
- All — shows everything
- Errors — shows only red error messages (use this when actively debugging a bug)
- Warnings — shows only yellow warnings
- Info — shows info-level messages
- Verbose — shows verbose-level messages
There is also a text filter field. Type any text and the Console will show only messages containing that text. Extremely useful for finding your specific console.log('job data:') statements among a wall of other output.
During active debugging: switch to Errors only. You will see only real problems and nothing else. Once you have found the issue, switch back to All to see your console.log() output.
Clearing the Console
The Console accumulates messages over time. When you start debugging a specific problem, clear it first so you are only looking at messages from the current interaction.
How to clear:
- Click the circle with a line through it (🚫) icon in the Console toolbar
- Keyboard shortcut:
Ctrl + L(Windows/Linux) orCmd + K(Mac) - Type
clear()in the Console input and press Enter
The Console as an Interactive REPL
The Console input field at the bottom (the > prompt) is a live JavaScript environment. You can type any JavaScript expression and it will execute immediately against your running page.
This means you can:
For Supabase debugging: if you have exposed your Supabase client globally (which you shouldn't do in production but might during development), you can run actual Supabase queries from the Console REPL and see the results immediately — without touching your code. This is useful for quickly checking if a query works before wiring it up to a component.
Preserve Log: Keeping Messages Across Navigation
By default, the Console clears when you navigate to a different page. This can be frustrating if you are trying to debug what happens during a redirect.
To keep Console messages across navigation:
In the Console toolbar, look for a gear icon or find the "Preserve log" checkbox
Check "Preserve log"
Now messages persist when the page navigates — even through full page loads
Remember to uncheck this when you're done, otherwise the Console will accumulate messages indefinitely.
The Habit to Build
Every time something in your app doesn't work the way you expect:
- Open DevTools (
F12) - Click the Console tab
- Read the error messages (red ones first)
- Click the file link in the stack trace to jump to the broken line
- Add
console.log()statements near that line to understand the state of your data - Fix the code
This process takes three minutes once you are practiced. Guessing takes three hours.