Track your progress, visualise on any site

A website widget that displays a live heatmap of the year, from data in a Google Sheet

◻️◻️◻️◻️◻️◻️


Track daily progress in a Google sheet

Connect your Sheet to the tracker widget

Embed widget anywhere with just an iframe

Example embed shown below – this tracker widget takes live data from a Google Sheet (like in this screenshot)

Show your streaks – perfect for accountability, or just for kudos

◻️◻️◻️◻️◻️◻️


Track daily habits

  • Exercise

  • Meditation

  • Journaling

  • Reading

Track creative output

  • Writing

  • Coding

  • Shipping

  • Drawing

Show accountability

  • Progress reporting

  • Social posting calendar

  • Campaign tracking

  • Safety checks

window.addEventListener('message', e => { if (e.data.type === 'resize') { const iframe = document.querySelector('iframe'); // assumes one iframe if (iframe) iframe.style.height = e.data.height + 'px'; } });
window.onload = () => { const a = document.createElement('a'); a.innerHTML = 'Made by @markbowley'; a.setAttribute('href', 'https://x.com/markbowley'); Object.assign(a.style, { 'position': 'fixed', 'top': 'null', 'right': '0', 'bottom': '0', 'left': 'null', 'padding': '0.3rem 0.39999999999999997rem', 'margin': '1rem 1rem 1rem 1rem', 'line-height': '0.6rem', 'color': '#ffffff', 'backgroundColor': '#333333', 'textDecoration': 'none', 'borderRadius': '0.3rem', 'font-size': '0.6rem', 'font-weight': 'normal', 'cursor': 'pointer', 'transition': 'all .2s ease-in-out', 'z-index': '1000', 'box-shadow': '0 4px 6px -4px rgb(0 0 0 / 0.1)', 'font-family': '-apple-system, BlinkMacSystemFont, avenir next, avenir, segoe ui, helvetica neue, helvetica, Cantarell, Ubuntu, roboto, noto, arial, sans-serif' }); a.onmouseover = () => a.style.transform = 'scale(1.1)'; a.onmouseout = () => a.style.transform = 'scale(1)'; a.setAttribute('target', '_blank'); document.body.append(a); }

◻️◻️◻️◻️◻️◻️

Currently just a prototype

Enter your email to try it or hear about updates first.


window.onload = () => { const a = document.createElement('a'); a.innerHTML = 'Made by @markbowley'; a.setAttribute('href', 'https://x.com/markbowley'); Object.assign(a.style, { 'position': 'fixed', 'top': 'null', 'right': '0', 'bottom': '0', 'left': 'null', 'padding': '0.3rem 0.39999999999999997rem', 'margin': '1rem 1rem 1rem 1rem', 'line-height': '0.6rem', 'color': '#ffffff', 'backgroundColor': '#333333', 'textDecoration': 'none', 'borderRadius': '0.3rem', 'font-size': '0.6rem', 'font-weight': 'normal', 'cursor': 'pointer', 'transition': 'all .2s ease-in-out', 'z-index': '1000', 'box-shadow': '0 4px 6px -4px rgb(0 0 0 / 0.1)', 'font-family': '-apple-system, BlinkMacSystemFont, avenir next, avenir, segoe ui, helvetica neue, helvetica, Cantarell, Ubuntu, roboto, noto, arial, sans-serif' }); a.onmouseover = () => a.style.transform = 'scale(1.1)'; a.onmouseout = () => a.style.transform = 'scale(1)'; a.setAttribute('target', '_blank'); document.body.append(a); }

Tracker iframe generator


Enter your details to generate an iframe code. See instructions below.


Set up your Google Sheet

  • Go to sheets.new

  • In Column A, put the dates in YYYY-MM-DD format

  • In Column B, put YES or NO or check boxes to indicate activity

  • Click Share → Change to Anyone with the link → Viewer to make it publicly readable

  • Find your Sheet ID – it's the long string between /d/ and /edit in the url


Create a Google Sheets API Key

  • Go to Google Cloud Console

  • Create a new project (or select an existing one)

  • In the left menu, go to APIs & Services → Library

  • Search for “Google Sheets API” and click Enable

  • Go to APIs & Services → Credentials → Create Credentials → API Key

  • Copy the generated API key


Google Sheets API Limits (Free tier):

  • Requests per day: ~100,000

  • Requests per 100 seconds per user: ~60

Example trackers


These are live embeds, using the prototype


Days I published a blog post this year

Days I shipped a prototype this year