The Palos Publishing Company

Follow Us On The X Platform @PalosPublishing
Categories We Write About

Create a journaling streak tracker

Here’s a simple and effective Journaling Streak Tracker built using HTML, CSS, and JavaScript. It visually tracks your daily journaling progress and highlights your current streak.

html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0"/> <title>Journaling Streak Tracker</title> <style> body { font-family: Arial, sans-serif; background: #f9f9f9; color: #333; text-align: center; padding: 2rem; } h1 { color: #444; } .streak-display { font-size: 2rem; margin: 1rem 0; color: #28a745; } .calendar { display: grid; grid-template-columns: repeat(7, 1fr); gap: 10px; margin: 2rem auto; max-width: 500px; } .day { padding: 1rem; background: #eee; border-radius: 8px; cursor: pointer; transition: 0.3s; } .day.logged { background: #28a745; color: #fff; } .controls { margin-top: 2rem; } .btn { background: #007bff; border: none; color: white; padding: 0.6rem 1.2rem; font-size: 1rem; border-radius: 5px; cursor: pointer; } .btn:hover { background: #0056b3; } </style> </head> <body> <h1>Journaling Streak Tracker</h1> <div class="streak-display">Current Streak: <span id="streak">0</span> days</div> <div class="calendar" id="calendar"></div> <div class="controls"> <button class="btn" onclick="resetStreak()">Reset Streak</button> </div> <script> const calendar = document.getElementById("calendar"); const streakDisplay = document.getElementById("streak"); const DAYS = 30; let streak = 0; let streakDates = JSON.parse(localStorage.getItem("journalStreakDates")) || []; function isToday(dateString) { const today = new Date(); const d = new Date(dateString); return today.toDateString() === d.toDateString(); } function renderCalendar() { calendar.innerHTML = ""; const today = new Date(); for (let i = DAYS - 1; i >= 0; i--) { const date = new Date(); date.setDate(today.getDate() - i); const dateStr = date.toISOString().split("T")[0]; const day = document.createElement("div"); day.classList.add("day"); day.innerText = date.getDate(); if (streakDates.includes(dateStr)) { day.classList.add("logged"); } day.onclick = () => toggleLog(dateStr, day); calendar.appendChild(day); } updateStreakDisplay(); } function toggleLog(dateStr, dayElement) { const index = streakDates.indexOf(dateStr); if (index > -1) { streakDates.splice(index, 1); dayElement.classList.remove("logged"); } else { streakDates.push(dateStr); dayElement.classList.add("logged"); } localStorage.setItem("journalStreakDates", JSON.stringify(streakDates)); updateStreakDisplay(); } function updateStreakDisplay() { streakDates = streakDates.filter(date => { const d = new Date(date); return !isNaN(d.getTime()); }); streakDates.sort((a, b) => new Date(a) - new Date(b)); streak = calculateStreak(); streakDisplay.innerText = streak; } function calculateStreak() { const today = new Date(); today.setHours(0, 0, 0, 0); let count = 0; for (let i = streakDates.length - 1; i >= 0; i--) { const date = new Date(streakDates[i]); date.setHours(0, 0, 0, 0); if (i === streakDates.length - 1) { if ((today - date) / (1000 * 3600 * 24) <= 1) { count = 1; } else { break; } } else { const prev = new Date(streakDates[i + 1]); const diff = (prev - date) / (1000 * 3600 * 24); if (diff === 1) { count++; } else { break; } } } return count; } function resetStreak() { if (confirm("Are you sure you want to reset your streak?")) { streakDates = []; localStorage.removeItem("journalStreakDates"); renderCalendar(); } } renderCalendar(); </script> </body> </html>

Features:

  • Tracks 30 days of journaling activity.

  • Click a date to mark it as “journaled.”

  • Automatically saves to localStorage.

  • Displays current streak based on consecutive days.

  • Includes a reset button.

You can copy and paste this into an .html file and open it in any browser to use the tracker. Let me know if you’d like a version with user accounts or backend integration.

Share this Page your favorite way: Click any app below to share.

Enter your email below to join The Palos Publishing Company Email List

We respect your email privacy

Categories We Write About