Sticky Note Bookmarklet

Pink stickies on any tab—type, move, resize, export. Stored in the browser only.

Sticky Note Bookmarklet

I work in Chrome with too many tabs and profiles. When I need to remember "come back to this tab later," I used to float windows in a corner—and then I could never tell which window was which in the Window menu.

So I made a bookmarklet that drops a bright pink sticky on the page. You can add more than one, drag the header to move, drag the corner to resize, and type whatever you need. Notes for a given URL are saved in local storage, so if you close the tab and come back, running the bookmarklet again pulls your notes back. That's the limit of what a bookmarklet can do without becoming a full extension.

Features

  • Multiple notes — Click the bookmark again for another sticky.
  • Persistent per URL — Stored locally per origin + path + query (same page gets the same notes back).
  • No server — Nothing leaves your machine.

How to use it

  1. Install the bookmark using the button at the top or bottom of this page (drag to the bar) or paste the code block into a new bookmark's URL field.
  2. On a normal website, click the bookmark. A new sticky appears; click again for another.
  3. Drag the header to move, the corner nub to resize, to remove a note.
  4. Revisit the same page later and click the bookmark to restore saved notes from storage.

Some sites fight for focus so aggressively that the textarea won't stick; if that happens, there's no magic fix—remove the note and use paper.

Safari / Firefox: Works, but I've seen small cosmetic differences. The code is yours to tweak if that bugs you.

Bookmarklet Code:

javascript:(()=>{const P="___pinkStickyNote";const STYLE_ID="__pinkStickyStyleLS";const LAYER_ID="___pinkStickyLayerLS";const KEY=(()=>{try{return"__pinkStickies::"+location.origin+location.pathname+location.search;}catch(e){return"__pinkStickies::fallback";}})();const CSS=`#${LAYER_ID}{position:fixed;inset:0;z-index:2147483647;pointer-events:none;} .${P}{position:absolute;width:220px;height:180px;background:#ff2db2;color:#111;border:2px solid rgba(0,0,0,.35);border-radius:10px;box-shadow:0 10px 25px rgba(0,0,0,.25);overflow:hidden;display:flex;flex-direction:column;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica,Arial,sans-serif;pointer-events:auto;} .${P}__header{flex:0 0 30px;display:flex;align-items:center;justify-content:space-between;padding:0 8px;background:rgba(255,255,255,.18);border-bottom:1px solid rgba(0,0,0,.2);cursor:move;user-select:none;} .${P}__title{font-size:12px;font-weight:800;letter-spacing:.2px;opacity:.85;} .${P}__close{width:22px;height:22px;line-height:20px;border-radius:6px;border:1px solid rgba(0,0,0,.25);background:rgba(255,255,255,.25);cursor:pointer;font-weight:900;} .${P}__close:hover{background:rgba(255,255,255,.4);} .${P}__body{flex:1;padding:8px;} .${P}__text{width:100%;height:100%;resize:none;border:none;outline:none;background:transparent;color:#111;font-size:13px;line-height:1.25;} .${P}__resize{position:absolute;right:6px;bottom:6px;width:14px;height:14px;cursor:nwse-resize;background:rgba(255,255,255,.45);border:1px solid rgba(0,0,0,.25);border-radius:4px;}`;const clamp=(v,min,max)=>Math.max(min,Math.min(max,v));const ensure=()=>{let s=document.getElementById(STYLE_ID);if(!s){s=document.createElement("style");s.id=STYLE_ID;s.textContent=CSS;document.documentElement.appendChild(s);}let layer=document.getElementById(LAYER_ID);if(!layer){layer=document.createElement("div");layer.id=LAYER_ID;document.documentElement.appendChild(layer);}return layer;};const safeParse=(txt)=>{try{const v=JSON.parse(txt);return Array.isArray(v)?v:[];}catch(e){return[];}};const loadAll=()=>{try{return safeParse(localStorage.getItem(KEY)||"[]");}catch(e){return[];}};const saveAll=(arr)=>{try{localStorage.setItem(KEY,JSON.stringify(arr));}catch(e){}};const forceFocus=(el)=>{const f=()=>{try{el.focus({preventScroll:true});}catch(_){try{el.focus();}catch(__){}}};f();setTimeout(()=>{if(document.activeElement!==el)f();},0);setTimeout(()=>{if(document.activeElement!==el)f();},25);setTimeout(()=>{if(document.activeElement!==el)f();},80);};const getAllLive=()=>Array.from(document.querySelectorAll("."+P)).map(note=>{const id=note.getAttribute("data-id")||"";const x=parseInt(note.style.left,10)||0;const y=parseInt(note.style.top,10)||0;const w=parseInt(note.style.width,10)||note.offsetWidth||220;const h=parseInt(note.style.height,10)||note.offsetHeight||180;const ta=note.querySelector("textarea");const text=ta?ta.value:"";return{id,x,y,w,h,text};}).filter(o=>o.id);const upsertSave=()=>{saveAll(getAllLive());};const buildNote=(data)=>{const layer=ensure();const note=document.createElement("div");note.className=P;note.style.zIndex="2147483647";note.setAttribute("data-id",data.id);note.style.left=(data.x||0)+"px";note.style.top=(data.y||0)+"px";note.style.width=(data.w||220)+"px";note.style.height=(data.h||180)+"px";const header=document.createElement("div");header.className=P+"__header";const title=document.createElement("div");title.className=P+"__title";title.textContent="NOTE";const close=document.createElement("button");close.className=P+"__close";close.type="button";close.title="Close";close.textContent="\u2715";header.appendChild(title);header.appendChild(close);const body=document.createElement("div");body.className=P+"__body";const ta=document.createElement("textarea");ta.className=P+"__text";ta.placeholder="Type...";ta.spellcheck=true;ta.value=data.text||"";body.appendChild(ta);const resizer=document.createElement("div");resizer.className=P+"__resize";resizer.title="Resize";note.appendChild(header);note.appendChild(body);note.appendChild(resizer);layer.appendChild(note);let drag=null,resize=null;const onMove=(e)=>{if(drag){const dx=e.clientX-drag.sx,dy=e.clientY-drag.sy;note.style.left=clamp(drag.ox+dx,0,window.innerWidth-30)+"px";note.style.top=clamp(drag.oy+dy,0,window.innerHeight-30)+"px";}else if(resize){note.style.width=clamp(resize.ow+(e.clientX-resize.sx),140,900)+"px";note.style.height=clamp(resize.oh+(e.clientY-resize.sy),90,900)+"px";}};const onUp=()=>{drag=null;resize=null;document.removeEventListener("mousemove",onMove,true);document.removeEventListener("mouseup",onUp,true);upsertSave();};header.addEventListener("mousedown",(e)=>{if(e.button!==0)return;e.preventDefault();drag={sx:e.clientX,sy:e.clientY,ox:parseInt(note.style.left,10)||0,oy:parseInt(note.style.top,10)||0};document.addEventListener("mousemove",onMove,true);document.addEventListener("mouseup",onUp,true);},{capture:true});resizer.addEventListener("mousedown",(e)=>{if(e.button!==0)return;e.preventDefault();e.stopPropagation();resize={sx:e.clientX,sy:e.clientY,ow:note.offsetWidth,oh:note.offsetHeight};document.addEventListener("mousemove",onMove,true);document.addEventListener("mouseup",onUp,true);},{capture:true});close.addEventListener("click",(e)=>{e.stopPropagation();note.remove();upsertSave();},{capture:true});let tmr=null;ta.addEventListener("input",()=>{if(tmr)clearTimeout(tmr);tmr=setTimeout(()=>upsertSave(),250);},{capture:true});ta.addEventListener("blur",upsertSave,{capture:true});ta.addEventListener("pointerdown",(e)=>{e.stopPropagation();forceFocus(ta);},{capture:true});return{note,ta};};const already=new Set(Array.from(document.querySelectorAll("."+P)).map(n=>n.getAttribute("data-id")).filter(Boolean));for(const s of loadAll()){if(s&&s.id&&!already.has(s.id))buildNote(s);}const id=String(Date.now())+"-"+Math.random().toString(16).slice(2);const w=220,h=180;const x=clamp(Math.round((window.innerWidth-w)/2),0,window.innerWidth-w);const y=clamp(Math.round((window.innerHeight-h)/2),0,window.innerHeight-h);const created=buildNote({id,x,y,w,h,text:""});upsertSave();setTimeout(()=>forceFocus(created.ta),0);})();