[{"data":1,"prerenderedAt":248},["ShallowReactive",2],{"sideproject-en-print-pruna-chrome-extension":3},{"id":4,"title":5,"body":6,"date":217,"description":218,"extension":219,"featured":220,"image":221,"locale":222,"meta":223,"navigation":236,"order":237,"path":238,"repo":239,"seo":240,"status":241,"stem":242,"technologies":243,"url":239,"__hash__":247},"sideprojects\u002Fen\u002Fsideprojects\u002Fprint-pruna-chrome-extension.md","PrintPruna (2026)",{"type":7,"value":8,"toc":209},"minimark",[9,13,17,28,33,36,72,79,83,106,118,122,133,143,147,157,175,179,195,198],[10,11,5],"h1",{"id":12},"printpruna-2026",[14,15,16],"p",{},"Chrome and Firefox extension that lets you mark HTML blocks on the current page to clean it up before printing to PDF. No server, no data leaving the browser: everything happens inside the same tab.",[14,18,19,20,27],{},"Available on the ",[21,22,26],"a",{"href":23,"rel":24},"https:\u002F\u002Fchromewebstore.google.com\u002Fdetail\u002Fprintpruna\u002Fkhknmplelejchmmifcbllajjkimodinb",[25],"nofollow","Chrome Web Store",".",[29,30,32],"h2",{"id":31},"what-does-it-do","What does it do?",[14,34,35],{},"Clicking the extension icon opens a small menu with three options:",[37,38,39,47,53],"ul",{},[40,41,42,46],"li",{},[43,44,45],"strong",{},"Select",": marks the block you want to keep; the rest of the page is hidden. The selected block is resized (~90% width, centered) so it doesn't lose readability if it depended on a flex\u002Fgrid layout with siblings now hidden.",[40,48,49,52],{},[43,50,51],{},"Remove",": marks a specific block and makes it disappear, leaving the rest of the page intact. It can be used repeatedly to remove more than one block.",[40,54,55,58,59,63,64,67,68,71],{},[43,56,57],{},"Print",": opens the browser's print dialog directly (",[60,61,62],"code",{},"window.print()","), without going through the keyboard. Useful on pages that block ",[60,65,66],{},"Ctrl+P","\u002F",[60,69,70],{},"Cmd+P"," with JavaScript.",[14,73,74,75,78],{},"In \"Select\" and \"Remove\" modes, the cursor turns into a crosshair and elements are highlighted on hover (blue for \"Select\", red for \"Remove\"). Click the desired element to apply the action, or press ",[60,76,77],{},"Esc"," at any time to exit marking mode without making any changes. To restore the page's original state, just reload it (F5).",[29,80,82],{"id":81},"bypassing-the-ctrlp-block","Bypassing the Ctrl+P block",[14,84,85,86,89,90,93,94,97,98,101,102,105],{},"Some pages block the print shortcut with JavaScript to stop users from printing or saving the content as a PDF. Whenever any menu option is activated, PrintPruna also installs a ",[60,87,88],{},"keydown"," listener at the ",[60,91,92],{},"window"," level in the capture phase, ahead of any listeners the page has attached to ",[60,95,96],{},"document",". Since the capture phase travels ",[60,99,100],{},"window → document → ...",", the extension's listener always runs first and stops propagation without calling ",[60,103,104],{},"preventDefault()",", letting the browser carry out its default action.",[14,107,108,109,111,112,114,115,27],{},"It's a best-effort mitigation: if the page attaches its listener directly to ",[60,110,92],{}," before the extension is injected, this method can't beat it. For those cases there's the menu's \"Print\" option, which calls ",[60,113,62],{}," from the extension's \"isolated world\" and remains unaffected even if the page has overwritten ",[60,116,117],{},"window.print",[29,119,121],{"id":120},"architecture","Architecture",[14,123,124,125,128,129,132],{},"Manifest V3 shared between Chrome and Firefox, with only two permissions (",[60,126,127],{},"activeTab",", ",[60,130,131],{},"scripting","):",[134,135,140],"pre",{"className":136,"code":138,"language":139},[137],"language-text","manifest.json     Manifest V3, shared between Chrome and Firefox\nsrc\u002Fpopup.html    Icon menu with the \"Select\", \"Remove\" and \"Print\" options\nsrc\u002Fpopup.js      Injects the content script (if needed) and sends the chosen mode\nsrc\u002Fcontent.js    Hover, block selection\u002Fremoval logic\nsrc\u002Fcontent.css   Hover highlight and marking cursor styles\n","text",[60,141,138],{"__ignoreMap":142},"",[29,144,146],{"id":145},"installing-in-developer-mode","Installing in developer mode",[14,148,149,152,153,156],{},[43,150,151],{},"Chrome \u002F Edge \u002F Brave",": open ",[60,154,155],{},"chrome:\u002F\u002Fextensions",", enable \"Developer mode\" and click \"Load unpacked\", selecting the project folder.",[14,158,159,152,162,165,166,169,170,27],{},[43,160,161],{},"Firefox",[60,163,164],{},"about:debugging#\u002Fruntime\u002Fthis-firefox"," and click \"Load Temporary Add-on\", selecting the ",[60,167,168],{},"manifest.json"," file. The load is temporary and is lost when the browser closes; a permanent install would require signing the extension via ",[21,171,174],{"href":172,"rel":173},"https:\u002F\u002Faddons.mozilla.org",[25],"addons.mozilla.org",[29,176,178],{"id":177},"tech-stack","Tech stack",[37,180,181,184,192],{},[40,182,183],{},"Manifest V3",[40,185,186,187,128,189,191],{},"Chrome Extensions API (",[60,188,127],{},[60,190,131],{},")",[40,193,194],{},"Vanilla JavaScript, no dependencies",[196,197],"hr",{},[14,199,200,203,204],{},[43,201,202],{},"Source code:"," ",[21,205,208],{"href":206,"rel":207},"https:\u002F\u002Fgithub.com\u002Falbertsarle\u002Fprint-pruna",[25],"github.com\u002Falbertsarle\u002Fprint-pruna",{"title":142,"searchDepth":210,"depth":210,"links":211},2,[212,213,214,215,216],{"id":31,"depth":210,"text":32},{"id":81,"depth":210,"text":82},{"id":120,"depth":210,"text":121},{"id":145,"depth":210,"text":146},{"id":177,"depth":210,"text":178},"2026-09-22T12:00:00Z","Chrome and Firefox extension that lets you mark HTML blocks on a page to clean it up before printing to PDF.","md",false,"\u002Fimages\u002Fsideprojects\u002Fprint-pruna-chrome-extension-banner.png","en",{"slug":224,"type":225,"categories":226,"tags":227,"achievements":231,"githubUrl":206},"print-pruna-chrome-extension","sideproject",[225],[228,229,183,230],"Chrome Extension","Firefox Extension","JavaScript",[232,233,234,235],"Dependency-free extension, compatible with Chrome, Edge, Brave and Firefox from the same manifest","Reusable \"Remove\" mode, applied repeatedly to clean up several blocks in a row","Ctrl+P block bypass: window.print() called from the extension's \"isolated world\", unaffected by the page","Capture-phase keydown listener that beats page scripts trying to block the print shortcut",true,1,"\u002Fen\u002Fsideprojects\u002Fprint-pruna-chrome-extension",null,{"title":5,"description":218},"published","en\u002Fsideprojects\u002Fprint-pruna-chrome-extension",[244,245,246],"Manifest V3 (shared Chrome\u002FFirefox)","Chrome Extensions API (activeTab, scripting)","Vanilla JavaScript","eaA6jUyehU2RXF6YHRpnDslNHfjZXOLR6pcjR-UP8Y0",1790587323223]