This content originally appeared on Modern Web Development with Chrome and was authored by Paul Kinlan
<p>Sometimes when I am on my mobile, I just want quick access to the JS console so that I can see what is going on inside the web page: Does the page have any logs, warnings or errors etc; without having to plug my phone into a laptop and hooking up to Chrome DevTools.</p>
<p>I really wish you could use DevTools more easily on a mobile device. That being said, I have a partial solution that solves my problem.</p>
<p>Now that I know how to access <a href="https://paul.kinlan.me/use-bookmarklets-on-chrome-on-android/">bookmarklets</a>, I realised it might be possible to create a simple tool that will show me the <code>console</code> log of what is happening on the page.</p>
<p>If you want to experiment with this, just drag this <a href='javascript:(function()%7B(function() %7Bconst id %3D "consoleElement12312312khfasdakh"%3Bif (document.getElementById(id) %3D%3D%3D undefined) return%3Bconst consoleElement %3D document.createElement("details")%3BconsoleElement.id %3D id%3Bconst scopedStyle %3D document.createElement("style")%3Bconst container %3D document.createElement("div")%3BscopedStyle.innerText %3D %60%23%24%7Bid%7D %7Bposition%3A fixed%3Bmax-height%3A 5em%3Bbottom%3A 0px%3Bleft%3A 0px%3Bborder%3A 1px solid red%3Bz-index%3A 100%3Bbackdrop-filter%3A blur(5px)%3Bpadding-left%3A 1em%3Bfont-family%3A monospace%3Bmargin%3A 1em%3Bbackground-color%3A rgba(250%2C 235%2C 215%2C 0.4)%3B%7D%23%7Bid%7D%5Bopen%5D %7Bright%3A 0px !important%3Bheight%3A 5em%3B%7D%23%7Bid%7D%3Anot(open) summary %7Bpadding-right%3A 1em%3B%7D%23%24%7Bid%7D div %7Bheight%3A 3em%3Bmax-height%3A 3em%3Boverflow%3A auto%3B%7D%23%24%7Bid%7D p %7Bfont-size%3A 12px%3B%7D%23%24%7Bid%7D p.log%3Abefore %7Bcontent%3A "Log%3A "%3B%7D%23%24%7Bid%7D p.warn %7Bcolor%3A orange%3Bborder-top%3A solid 1px orange%3Bborder-bottom%3A solid 1px orange%3B%7D%23%24%7Bid%7D p.warn%3Abefore %7Bcontent%3A "Warn%3A "%3B%7D%23%24%7Bid%7D p.error %7Bcolor%3A red%3Bborder-top%3A solid 1px red%3Bborder-bottom%3A solid 1px red%3B%7D%23%24%7Bid%7D p.error%3Abefore %7Bcontent%3A "Error%3A "%3B%7D%60%3Bconst summary %3D document.createElement("summary")%3Bsummary.innerText %3D "Console%3A L%3A 0%2C W%3A 0%2C E%3A 0"%3BconsoleElement.appendChild(scopedStyle)%3BconsoleElement.appendChild(summary)%3BconsoleElement.appendChild(container)%3Bconst log %3D console.log.bind(console)%3Bconst error %3D console.error.bind(console)%3Bconst warn %3D console.warn.bind(console)%3Bconst count %3D %7B%7D%3Bconst output %3D function(type%2C fn%2C ...args) %7Bconst logElement %3D document.createElement("p")%3Bif (type in count %3D%3D false) count%5Btype%5D %3D 0%3Bcount%5Btype%5D%2B%2B%3BlogElement.className %3D type%3Bcontainer.appendChild(logElement)%3BlogElement.innerText %3D %60%24%7Bargs%7D%60%3Bsummary.innerText %3D %60Console%3A L%3A %24%7Bcount%5B"log"%5D %7C%7C 0%7D%2C W%3A %24%7Bcount%5B"warn"%5D %7C%7C 0%7D%2C E%3A %24%7Bcount%5B"error"%5D %7C%7C 0%7D%60%3Bfn(...args)%3B%7D%3Bconsole.log %3D function(...args) %7Boutput("log"%2C log%2C ...args)%3B%7D%3Bconsole.warn %3D function(...args) %7Boutput("warn"%2C warn%2C ...args)%3B%7D%3Bconsole.error %3D function(...args) %7Boutput("error"%2C error%2C ...args)%3B%7D%3Bdocument.body.appendChild(consoleElement)%3B%7D)()%7D)()'>Developer Console</a> link to your bookmarks bar.</p>
<p>The above link when clicked will open up a small <code>detail</code> element anchored to the bottom of the page, when opened will show all of the console logs, warnings and errors since the bookmark was activated (it can't retrospectively access what was added to the log beforehand).</p>
<p>It's a simple tool, but it gives me just enough insight (especially if you like to debug with <code>console.log</code>)</p>
<p>Below is a quick video showing how the bookmarklet works:</p>
<figure><video src="https://paul.kinlan.me/videos/2020-05-21-quick-console-bookmarklet-for-desktop-and-mobile-0.mp4" alt="A bookmarklet that shows the console logs" controls></video></figure>
<p>The code for the bookmarklet is below:</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-JavaScript" data-lang="JavaScript">(<span style="color:#66d9ef">function</span>() {
<span style="color:#66d9ef">const</span> <span style="color:#a6e22e">id</span> <span style="color:#f92672">=</span> <span style="color:#e6db74">"consoleElement12312312khfasdakh"</span>;
<span style="color:#66d9ef">if</span> (document.<span style="color:#a6e22e">getElementById</span>(<span style="color:#a6e22e">id</span>) <span style="color:#f92672">===</span> <span style="color:#66d9ef">undefined</span>) <span style="color:#66d9ef">return</span>;
<span style="color:#66d9ef">const</span> <span style="color:#a6e22e">consoleElement</span> <span style="color:#f92672">=</span> document.<span style="color:#a6e22e">createElement</span>(<span style="color:#e6db74">"details"</span>);
<span style="color:#a6e22e">consoleElement</span>.<span style="color:#a6e22e">id</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">id</span>;
<span style="color:#66d9ef">const</span> <span style="color:#a6e22e">scopedStyle</span> <span style="color:#f92672">=</span> document.<span style="color:#a6e22e">createElement</span>(<span style="color:#e6db74">"style"</span>);
<span style="color:#66d9ef">const</span> <span style="color:#a6e22e">container</span> <span style="color:#f92672">=</span> document.<span style="color:#a6e22e">createElement</span>(<span style="color:#e6db74">"div"</span>);
<span style="color:#a6e22e">scopedStyle</span>.<span style="color:#a6e22e">innerText</span> <span style="color:#f92672">=</span> <span style="color:#e6db74">`
</span><span style="color:#e6db74">#</span><span style="color:#e6db74">${</span><span style="color:#a6e22e">id</span><span style="color:#e6db74">}</span><span style="color:#e6db74"> {
</span><span style="color:#e6db74"> position: fixed;
</span><span style="color:#e6db74"> max-height: 5em;
</span><span style="color:#e6db74"> bottom: 0px;
</span><span style="color:#e6db74"> left: 0px;
</span><span style="color:#e6db74"> border: 1px solid red;
</span><span style="color:#e6db74"> z-index: 100;
</span><span style="color:#e6db74"> backdrop-filter: blur(5px);
</span><span style="color:#e6db74"> padding-left: 1em;
</span><span style="color:#e6db74"> font-family: monospace;
</span><span style="color:#e6db74"> margin: 1em;
</span><span style="color:#e6db74"> background-color: rgba(250, 235, 215, 0.4);
</span><span style="color:#e6db74">}
</span><span style="color:#e6db74">
</span><span style="color:#e6db74">#{id}[open] {
</span><span style="color:#e6db74"> right: 0px !important;
</span><span style="color:#e6db74"> height: 5em;
</span><span style="color:#e6db74">}
</span><span style="color:#e6db74">
</span><span style="color:#e6db74">#{id}:not(open) summary {
</span><span style="color:#e6db74"> padding-right: 1em;
</span><span style="color:#e6db74">}
</span><span style="color:#e6db74">
</span><span style="color:#e6db74">#</span><span style="color:#e6db74">${</span><span style="color:#a6e22e">id</span><span style="color:#e6db74">}</span><span style="color:#e6db74"> div {
</span><span style="color:#e6db74"> height: 3em;
</span><span style="color:#e6db74"> max-height: 3em;
</span><span style="color:#e6db74"> overflow: auto;
</span><span style="color:#e6db74">}
</span><span style="color:#e6db74">
</span><span style="color:#e6db74">#</span><span style="color:#e6db74">${</span><span style="color:#a6e22e">id</span><span style="color:#e6db74">}</span><span style="color:#e6db74"> p {
</span><span style="color:#e6db74"> font-size: 12px;
</span><span style="color:#e6db74">}
</span><span style="color:#e6db74">
</span><span style="color:#e6db74">#</span><span style="color:#e6db74">${</span><span style="color:#a6e22e">id</span><span style="color:#e6db74">}</span><span style="color:#e6db74"> p.log:before {
</span><span style="color:#e6db74"> content: "Log: ";
</span><span style="color:#e6db74">}
</span><span style="color:#e6db74">
</span><span style="color:#e6db74">#</span><span style="color:#e6db74">${</span><span style="color:#a6e22e">id</span><span style="color:#e6db74">}</span><span style="color:#e6db74"> p.warn {
</span><span style="color:#e6db74"> color: orange;
</span><span style="color:#e6db74"> border-top: solid 1px orange;
</span><span style="color:#e6db74"> border-bottom: solid 1px orange;
</span><span style="color:#e6db74">}
</span><span style="color:#e6db74">
</span><span style="color:#e6db74">#</span><span style="color:#e6db74">${</span><span style="color:#a6e22e">id</span><span style="color:#e6db74">}</span><span style="color:#e6db74"> p.warn:before {
</span><span style="color:#e6db74"> content: "Warn: ";
</span><span style="color:#e6db74">}
</span><span style="color:#e6db74">
</span><span style="color:#e6db74">#</span><span style="color:#e6db74">${</span><span style="color:#a6e22e">id</span><span style="color:#e6db74">}</span><span style="color:#e6db74"> p.error {
</span><span style="color:#e6db74"> color: red;
</span><span style="color:#e6db74"> border-top: solid 1px red;
</span><span style="color:#e6db74"> border-bottom: solid 1px red;
</span><span style="color:#e6db74">}
</span><span style="color:#e6db74">
</span><span style="color:#e6db74">#</span><span style="color:#e6db74">${</span><span style="color:#a6e22e">id</span><span style="color:#e6db74">}</span><span style="color:#e6db74"> p.error:before {
</span><span style="color:#e6db74"> content: "Error: ";
</span><span style="color:#e6db74">}`</span>;
<span style="color:#66d9ef">const</span> <span style="color:#a6e22e">summary</span> <span style="color:#f92672">=</span> document.<span style="color:#a6e22e">createElement</span>(<span style="color:#e6db74">"summary"</span>);
<span style="color:#a6e22e">summary</span>.<span style="color:#a6e22e">innerText</span> <span style="color:#f92672">=</span> <span style="color:#e6db74">"Console: L: 0, W: 0, E: 0"</span>;
<span style="color:#a6e22e">consoleElement</span>.<span style="color:#a6e22e">appendChild</span>(<span style="color:#a6e22e">scopedStyle</span>);
<span style="color:#a6e22e">consoleElement</span>.<span style="color:#a6e22e">appendChild</span>(<span style="color:#a6e22e">summary</span>);
<span style="color:#a6e22e">consoleElement</span>.<span style="color:#a6e22e">appendChild</span>(<span style="color:#a6e22e">container</span>);
<span style="color:#66d9ef">const</span> <span style="color:#a6e22e">log</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">console</span>.<span style="color:#a6e22e">log</span>.<span style="color:#a6e22e">bind</span>(<span style="color:#a6e22e">console</span>);
<span style="color:#66d9ef">const</span> <span style="color:#a6e22e">error</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">console</span>.<span style="color:#a6e22e">error</span>.<span style="color:#a6e22e">bind</span>(<span style="color:#a6e22e">console</span>);
<span style="color:#66d9ef">const</span> <span style="color:#a6e22e">warn</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">console</span>.<span style="color:#a6e22e">warn</span>.<span style="color:#a6e22e">bind</span>(<span style="color:#a6e22e">console</span>);
<span style="color:#66d9ef">const</span> <span style="color:#a6e22e">count</span> <span style="color:#f92672">=</span> {};
<span style="color:#66d9ef">const</span> <span style="color:#a6e22e">output</span> <span style="color:#f92672">=</span> <span style="color:#66d9ef">function</span>(<span style="color:#a6e22e">type</span>, <span style="color:#a6e22e">fn</span>, ...<span style="color:#a6e22e">args</span>) {
<span style="color:#66d9ef">const</span> <span style="color:#a6e22e">logElement</span> <span style="color:#f92672">=</span> document.<span style="color:#a6e22e">createElement</span>(<span style="color:#e6db74">"p"</span>);
<span style="color:#66d9ef">if</span> (<span style="color:#a6e22e">type</span> <span style="color:#66d9ef">in</span> <span style="color:#a6e22e">count</span> <span style="color:#f92672">==</span> <span style="color:#66d9ef">false</span>) <span style="color:#a6e22e">count</span>[<span style="color:#a6e22e">type</span>] <span style="color:#f92672">=</span> <span style="color:#ae81ff">0</span>;
<span style="color:#a6e22e">count</span>[<span style="color:#a6e22e">type</span>]<span style="color:#f92672">++</span>;
<span style="color:#a6e22e">summary</span>.<span style="color:#a6e22e">innerText</span> <span style="color:#f92672">=</span> <span style="color:#e6db74">`Console: L: </span><span style="color:#e6db74">${</span><span style="color:#a6e22e">count</span>[<span style="color:#e6db74">"log"</span>] <span style="color:#f92672">||</span> <span style="color:#ae81ff">0</span><span style="color:#e6db74">}</span><span style="color:#e6db74">, W: </span><span style="color:#e6db74">${</span><span style="color:#a6e22e">count</span>[<span style="color:#e6db74">"warn"</span>] <span style="color:#f92672">||</span>
<span style="color:#ae81ff">0</span><span style="color:#e6db74">}</span><span style="color:#e6db74">, E: </span><span style="color:#e6db74">${</span><span style="color:#a6e22e">count</span>[<span style="color:#e6db74">"error"</span>] <span style="color:#f92672">||</span> <span style="color:#ae81ff">0</span><span style="color:#e6db74">}</span><span style="color:#e6db74">`</span>;
<span style="color:#a6e22e">logElement</span>.<span style="color:#a6e22e">className</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">type</span>;
<span style="color:#a6e22e">logElement</span>.<span style="color:#a6e22e">innerText</span> <span style="color:#f92672">=</span> <span style="color:#e6db74">`</span><span style="color:#e6db74">${</span><span style="color:#a6e22e">args</span><span style="color:#e6db74">}</span><span style="color:#e6db74">`</span>;
<span style="color:#a6e22e">container</span>.<span style="color:#a6e22e">appendChild</span>(<span style="color:#a6e22e">logElement</span>);
<span style="color:#a6e22e">logElement</span>.<span style="color:#a6e22e">scrollIntoView</span>({<span style="color:#a6e22e">behavior</span><span style="color:#f92672">:</span> <span style="color:#e6db74">"smooth"</span>, <span style="color:#a6e22e">block</span><span style="color:#f92672">:</span> <span style="color:#e6db74">"start"</span> });
<span style="color:#a6e22e">fn</span>(...<span style="color:#a6e22e">args</span>);
};
<span style="color:#a6e22e">console</span>.<span style="color:#a6e22e">log</span> <span style="color:#f92672">=</span> <span style="color:#66d9ef">function</span>(...<span style="color:#a6e22e">args</span>) {
<span style="color:#a6e22e">output</span>(<span style="color:#e6db74">"log"</span>, <span style="color:#a6e22e">log</span>, ...<span style="color:#a6e22e">args</span>);
};
<span style="color:#a6e22e">console</span>.<span style="color:#a6e22e">warn</span> <span style="color:#f92672">=</span> <span style="color:#66d9ef">function</span>(...<span style="color:#a6e22e">args</span>) {
<span style="color:#a6e22e">output</span>(<span style="color:#e6db74">"warn"</span>, <span style="color:#a6e22e">warn</span>, ...<span style="color:#a6e22e">args</span>);
};
<span style="color:#a6e22e">console</span>.<span style="color:#a6e22e">error</span> <span style="color:#f92672">=</span> <span style="color:#66d9ef">function</span>(...<span style="color:#a6e22e">args</span>) {
<span style="color:#a6e22e">output</span>(<span style="color:#e6db74">"error"</span>, <span style="color:#a6e22e">error</span>, ...<span style="color:#a6e22e">args</span>);
};
document.<span style="color:#a6e22e">body</span>.<span style="color:#a6e22e">appendChild</span>(<span style="color:#a6e22e">consoleElement</span>);
})();
</code></pre></div><p>When clicked we create a <code>details</code> element, a set of styles, a summary element (that contains a running tally of the console logs) and a container that will hold all the logs and add it to the page.</p>
<p>We then intercept every call to <code>console.log</code>, <code>console.warn</code> and <code>console.error</code>, add the details to the <code>details</code> container and then invoke the original log (so that it will actually appear in DevTools).</p>
<p>And, that's about it. It's a simple utility that's not supposed to replace proper devtools, but it can quickly help you find an issue in the page without any extra tooling required.</p>
This content originally appeared on Modern Web Development with Chrome and was authored by Paul Kinlan