{"course":{"slug":"building-apps-with-ai","title":"Building Apps with AI","url":"https://addaly.com/learn/building-apps-with-ai","level":"beginner","track":"build"},"lesson":{"slug":"devtools-as-an-x-ray","title":"The browser devtools as an x-ray","url":"https://addaly.com/learn/building-apps-with-ai/devtools-as-an-x-ray","position":25,"of":87,"minutes":8,"answer":"Open the console for errors nobody read, the network panel to see whether a request happened and what came back, and throttle to Slow 4G before you show anybody the app.","keyIdea":"Open the console for errors nobody read, the network panel to see whether a request happened and what came back, and throttle to Slow 4G before you show anybody the app."},"body":{"format":"markdown","text":"## Free instruments, already installed\n\nEvery browser ships a set of professional debugging tools. F12, or Ctrl+Shift+I, or Cmd+Option+I. Five panels matter.\n\n## Elements: what is actually on the page\n\nThe HTML as it exists right now, after JavaScript has finished with it, which is often not what is in your source file. Click any element and the right pane shows every CSS rule affecting it, with overridden ones struck through, and which file each came from.\n\n> Figure: Five panels, five different questions. Layers, top to bottom: Elements: why is this the wrong size (the rule responsible, named with its source file); Console: what already failed (read from the top; the first error causes the rest); Network: did the request happen at all (path, status, what was sent, what came back); Application: what is stored on the device (is the session cookie HttpOnly and Secure); Throttling: what a real user has (Slow 4G and 4x CPU, before you show anybody). All of it is already installed and free. Most long debugging sessions are somebody looking in the first panel for an answer that is in the third.\n\nThe practical use: something is the wrong size and you cannot find why. Select it, read the computed styles, and the rule responsible is named with its source. This answers layout questions in seconds that would otherwise be twenty minutes of guessing.\n\nYou can also edit values live. Change a padding, see the result, then go and make the change in the real file. Nothing you type here is saved, which is exactly what makes it safe to experiment in.\n\n## Console: the errors nobody saw\n\nRed lines here are JavaScript errors that already happened. A great many broken generated apps have an error sitting in the console that nobody looked at, because the page still rendered something.\n\nMake this your first move whenever anything is odd. Reload with the console open, and read from the top: the first error usually causes the ones below it.\n\nYou can also run code here against the live page. Typing `document.cookie` or the name of a global variable and reading what comes back settles arguments about what state actually exists.\n\n## Network: what crossed the road\n\nEvery request, with method, status, size and timing. This panel answers questions no amount of code reading will.\n\n- **Did the request happen at all?** A button that does nothing is usually a button that sends nothing.\n- **What did we send?** The Payload or Request tab shows the exact body. Wrong field names show up instantly here.\n- **What came back?** The Response tab shows the raw answer, before any of your display code touched it. When the screen shows nothing and the response contains the data, the bug is in rendering, not in fetching.\n- **What is the status code?** 401 means not authenticated. 403, not allowed. 404, no such route, often a typo in the path. 500, your server crashed and the details are in your server logs, not here.\n- **How big and how slow?** Sort by size. The 3 MB image somebody pasted in unresized will be at the top.\n\nTick **Preserve log** before testing anything that redirects, or the evidence disappears when the page changes.\n\n## Application: where data is stored on the device\n\nCookies, local storage, session storage. Two things to check here.\n\nIs a session cookie marked `HttpOnly` and `Secure`? `HttpOnly` means JavaScript cannot read it, which is what stops a script on your page from stealing a login. A session token in local storage instead of an HttpOnly cookie is readable by any script that runs on your page.\n\nAnd is anything sensitive being kept here? Generated apps sometimes cache a user object, including an email or a phone number, in local storage where it persists after logout on a shared computer.\n\n## Throttling: becoming a realistic user\n\nIn the Network panel, the speed dropdown offers Slow 4G and Offline. In Performance, a CPU slowdown multiplier.\n\nSet Slow 4G and 4x CPU slowdown, then use your app. This is roughly a mid-range Android phone on a normal connection, which is what most of your users have. Every missing loading state, every layout that jumps as content arrives, and every double-submit becomes visible immediately.\n\nDo this once before you show anybody your app. It takes two minutes and it is the closest thing to testing on real hardware you can get without owning it.\n\n## On a phone\n\nAndroid Chrome connects to desktop devtools over USB via `chrome://inspect`. iPhone Safari connects to desktop Safari's Develop menu. Both are free, both take five minutes to set up, and both are the only way to debug something that happens only on a real device."},"check":{"question":"A list page shows nothing. The Network panel shows a 200 response containing the expected rows. Where is the fault?","options":[{"text":"In the database query, which must be returning the wrong rows.","correct":false,"tempting":"Contradicts the evidence; the correct rows are visible in the response body, so the query already succeeded."},{"text":"In authentication, since the user may not be permitted to see the data.","correct":false,"tempting":"Would produce a 401 or 403 rather than a 200 with the data attached."},{"text":"In the code that renders the response into the page.","correct":true},{"text":"In the network, since the response may not have arrived completely.","correct":false,"tempting":"The panel shows a completed 200 with a body, which is what a complete arrival looks like."}]},"prev":{"slug":"reading-the-query-behind-the-page","title":"Reading the query behind the page","url":"https://addaly.com/learn/building-apps-with-ai/reading-the-query-behind-the-page"},"next":{"slug":"the-smallest-experiment","title":"The smallest experiment that settles it","url":"https://addaly.com/learn/building-apps-with-ai/the-smallest-experiment"},"authorship":"Founder and series editor: Dr Mustafa Mun. Written by AI models to a written standard. Exam keys checked blind by a second model: 3,665 of 3,666 agreed. Academic review invited.","review":{"status":"Draft, open for academic review"},"cite":"Addaly (2026) 'The browser devtools as an x-ray', in Building Apps with AI. Edited by M. Mun. Addaly. Available at: https://addaly.com/learn/building-apps-with-ai/devtools-as-an-x-ray (Accessed: 13 October 2026).","licence":{"name":"CC BY-NC-SA 4.0","url":"https://creativecommons.org/licenses/by-nc-sa/4.0/"},"reader":{"schema":1,"title":"The browser devtools as an x-ray","courseTitle":"Building Apps with AI","module":{"index":3,"slug":"reading-and-checking","title":"Reading and checking what came back"},"answer":null,"keyIdea":"Open the console for errors nobody read, the network panel to see whether a request happened and what came back, and throttle to Slow 4G before you show anybody the app.","hero":{"kind":"figure","figure":{"t":"figure","label":"Figure","figure":{"type":"stack","title":"Five panels, five different questions","layers":[{"label":"Elements: why is this the wrong size","detail":"the rule responsible, named with its source file"},{"label":"Console: what already failed","detail":"read from the top; the first error causes the rest"},{"label":"Network: did the request happen at all","detail":"path, status, what was sent, what came back"},{"label":"Application: what is stored on the device","detail":"is the session cookie HttpOnly and Secure"},{"label":"Throttling: what a real user has","detail":"Slow 4G and 4x CPU, before you show anybody"}],"caption":"All of it is already installed and free. Most long debugging sessions are somebody looking in the first panel for an answer that is in the third."},"alt":"Figure: Five panels, five different questions. Layers, top to bottom: Elements: why is this the wrong size (the rule responsible, named with its source file); Console: what already failed (read from the top; the first error causes the rest); Network: did the request happen at all (path, status, what was sent, what came back); Application: what is stored on the device (is the session cookie HttpOnly and Secure); Throttling: what a real user has (Slow 4G and 4x CPU, before you show anybody). All of it is already installed and free. Most long debugging sessions are somebody looking in the first panel for an answer that is in the third."}},"blocks":[{"t":"h2","id":"free-instruments-already-installed","runs":[{"text":"Free instruments, already installed"}]},{"t":"p","runs":[{"text":"Every browser ships a set of professional debugging tools. F12, or Ctrl+Shift+I, or Cmd+Option+I. Five panels matter."}]},{"t":"h2","id":"elements-what-is-actually-on-the-page","runs":[{"text":"Elements: what is actually on the page"}]},{"t":"p","runs":[{"text":"The HTML as it exists right now, after JavaScript has finished with it, which is often not what is in your source file. Click any element and the right pane shows every CSS rule affecting it, with overridden ones struck through, and which file each came from."}]},{"t":"p","runs":[{"text":"The practical use: something is the wrong size and you cannot find why. Select it, read the computed styles, and the rule responsible is named with its source. This answers layout questions in seconds that would otherwise be twenty minutes of guessing."}]},{"t":"p","runs":[{"text":"You can also edit values live. Change a padding, see the result, then go and make the change in the real file. Nothing you type here is saved, which is exactly what makes it safe to experiment in."}]},{"t":"h2","id":"console-the-errors-nobody-saw","runs":[{"text":"Console: the errors nobody saw"}]},{"t":"p","runs":[{"text":"Red lines here are JavaScript errors that already happened. A great many broken generated apps have an error sitting in the console that nobody looked at, because the page still rendered something."}]},{"t":"p","runs":[{"text":"Make this your first move whenever anything is odd. Reload with the console open, and read from the top: the first error usually causes the ones below it."}]},{"t":"p","runs":[{"text":"You can also run code here against the live page. Typing "},{"text":"document.cookie","code":true},{"text":" or the name of a global variable and reading what comes back settles arguments about what state actually exists."}]},{"t":"h2","id":"network-what-crossed-the-road","runs":[{"text":"Network: what crossed the road"}]},{"t":"p","runs":[{"text":"Every request, with method, status, size and timing. This panel answers questions no amount of code reading will."}]},{"t":"ul","items":[[{"text":"Did the request happen at all?","b":true},{"text":" A button that does nothing is usually a button that sends nothing."}],[{"text":"What did we send?","b":true},{"text":" The Payload or Request tab shows the exact body. Wrong field names show up instantly here."}],[{"text":"What came back?","b":true},{"text":" The Response tab shows the raw answer, before any of your display code touched it. When the screen shows nothing and the response contains the data, the bug is in rendering, not in fetching."}],[{"text":"What is the status code?","b":true},{"text":" 401 means not authenticated. 403, not allowed. 404, no such route, often a typo in the path. 500, your server crashed and the details are in your server logs, not here."}],[{"text":"How big and how slow?","b":true},{"text":" Sort by size. The 3 MB image somebody pasted in unresized will be at the top."}]]},{"t":"p","runs":[{"text":"Tick "},{"text":"Preserve log","b":true},{"text":" before testing anything that redirects, or the evidence disappears when the page changes."}]},{"t":"h2","id":"application-where-data-is-stored-on-the-device","runs":[{"text":"Application: where data is stored on the device"}]},{"t":"p","runs":[{"text":"Cookies, local storage, session storage. Two things to check here."}]},{"t":"p","runs":[{"text":"Is a session cookie marked "},{"text":"HttpOnly","code":true},{"text":" and "},{"text":"Secure","code":true},{"text":"? "},{"text":"HttpOnly","code":true},{"text":" means JavaScript cannot read it, which is what stops a script on your page from stealing a login. A session token in local storage instead of an HttpOnly cookie is readable by any script that runs on your page."}]},{"t":"p","runs":[{"text":"And is anything sensitive being kept here? Generated apps sometimes cache a user object, including an email or a phone number, in local storage where it persists after logout on a shared computer."}]},{"t":"h2","id":"throttling-becoming-a-realistic-user","runs":[{"text":"Throttling: becoming a realistic user"}]},{"t":"p","runs":[{"text":"In the Network panel, the speed dropdown offers Slow 4G and Offline. In Performance, a CPU slowdown multiplier."}]},{"t":"p","runs":[{"text":"Set Slow 4G and 4x CPU slowdown, then use your app. This is roughly a mid-range Android phone on a normal connection, which is what most of your users have. Every missing loading state, every layout that jumps as content arrives, and every double-submit becomes visible immediately."}]},{"t":"p","runs":[{"text":"Do this once before you show anybody your app. It takes two minutes and it is the closest thing to testing on real hardware you can get without owning it."}]},{"t":"h2","id":"on-a-phone","runs":[{"text":"On a phone"}]},{"t":"p","runs":[{"text":"Android Chrome connects to desktop devtools over USB via "},{"text":"chrome://inspect","code":true},{"text":". iPhone Safari connects to desktop Safari’s Develop menu. Both are free, both take five minutes to set up, and both are the only way to debug something that happens only on a real device."}]}],"check":{"question":[{"text":"A list page shows nothing. The Network panel shows a 200 response containing the expected rows. Where is the fault?"}],"options":[{"text":[{"text":"In the database query, which must be returning the wrong rows."}],"correct":false,"tempting":[{"text":"Contradicts the evidence; the correct rows are visible in the response body, so the query already succeeded."}]},{"text":[{"text":"In authentication, since the user may not be permitted to see the data."}],"correct":false,"tempting":[{"text":"Would produce a 401 or 403 rather than a 200 with the data attached."}]},{"text":[{"text":"In the code that renders the response into the page."}],"correct":true,"tempting":null},{"text":[{"text":"In the network, since the response may not have arrived completely."}],"correct":false,"tempting":[{"text":"The panel shows a completed 200 with a body, which is what a complete arrival looks like."}]}],"order":[1,0,3,2],"why":null},"prev":{"slug":"reading-the-query-behind-the-page","title":"Reading the query behind the page","minutes":9},"next":{"slug":"the-smallest-experiment","title":"The smallest experiment that settles it","minutes":8}}}