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
- Buka Firebase Console.
- Buat proyek baru.
- Di menu samping, pilih Realtime Database > Create Database.
- Pilih lokasi database (bebas) dan pilih Start in test mode agar bisa langsung digunakan (untuk produksi, Anda harus mengatur Rules nanti).
- 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
Komentar