Console: Open Panel

With the console panel of devtools you can do two main functions:

1. View diagnostics (e.g. error msgs logged by the developer or by the browser) and

2. Run javascript (can be arbitrary code or related to the page).


Try cmd + alt/option + i (or j, or c) to open it.

More info: Keyboard Shortcuts Reference.

Console: Browser Errors

There are two types of messages logged in the Console Panel:

1. Errors & warnings on the page caught by the Browser.

2. Errors, warnings & information explictly printed by the developer.

Both are visible on the Console Panel and can be traced back to the original source file that caused the issue.

Open this page.

What is the 4-letter acronym of the security issue printed on the console by Chrome?

What is the name of the component that has an error?

More info: Console Getting Started.

Console: Settings

There are a few optional settings you can enable for the console.

1. Hide Network: Hides all network msgs, for example 404 errors (e.g. an image that cannot be found).

2. Preserve Log: Keeps previously printed msgs on the console after refreshing the page.

3. Selected Context Only: Show only msgs from your selected context (can be top, which is the current page, an iframe it page has any, a extension or a service worker).

4. Log XMLHttpRequests: Shows a msg for each AJAX call made by the page.

5. Eager Evaluation: Shows results of the Console as you type (without the need to hit enter).

6. Autocomplete from history: As you type, previously entered commands are shown.

More info: Console Overview.

Console: API

console (in lowercase) is a special object with an API with some helpful methods.

1. console.log is the most common popular method from API and can be used to print arbitrary messages (strings and variables separated by commas).

2. console.table can print and array/list (e.g. people) of objects as a table, where each row is a single object (e.g. person), and each column an attribute of the object (name, age, etc).

Both can be used to understand the structure of the data used by the app (e.g. AJAX responses).

Here is an example that print on the console using both console.log and console.table.

More info: Console API Reference and Diagnose and Log to Console.

Console: Dev Errors

A Dev can leave more explicit logging messages that can be read on the Console when specific errors happen.

Open this page.

The page is making the same AJAX call to the same 3rd party API from the previous example, but is now using the production URL of the API.

The page used to work, but now it doesn't. And our code has not changed recently.

What changed on the API?

More info: Console Getting Started.

Console: Store, Manipulate and Copy

Almost everything that looks like javascript data can be stored as a variable on the console, for further manipulation and inspection.

1. From the Network Panel: On AJAX responses that are displayed on the Network Panel, you can go to the Preview section, right click the request and select "Store as global variable".

2. From the Console Log: Right click any Objects or Arrays or JSON data and select "Store as global variable".

In both cases a new console message will appear displaying the name of the variable where the data was stored.

Since the data is now stored in a variable, it's no longer just a message on the console. It's a javascript object that you can manipulate it and play around with.

Open this page.

1. On the console settings active AJAX logging.

2. Then refresh the page. You'll see 8 AJAX calls, click on the people.json request (the url).

3. That will redirect you to its details on the Network Panel (more on that later). Click on people.json and then on the Preview tab. That will show you the entire response which you can expand to see its details.

4. Right click on (7 array of people) and select "Store as global variable". These 4 previous steps can be used to inspect AJAX results in detail.

Right now, the AJAX response should be stored on a variable named temp1. Try this on the console

temp1.filter(person => person.isActive)

That should filter the 7 people and only show those who are active. Now try this:

temp1.map(person => person.age)

That should've printed only the ages of the 7 people as a table.

Finally, try this to copy the entire content of a the variable to the clipboard:


How would you print in a table only the ages of people that are active (hint: you can do things like filter().map())?

More info: Command-Line Reference .

Console: Stack Traces

Stack Traces show us the chain of events that led to an error happening.

Open this page.

On the console you'll see 5 functions that were called until an error stopped the JS execution. Click on each one starting from the bottom to know what happened.

What's the name of the 3rd function called?

Console: Open as a Drawer

In the previous example the back and forth between the different panels made it difficult to understand what was going on.

In those cases is better to have the other Panel (Sources in this case) selected and open the Console as a separate drawer, so both can be used at the same time.

Open this page.

1. Click on the first function of the stack trace, which will take you to the source file in the Sources Panel.

2. Now hit ESC to make the console show up as a drawer on top of the Sources Panel. Now when you click each part of the stack trace you won't be redirected to the other panel.

Console: Stopped Execution

Let's open this page.

The page is made out of two components. The top one made by "Miguel" which shows the first names, last names and full names of the users. And a bottom one which shows the ages made by "José".

Visually, it looks like there is something wrong with the bottom component. Instead of the birth year we are getting undefined multiple times.

Let's look in the console and see what's happening.

1. The first component prints the first and last names. Then it adds the full names to each person and tries to display those.

2. But, there is an error when it tries to add the full name. Javascript stops the execution of everything after an error, unless explictly told not to do that (which isn't the case 99% of the time).

3. The bottom component never gets to the point of calculating the birth year which was the final step of the page's execution.

Who should you assign the BUG to?

Console: Querying the DOM ($ and $$)

When you load a page the browser receives the HTML string and creates the DOM (Document Object Model), an object representation of the same page that Javascript can use to manipulate the page (add content, change styles, listen to events like clicks, etc).

Using the console we can have quick access to the page's DOM and do everything a Front End Dev can with Javascript, right in the browser, without the need of setting up anything or have access to the source code.

The main two things you can do with the DOM are:

1. Query/select elements (e.g. all links aka anchor tags, or all paragraphs aka p tags).

2. Once with some elements selected you can modify them. All changes to a DOM element are immediately reflected on the actual page.

Want to change a page dynamically somehow? Use the DOM with Javascript.

What is the Elements panel of devtools? It's just a visual representation of the DOM.

Open this page. Try the following command on the console.


That DOM API method selects the first tag in the page with the class "app" and prints it in the console (in this case app contains basically the whole page, which is a navigation and some content). Now try:

document.querySelectorAll('.app p')

The previous code will select all paragraphs of the app (p tags inside the div with class app). Hover through the results and you'll see the element highlighted in the page, and if you click it, you'll get redirected to it in the Elements panel.

The devtools provides some useful aliases for document.querySelector and document.querySelectorAll. They are $ and $$. $$('p') should get you the same result as the previous command.

This kind of Javascript querying can be useful to catch things that are not easily catch visually by inspecting using the Elements panel or to repeatedly inspect the same elements over and over agains after refreshing the page several times.

How many links with the class "link" are in the page?

How many links (of any kind) are in the page?

With an element selected you can do all kind of fancy stuff. Everything Javascript provides. For instance, try:



$('h1').style.color = 'magenta'

The first gets you the character count of the heading.

The second gets you the exact position of the heading in relation to the viewport.

More info: API reference of DOM Elements.

Console: $0 - $4 (last five)

The console has a way to access the last five selected elements in the Elements Panel, to avoid having to query by selector on the console every time.

If you type $0 on the console you'll get the last selected element. $1 - $4 reference second last, third last, ... till the five last element.

Open this page and try to make some quick selections with $0, $1 and $2 as shown in the video.

More info: Command Line Reference.

Console: checkvalidity()

As mentioned before, in the console you have the full power of Javascript available to you. You don't need access to the Front End repository and source code to execute some advanced Javascript.

Open this page, select each form element in the Elements panel and execute the following after each selection (as shown in the video).


What is the max age constraint on the form?

More info: checkvalidity() Reference.

Console: Active Element

When doing accessibility test on a page, a common problem is to get into a focus trap. You start to navigate the page with tabs and at some point the focus is lost or on something invisible.

An useful tool for that is document.activeElement. That property on the document Javascript object always returns the currently active element. We can use that to print it in the console in case it is visually difficult to find.

Inspect this very page hit tab once and run on the console:


Then right click the result on the console and select "Reveal in Elements panel" to see exactly which HTML element has the focus.

Open this page, start tabbing and set the focus on the cta that says "I'm a button". Then hit tab again.

Where is the focus? Use document.activeElement to find out.

What's the id of the invisible element that traps the focus?

More info: document.activeElement MDN reference .

Console: Monitor Events

Sometimes, you know there is a defect related to an specific element (e.g. a button), but don't know what's exactly causing it.

Using Monitor Events you can get log specific events or all events that happen to an element.

Type the following:


That will log in the console every single event/interaction on the whole page.

To monitor the events of an element just type monitorEvents() with the element in the between the parenthesis:

An easy way to do that is to inspect an element you want to monitor, that will save a reference to it in $0 and then type monitorEvents($0).

Open this page. Click the first button, it should be toggle the visibility of an element.

Click the second in the magenta part. Tt should do the same. Now do it in the white part with the text. It shouldn't work. Monitor that second button click events on the magent part and then in the white part. You can do that by adding 'click' as the second param of monitorEvents:

monitorEvents($0, 'click')

On the object logged in the console, look for the target value in both cases.

What tag is logged as the target in the white part?

What tag is logged as the target in the magenta part?

What do you think is the problem?

More info: Monitor Events reference .