p7xhMSO4O9fyfib8OANOxXym2LUEvDesKq0YUJbG

Pengaturan

Pilih Warna Tema

Bookmark

Cara Membuat Widget Dynamic Recently Viewed Post di Blog

Membuat Fitur Dynamic Recent Viewed Post di Blogger
Membuat Fitur Dynamic Recent Viewed Post di Blogger

Halo semua, rasanya sudah lama tidak update postingan dan membahas seputar Blogger. Di postingan kali ini, saya akan membahas sekaligus berbagi script fitur sederhana namun sangat powerful, yaitu widget recently viewed posts blogspot. Fitur ini memungkinkan para pengunjung blog dapat melihat kembali artikel yang terakhir mereka baca dari blog kita, jadi mereka tidak perlu repot mencari ulang postingan sebelumnya melalui halaman sitemap kalau belum selesai membaca atau ingin dilanjutkan nanti.

Menariknya, kamu tidak perlu database atau backend untuk membuat fitur dynamic recently viewed posts blogspot ini. Cukup memanfaatkan localStorage browser di JavaScript, semua data seperti judul artikel, thumbnail artikel, dan link artikel bisa disimpan langsung di browser user. Cara ini jauh lebih ringan, cepat, dan sangat cocok digunakan di platform seperti Blogger yang memiliki keterbatasan akses backend.

Selain itu, implementasinya juga bisa dibuat lebih interaktif dengan tampilan slider modern. Dengan menggabungkan konsep recent viewed post JavaScript dan efek swipe (geser), widget ini bisa terlihat seperti fitur profesional layaknya website profesional. Ditambah lagi dengan auto slide, efek animasi skeleton pre-loading, dan indikator navigasi, tampilan blog kamu akan terasa lebih hidup dan tidak kalah dengan website-website premium.

Fitur ini saya buat karena terinspirasi oleh salah satu template premium blogspot buatan GilaTemax, yaitu DUID. Hanya saja saya modifikasi sedikit pada fungsionalnya agar terkesan lebih interaktif dan profesional. Bagi kamu yang ingin mencoba memasang fitur dynamic recently viewed posts ini di blog, kamu bisa ikuti langkah-langkahnya di bawah ini. Untuk demo fiturnya, silakan klik tombol demo berikut.

Kelebihan Memasang Fitur/Widget Dynamic Recently Viewed Posts di Blog

Salah satu kelebihan utama memasang fitur dynamic recently viewed posts Blogger adalah meningkatkan kenyamanan pengguna saat menjelajahi blog. Pengunjung tidak perlu lagi mengingat atau mencari ulang artikel yang sebelumnya dibaca, karena semuanya sudah tersedia dalam satu widget yang praktis. Hal ini sangat membantu terutama bagi user yang membaca secara bertahap, sehingga mereka bisa langsung melanjutkan tanpa kehilangan jejak.

Dari sisi teknis, penggunaan localStorage recent posts membuat fitur ini jauh lebih ringan dan efisien sehingga tidak akan memberatkan loading blog kamu. Semua data disimpan langsung di browser pengguna tanpa perlu database atau request tambahan ke server. Selain mengurangi beban hosting, metode ini juga membuat loading lebih cepat dan responsif, sehingga sangat cocok diterapkan pada platform seperti Blogger yang memiliki keterbatasan backend.

Selain fungsional, widget dynamic recently viewed posts blogspot ini juga memberikan nilai tambah dari segi tampilan. Dengan memanfaatkan konsep recent viewed post JavaScript yang dikombinasikan dengan slider, swipe, dan auto slide, blog akan terlihat lebih modern dan interaktif. Tampilan seperti ini tidak hanya menarik secara visual, tetapi juga bisa meningkatkan engagement karena pengunjung terdorong untuk kembali membuka artikel yang sebelumnya mereka kunjungi.

Memasang Fitur Dynamic Recently Viewed Posts di Blog

Berikut cara membuat widget dynamic recently viewed posts di blogspot menggunakan JavaScript open source. Simak langkah-langkanya dengan baik agar tidak terjadi error saat memasang kodenya.

  1. Pertama, buka dashboard Blogger kamu.
  2. Masuk ke menu Tema Edit HTML.
  3. Kemudian salin semua kode JavaScript di bawah ini ke dalam template blog. Kamu bisa gabungkan kode JavaScript di bawah ini dengan kode JavaScript lain di template kamu. Atau, kamu bisa simpan kodenya DI ATAS tag </body>.
  4. <script>/*<![CDATA[*/
    //* script dynamic recent viewed posts by ignelius.com - source : https://www.ignelius.com/2026/04/buat-widget-dynamic-recent-viewed-post.html*/
    
    const MAX_POST = 5; // maksimal jumlah artikel yang diload
    const AUTO_SLIDE_INTERVAL = 2500; // waktu jeda auto slide - 2500 milidetik = 2,5 detik
    const STORAGE_KEY = "recent_posts"; // jangan diedit/dihapus
    const DEFAULT_THUMB = "https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhYsIrfaJQ2BytaxI1q1G7q2EUA3g5TlaVeDxmihX66oHzidd9bewbuP7_cQJXgRuDF0dps3MCJcQPHEQ1SPTE8nd-Hj4uXLq5I9pK88gD6n6Z5WmUz5v7bq2g0rxn5dRg7WmNB51iNxqaGjeE2vh6jl4KzeGlb3eKBUE5J1Lh4Dw3wfrjTuQ5AKahQRQ/s0/igniplex-noimage.png"; // gambar default jika artikel tidak punya thumbnail
    const DEVELOPER = "www.ignelius.com";
    
    let currentIndex = 0;
    let posts = [];
    let autoSlide;
    
    const slider = document.getElementById("slider");
    const indicators = document.getElementById("indicators");
    const widget = document.getElementById("recent-widget");
    
    function getPosts() {
      let data = JSON.parse(localStorage.getItem(STORAGE_KEY)) || [];
      return data.slice(0, MAX_POST);
    }
    
    function getImage(src) {
      if (!src || src.trim() === "") return DEFAULT_THUMB;
      return src;
    }
      
    function renderSkeleton() {
      slider.innerHTML = "";
      for (let i = 0; i < 1; i++) {
        const skel = document.createElement("div");
        skel.className = "recent-card";
    
        skel.innerHTML = `
          <div class="ignelius-skeleton skeload-img"></div>
          <div>
            <div class="ignelius-skeleton skeload-text"></div>
          </div>
        `;
        slider.appendChild(skel);
      }
    }
    
    /* ======= PRELOAD IMAGE ======= */
    function preloadImages(list, callback) {
      let loaded = 0;
      if (list.length === 0) return callback();
    
      list.forEach(post => {
        const img = new Image();
        img.src = getImage(post.image);
        img.onload = img.onerror = () => {
          loaded++;
          if (loaded === list.length) callback();
        };
      });
    }
    
    /* ======= RENDER POSTS ======= */
    function render() {
      posts = getPosts();
      if (posts.length === 0) {
        widget.style.display = "none";
        return;
      } else {
        widget.style.display = "block";
      }
    
      slider.innerHTML = "";
      indicators.innerHTML = "";
    
      posts.forEach((post, index) => {
        const card = document.createElement("div");
        card.className = "recent-card";
    
        const imgSrc = getImage(post.image);
    
        card.innerHTML = `
          <img src="${imgSrc || DEFAULT_THUMB}" onerror="this.src='${DEFAULT_THUMB}'" />
          <div class="recent-text">
            <div class="hLine">Lanjutkan Membaca?</div>
            <div class="jPost" title="${post.title}">${post.title}</div>
          </div>
          <div class="close-btn">✕</div>
        `;
    
        card.addEventListener("click", (e) => {
          if (e.target.classList.contains("close-btn")) return;
          window.location.href = post.url;
        });
    
        card.querySelector(".close-btn").onclick = (e) => {
          e.stopPropagation();
          removePost(index);
        };
    
        slider.appendChild(card);
    
        if (posts.length > 1) {
          const dot = document.createElement("span");
          dot.className = "dot";
          if (index === currentIndex) dot.classList.add("active");
          
          dot.addEventListener("click", () => {
            currentIndex = index;
            updateSlider();
          });
    
          indicators.appendChild(dot);
        }
      });
    
      updateSlider();
    }
    
    function updateSlider(animate = true) {
      slider.style.transition = animate ? "transform 0.4s ease" : "none";
      slider.style.transform = `translateX(-${currentIndex * 100}%)`;
    
      document.querySelectorAll(".dot").forEach((dot, i) => {
        dot.classList.toggle("active", i === currentIndex);
      });
    }
    
    /* ======= AUTO SLIDE ======= */
    function startAutoSlide() {
      clearInterval(autoSlide);
    
      if (posts.length <= 1) return;
    
      autoSlide = setInterval(() => {
        currentIndex = (currentIndex + 1) % posts.length;
        updateSlider();
      }, AUTO_SLIDE_INTERVAL);
    }
    
    /* ======= REMOVE POST ======= */
    function removePost(index) {
      let data = JSON.parse(localStorage.getItem(STORAGE_KEY)) || [];
      data.splice(index, 1);
      localStorage.setItem(STORAGE_KEY, JSON.stringify(data));
    
      if (currentIndex >= data.length) currentIndex = 0;
    
      render();
    }
    
    let startX = 0;
    let currentX = 0;
    let isDragging = false;
    
    function onStart(e) {
      isDragging = true;
      startX = e.touches ? e.touches[0].clientX : e.clientX;
      slider.style.transition = "none";
      clearInterval(autoSlide);
    }
    
    function onMove(e) {
      if (!isDragging) return;
    
      currentX = e.touches ? e.touches[0].clientX : e.clientX;
      const diff = currentX - startX;
    
      slider.style.transform =
        `translateX(${ -currentIndex * slider.offsetWidth + diff }px)`;
    }
    
    function onEnd() {
      if (!isDragging) return;
      isDragging = false;
    
      const diff = currentX - startX;
    
      if (Math.abs(diff) > 50) {
        if (diff < 0) currentIndex++;
        else currentIndex--;
      }
    
      if (currentIndex < 0) currentIndex = posts.length - 1;
      if (currentIndex >= posts.length) currentIndex = 0;
    
      updateSlider();
      startAutoSlide();
    }
    
    slider.addEventListener("touchstart", onStart);
    slider.addEventListener("touchmove", onMove);
    slider.addEventListener("touchend", onEnd);
    
    slider.addEventListener("mousedown", onStart);
    slider.addEventListener("mousemove", onMove);
    slider.addEventListener("mouseup", onEnd);
    slider.addEventListener("mouseleave", onEnd);
    
    function init() {
      renderSkeleton();
    
      setTimeout(() => {
        posts = getPosts();
    
        preloadImages(posts, () => {
          render();
          startAutoSlide();
        });
      }, 500);
    }
    
    init();
    /*]]>*/</script>
    <b:if cond='data:view.isPost'>
      <script>/*<![CDATA[*/
    function saveRecentPost() {
      const KEY = "recent_posts";
      let data = JSON.parse(localStorage.getItem(KEY)) || [];
    
      const post = {
        title: document.querySelector('meta[property="og:title"]')?.content || document.title,
        image: document.querySelector('meta[property="og:image"]')?.content || "",
        url: window.location.href
      };
    
      data = data.filter(item => item.url !== post.url);
      data.unshift(post);
    
      if (data.length > 10) data = data.slice(0, 10);
    
      localStorage.setItem(KEY, JSON.stringify(data));
    }
    
    saveRecentPost();
      /*]]>*/</script>
    </b:if>
    Pertahikan pada teks yang ditandai berikut:
    MAX_POST : adalah untuk mengatur jumlah maksimal postingan yang akan diload dalam widget dynamic recent viewed posts ini. Jika diatur 5, maka postingan yang akan ditampilkan dalam widget dynamic recent viewed posts sebanyak 5 postingan.
    AUTO_SLIDE_INTERVAL : adalah durasi atau waktu jeda auto slide posts. Menggunakan hitungan milidetik. Yang berarti jika diatur ke 2500, maka waktu jeda auto slide nya adalah 2,5 detik.
    DEFAULT_THUMB : adalah URL gambar thumbnail default atau pengganti jika postingan di blog kamu tidak memiliki gambar thumbnail bawaan.
  5. Langkah selanjutnya (masih dalam template HTML blog) cari kode //]]></b:skin> atau </style> kemudian salin dan tempel kode CSS di bawah ini tepat DI ATAS kode tersebut.
  6. /* css widget dynamic recent viewed posts by ignelius.com */
    .recent-card {
      min-width: 100%;
      background: #e1f5f3; /* warna background widget */
      border-radius: 50px; /* border atau lengkungan di sisi widget */
      padding: 8px 12px;
      display: flex;
      align-items: center;
      gap: 12px;
    }
    
    /* Thumbnail */
    .recent-card img {
      width: 45px;
      height: 45px;
      border-radius: 50%;
      object-fit: cover;
      flex-shrink: 0;
    }
    
    /* Text container */
    .recent-text {
      display: flex;
      flex-direction: column;
      justify-content: center;
      flex: 1;
      overflow: hidden;
    }
    
    /* Continue reading */
    .recent-text .hLine {
      font-size: 12px;
      color: #777;
      margin-bottom: 2px;
    }
    
    /* Title (1 line ellipsis) */
    .recent-text .jPost {
      font-weight: 600;
      white-space: nowrap;
      overflow: hidden;
      text-overflow: ellipsis;
    }
    .recent-container {
      width: 100%;
      max-width: 420px;
      overflow: hidden;
    }
    
    .recent-slider {
      display: flex;
      transition: transform 0.4s ease;
    }
    
    .recent-card img {
      width: 45px;
      height: 45px;
      border-radius: 50%;
      object-fit: cover;
    }
    
    .recent-text small {
      color: #777;
    }
    
    .close-btn {
      margin-left: auto;
      cursor: pointer;
    }
    
    /* Skeleton */
    .ignelius-skeleton {
      animation: shimmer 1.5s infinite linear;
      background: linear-gradient(90deg, #eee 25%, #ddd 50%, #eee 75%);
      background-size: 200% 100%;
    }
    
    .skeload-img {
      width: 45px;
      height: 45px;
      border-radius: 50%;
    }
    
    .skeload-text {
      height: 10px;
      width: 120px;
      border-radius: 6px;
    }
    
    @keyframes shimmer {
      0% { background-position: -200% 0; }
      100% { background-position: 200% 0; }
    }
    
    /* Indicators */
    .recent-indicators {
      display: flex;
      justify-content: center;
      align-items: center;
      margin: 1rem 0;
    }
    .dot {
      width: 10px;
      height: 10px;
      background: #bbb;
      margin: 0 3px;
      display: inline-block;
      border-radius: 50%;
    }
    
    .dot.active {
      background: #333;
    }
  7. Jika semua kode sudah ditambahkan ke dalam template HTML blog, klik simpan.
  8. Langkah terakhir, kembali ke halaman dashboard blogspot. Masuk ke menu Tata Letak atau Layout tambahkan satu gadget HTML/JavaScript baru. Untuk posisinya bebas mau diletakkan di bagian mana saja, misal di sidebar atau di bawah header blog juga bisa. Tapi posisi yang paling cocok untuk memasang widget recently viewed posts ini adalah di bawah widget Pinned Post atau sebelum widget Postingan Blog.
  9. Di bagian konten gadget, isi dengan kode HTML widget recentlt viewed posts berikut ini.
  10. <!--[ widget dynamic recent viewed posts by ignelius.com - source : https://www.ignelius.com/2026/04/buat-widget-dynamic-recent-viewed-post.html ]-->
    <div id="recent-widget" class="recent-container">
      <div class="recent-slider" id="slider"></div>
      <div class="recent-indicators" id="indicators"></div>
    </div>
  11. Jika sudah, klik simpan dan uji coba hasil membuat widget recently viewed posts ini di blog kamu.

Penutup

Itu dia panduan lengkap cara membuat widget dynamic recently viewed posts di blog menggunakan JavaScript sederhana tanpa perlu database. Dengan memanfaatkan teknik seperti recent viewed post javascript dan penyimpanan data berbasis browser, kamu bisa menghadirkan fitur yang tidak hanya fungsional, tetapi juga meningkatkan pengalaman pengguna secara keseluruhan.

Perlu diingat, meskipun script ini dibagikan secara gratis dan open source, kamu tetap tidak diperbolehkan menggunakan atau mendistribusikannya untuk kepentingan komersial tanpa izin. Semoga tutorial ini bisa membantu kamu dalam mengembangkan blog yang lebih menarik dan profesional.

Jika kamu mengalami kendala saat memasang widget recently viewed posts Blogger atau ingin mengembangkan fitur ini lebih lanjut, jangan ragu untuk bertanya melalui kolom komentar. Dengan berdiskusi, dapat membantu kita semua untuk belajar dan berkembang bersama.

dynamic recently viewed posts blogger
recently viewed posts blogger
recent viewed post javascript
localstorage recent posts javascript
cara membuat recent viewed posts blogger
widget recent viewed posts blogger
recently viewed posts tanpa database
javascript recent viewed posts
cara menyimpan data localstorage javascript
tutorial recent viewed posts blogger
dynamic recent posts javascript
recent posts otomatis blogger
continue reading widget blogger
cara membuat continue reading otomatis
recent viewed posts dengan swipe slider
javascript slider swipe tutorial
membuat slider otomatis javascript
recent viewed post dengan auto slide
widget blog modern javascript
fitur artikel terakhir dibaca blogger
cara menampilkan artikel terakhir dibaca
recent viewed post tanpa backend
recent posts tanpa database blogger
membuat widget interaktif blogger
recent viewed post dengan localstorage
javascript touch swipe slider
recent viewed posts responsive
widget blogger swipe slider
recent viewed post dengan indikator dot
recent viewed post dengan auto swipe
cara membuat widget blogger modern
recent viewed post dengan thumbnail otomatis
recent viewed post dengan fallback image
recent viewed posts ui modern
recent viewed post dengan skeleton loading
cara membuat skeleton loading javascript
recent viewed post preload image
widget recent viewed posts gratis
recent viewed posts open source javascript
recent viewed posts ringan dan cepat
recent viewed posts tanpa api
cara membuat widget artikel terakhir dikunjungi
recent viewed post dengan animasi smooth
recent viewed posts untuk meningkatkan ux
recent viewed posts untuk blogger pemula
recent viewed post mobile friendly
recent viewed post dengan click redirect
recent viewed post dengan hapus item
recent viewed posts dengan limit data
recent viewed post dengan localstorage browser
tips mempercantik blogspot
buat fitur modern dan interaktif di blog
rekomendasi widget modern dan interaktif blogger
javascript open source dynamic recent viewed post
tips agar blog lebih modern dan profesional
Komentar

Posting Komentar

Sebelum memposting komentar, harap baca kebijakan berkomentar terlebih dulu.

1. Untuk menulis kode syntax highlighter, gunakan <i rel="pre">KODE SYNTAX DI SINI</i> (kode harus di parse terlebih dulu).
2. Untuk menyisipkan gambar dalam komentar, gunakan <strong>URL GAMBAR</strong>.
3. Untuk menulis tautan, gunakan <a href='URL WEB TUJUAN'>Anchor Teks</a>.
4. Untuk menulis sebuah quote / kutipuan, gunakan <i rel="quote">TULIS QUOTE DI SINI</i>.
5. Centang Beri Tahu Saya untuk mendapatkan notifikasi yang dikirim langsung ke email saat ada yang membalas komentar kamu.