v i b e Scriptz

Reading time badge with vanilla JS

November 29, 2025 NEW

Tags: javascript reading time ux microcopy

What this snippet does

Sometimes you just want a tiny “3 min read” badge under your title without pulling in a whole framework. This snippet:

You give your main content a class (for example .vibe-article) and place a badge span near the title with class .vibe-reading-time. The script does the rest.

<style>
  /* Tiny reading time badge */
  .vibe-reading-time {
    display: inline-block;
    margin-left: 6px;
    padding: 2px 8px;
    border-radius: 999px;
    font-size: 12px;
    line-height: 1.4;
    background: #f2f4ff;
    color: #333;
    border: 1px solid #d3d7ff;
    white-space: nowrap;
  }
</style>

<script>
  (function () {
    // Words per minute you want to assume
    var WORDS_PER_MINUTE = 220;

    // Where your main article content lives
    var article = document.querySelector('.vibe-article');
    // Where the badge text should be rendered
    var badge = document.querySelector('.vibe-reading-time');

    if (!article || !badge) {
      return; // nothing to do
    }

    var text = article.innerText || article.textContent || '';
    text = text.trim();
    if (!text) {
      return;
    }

    // Count words
    var words = text.split(/\s+/).filter(Boolean).length;
    var minutes = Math.round(words / WORDS_PER_MINUTE);

    if (!minutes || minutes < 1) {
      minutes = 1;
    }

    badge.textContent = minutes + ' min read';
  })();
</script>

How to use it

  1. Wrap your main article content in a container, for example:
    <article class="vibe-article">...your post text...</article>
  2. Add the badge span near your title, for example:
    <h1>My post title <span class="vibe-reading-time"></span></h1>
  3. Paste the <style> and <script> block into your layout (near the bottom of the page or in a shared template).

The script will look at .vibe-article, count words, and drop the finished badge text into .vibe-reading-time. If you write long posts, bump WORDS_PER_MINUTE up or down to match your audience.

← Back to all scripts