Cara Membuat Widget Rating Bintang di Blogger dengan Firebase dan LocalStorage

Membuat rating Blogger dengan menggabungkan LocalStorage (agar user tidak bisa spam rating berkali-kali) dengan Firebase (untuk menyimpan data secara permanen dan sinkron antar pembaca).

Berikut adalah panduan lengkap menggunakan Firebase Realtime Database karena paling ringan dan gratis.

Persiapan Firebase

  1. Buka Firebase Console.
  2. Buat proyek baru.
  3. Di menu samping, pilih Realtime Database > Create Database.
  4. Pilih lokasi database (bebas) dan pilih Start in test mode agar bisa langsung digunakan (untuk produksi, Anda harus mengatur Rules nanti).
  5. Salin URL database Anda (contoh: [https://proyek-anda.firebaseio.com/](https://proyek-anda.firebaseio.com/)).

Kode Integrasi (HTML, CSS, JS)

Salin kode ini dan letakkan di dalam postingan Blogger (Mode HTML) atau di dalam tata letak widget.

<!-- Widget Rating by WendyCode (Modified with Firebase) -->
<style>
.rating-wrap{display:flex;gap:10px;padding:22px 0;border:1px solid #e4e3e1;border-left:0;border-right:0;font-family:sans-serif}
.rating-box{width:100%;text-align:center}
.rating-box:before{content:attr(aria-label);font-size:12px;font-weight:800}
.rating-box .stars{display:flex;justify-content:center;gap:15px;margin-top:15px}
.stars-svg{width:35px;height:35px;fill:#b5b8b1;cursor:pointer;transition:all .2s}
.stars-svg.active, .stars-svg:hover{fill:#ffb851;transform:scale(1.2)}
.stars.pointer-none {pointer-events:none}
.hasil-rating{font-weight:800;margin-top:10px}
.hasil-rating:after{content:attr(data-after);display:block;font-weight:normal;opacity:.8;font-size:12px}
.sudahRt{display:none;margin-top:10px;color:#27ae60;font-size:13px;font-weight:bold}
.sudahRt.show{display:block}
.sudahRt:after{content:attr(aria-label)}
</style>

<div class="rating-wrap">
  <div class="rating-box" aria-label="Apakah artikel ini bermanfaat">
    <div class="stars" id="starContainer">
      <!-- Star SVGs -->
      <svg class='stars-svg' data-value='1' xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M12 17.27L18.18 21l-1.64-7.03L22 9.24l-7.19-.61L12 2 9.19 8.63 2 9.24l5.46 4.73L5.82 21z'/></svg>
      <svg class='stars-svg' data-value='2' xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M12 17.27L18.18 21l-1.64-7.03L22 9.24l-7.19-.61L12 2 9.19 8.63 2 9.24l5.46 4.73L5.82 21z'/></svg>
      <svg class='stars-svg' data-value='3' xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M12 17.27L18.18 21l-1.64-7.03L22 9.24l-7.19-.61L12 2 9.19 8.63 2 9.24l5.46 4.73L5.82 21z'/></svg>
      <svg class='stars-svg' data-value='4' xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M12 17.27L18.18 21l-1.64-7.03L22 9.24l-7.19-.61L12 2 9.19 8.63 2 9.24l5.46 4.73L5.82 21z'/></svg>
      <svg class='stars-svg' data-value='5' xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M12 17.27L18.18 21l-1.64-7.03L22 9.24l-7.19-.61L12 2 9.19 8.63 2 9.24l5.46 4.73L5.82 21z'/></svg>
    </div>
    <div class='hasil-rating' id="ratingText" data-after='memuat suara...'>0/5</div>
    <div class='sudahRt' id="msgDone" aria-label='Terima kasih! Anda sudah memberi rating.'></div>
  </div>
</div>

<script>
// --- KONFIGURASI ---
const FIREBASE_URL = "ISI_DENGAN_URL_FIREBASE_ANDA"; // Contoh: https://xyz.firebaseio.com/
const POST_ID = window.location.pathname.replace(/[^a-zA-Z0-9]/g, ""); // ID unik berdasarkan URL

const starContainer = document.getElementById('starContainer');
const stars = document.querySelectorAll('.stars-svg');
const ratingText = document.getElementById('ratingText');
const msgDone = document.getElementById('msgDone');

// --- 1. AMBIL DATA DARI FIREBASE ---
async function fetchRating() {
  const response = await fetch(`${FIREBASE_URL}/ratings/${POST_ID}.json`);
  const data = await response.json();
  
  if (data) {
    const avg = (data.totalPoints / data.count).toFixed(1);
    updateDisplay(avg, data.count);
  } else {
    updateDisplay(0, 0);
  }
}

function updateDisplay(avg, count) {
  ratingText.innerText = `${avg}/5`;
  ratingText.setAttribute('data-after', `${count} suara`);
  // Beri warna bintang sesuai rata-rata
  stars.forEach(s => {
    if (parseInt(s.dataset.value) <= Math.round(avg)) s.classList.add('active');
  });
}

// --- 2. CEK LOCALSTORAGE (Sudah vote belum?) ---
if (localStorage.getItem('rated_' + POST_ID)) {
  starContainer.classList.add('pointer-none');
  msgDone.classList.add('show');
}

// --- 3. LOGIKA VOTE ---
stars.forEach(star => {
  star.addEventListener('click', async () => {
    if (localStorage.getItem('rated_' + POST_ID)) return;

    const val = parseInt(star.dataset.value);
    
    // Ambil data terbaru dulu
    const response = await fetch(`${FIREBASE_URL}/ratings/${POST_ID}.json`);
    const data = (await response.json()) || { totalPoints: 0, count: 0 };

    // Update data
    const newData = {
      totalPoints: data.totalPoints + val,
      count: data.count + 1
    };

    // Simpan ke Firebase
    await fetch(`${FIREBASE_URL}/ratings/${POST_ID}.json`, {
      method: 'PUT',
      body: JSON.stringify(newData)
    });

    // Simpan ke LocalStorage agar tidak vote lagi
    localStorage.setItem('rated_' + POST_ID, true);
    
    // UI Feedback
    location.reload(); // Refresh sederhana untuk update tampilan
  });
});

fetchRating();
</script>
Sumber: WendyCode
Aurealisa ID
Fakta Gambar (Science Fact), Kutipan (Quote Of The Day), Ulasan (Science Review), Tips, Artikel.

Komentar