Berikut adalah panduan tutorial dan tata cara pemasangan widget Notifikasi & Komentar 3D Glassmorphism yang sudah dioptimalkan untuk blog warkasa1919.my.id agar aman untuk SEO, ramah kecepatan muat (Core Web Vitals), dan tampil sempurna.
🛠️ Opsi Pemasangan di Warkasa1919
Terdapat 2 metode utama untuk memasang widget ini. Pilih metode yang paling sesuai dengan kebutuhan situs Anda:
METODE 1: Pasang di Seluruh Blog (Global Layout / Tema Blogger)
Rekomendasi Utama: Menggunakan metode ini membuat widget tombol melayang (floating bubble) atau widget widget-box otomatis aktif di semua postingan/halaman tanpa perlu menempelkan kode satu per satu di setiap artikel.
Langkah-Langkah:
Masuk ke Dashboard Blogger Anda.
Pilih menu Tema (Theme) $\rightarrow$ klik tanda panah kecil di sebelah tombol Sesuaikan (Customize) $\rightarrow$ pilih Edit HTML.
Klik di dalam area kode HTML, lalu tekan
Ctrl + F(atauCmd + Fdi Mac) untuk membuka kolom pencarian.Cari tag penutup halaman:
</body>.Tempelkan (Paste) kode utuh yang sudah disediakan tepat di atas / sebelum tag
</body>.Klik ikon Simpan (Save) di pojok kanan atas.
METODE 2: Pasang Hanya di Artikel / Halaman Tertentu
Digunakan jika Anda hanya ingin widget ini muncul sebagai Embedded Container di dalam konten artikel spesifik (misalnya di halaman Member, Jasa, atau postingan khusus).
Langkah-Langkah:
Buka editor artikel atau halaman baru di Blogger.
Pada pojok kiri atas editor (di sebelah ikon pensil), ubah tampilan dari Tampilan Menulis (Compose view) menjadi Tampilan HTML (HTML view).
Tempelkan kode di posisi yang Anda inginkan (biasanya di bagian paling bawah artikel).
Klik Publikasikan atau Perbarui.
🚀 Fitur & Keunggulan SEO / Performa
Zero Cumulative Layout Shift (CLS): Menggunakan properti
contain: content;dan ukuran pembungkus yang pasti agar struktur tata letak artikel tidak bergoyang saat widget memuat data (Core Web Vitals Friendly).Lazy Loading Native: Gambar avatar menggunakan
loading="lazy"native browser sehingga gambar tidak membebani kecepatan rendering awal (First Contentful Paint).Fitur Aksesibilitas (a11y): Dilengkapi tag semantic
aria-label,role="region", danaria-liveyang ramah terhadap mesin pencari (Googlebot) dan screen reader.XSS Protection: Pengambilan data komentar dari Feed Blogger dibersihkan dari tag HTML liar sebelum di-render ke halaman.
Auto Dark Mode: Otomatis menyesuaikan skema warna secara dinamis jika pengunjung mengaktifkan mode gelap di perangkat mereka.
💡 Tips & Customization Tambahan
Menambah / Mengubah Menu Notifikasi Static:
Jika ingin mengubah tautan notifikasi ke artikel terbaru Anda, cukup sesuaikan array
staticDatadi dalam kodenya:JavaScriptconst staticData = [ {id:"n1", type:"premium", title:"Judul Notif Anda", body:"Deskripsi singkat...", url:"https://www.warkasa1919.my.id/link-artikel.html"}, // tambah item di sini... ];Pengujian Tampilan:
Setelah dipasang, buka blog Anda menggunakan tab Incognito / Private Window untuk memastikan tampilan Glassmorphism dan penyimpanan lokal (
localStorage) bekerja dengan bersih.
Berikut adalah kode utuh siap pasang yang sudah disesuaikan agar langsung muncul di halaman/postingan (secara otomatis tampil sebagai widget inline/embedded yang rapi di dalam artikel) sekaligus memiliki tombol melayang (floating) jika dipasang di tema.
Kode ini sudah dioptimalkan penuh untuk SEO, Kecepatan Loading (LCP/CLS/INP), Glassmorphism 3D, serta aman dari konflik script tema.
Kode Utuh Siap Pasang
<!-- =============== SUPER MINI NOTIFICATION & KOMENTAR (SIAP PASANG) =============== -->
<style>
/* CSS Reset & Performance Isolation */
.wk-container, .wk-container * {
box-sizing: border-box;
font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
}
/* Container utama di dalam postingan */
.wk-container {
width: 100%;
max-width: 480px;
margin: 20px auto;
position: relative;
z-index: 99;
}
/* Glassmorphism Panel (Tampil langsung di artikel) */
#wkMiniPanel {
width: 100%;
background: rgba(255, 255, 255, 0.75);
backdrop-filter: blur(16px) saturate(180%);
-webkit-backdrop-filter: blur(16px);
border-radius: 16px;
border: 1px solid rgba(255, 255, 255, 0.6);
box-shadow: 0 12px 32px rgba(0, 0, 0, 0.08);
overflow: hidden;
display: flex;
flex-direction: column;
contain: content;
}
/* Header & Filter */
.wk-m-head {
padding: 12px 14px;
font-size: 14px;
font-weight: 700;
display: flex;
justify-content: space-between;
align-items: center;
border-bottom: 1px solid rgba(0, 0, 0, 0.06);
color: #1e293b;
}
.wk-m-filter {
padding: 4px 8px;
font-size: 12px;
border-radius: 6px;
border: 1px solid rgba(0, 0, 0, 0.12);
background: rgba(255, 255, 255, 0.8);
color: #334155;
outline: none;
cursor: pointer;
}
/* Tabs Navigation */
.wk-m-tabs {
display: flex;
background: rgba(0, 0, 0, 0.03);
border-bottom: 1px solid rgba(0, 0, 0, 0.05);
}
.wk-tab {
flex: 1;
text-align: center;
padding: 10px 0;
font-size: 13px;
font-weight: 600;
color: #64748b;
cursor: pointer;
transition: all 0.2s ease;
user-select: none;
}
.wk-tab.active {
background: rgba(255, 255, 255, 0.85);
color: #0f172a;
box-shadow: inset 0 -2px 0 #2563eb;
}
/* List Items */
.wk-m-list {
padding: 12px;
overflow-y: auto;
max-height: 420px;
display: flex;
flex-direction: column;
gap: 10px;
}
.wk-m-item {
display: flex;
gap: 12px;
padding: 10px;
border-radius: 12px;
background: rgba(255, 255, 255, 0.6);
border: 1px solid rgba(255, 255, 255, 0.4);
cursor: pointer;
align-items: flex-start;
transition: transform 0.2s ease, background 0.2s ease, box-shadow 0.2s ease;
}
.wk-m-item:hover {
transform: translateY(-2px);
background: rgba(255, 255, 255, 0.95);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
}
.wk-m-item.unread {
border-left: 3px solid #ef4444;
}
.wk-m-avatar {
width: 44px;
height: 44px;
border-radius: 10px;
object-fit: cover;
background: #e2e8f0;
flex-shrink: 0;
}
.wk-m-body {
flex: 1;
font-size: 12px;
color: #334155;
line-height: 1.4;
}
.wk-m-body b {
display: block;
font-size: 13px;
color: #0f172a;
margin-bottom: 3px;
}
.wk-m-meta {
font-size: 11px;
color: #94a3b8;
margin-top: 4px;
}
/* Footer Action */
.wk-m-foot {
border-top: 1px solid rgba(0, 0, 0, 0.05);
padding: 10px 14px;
display: flex;
justify-content: space-between;
align-items: center;
background: rgba(255, 255, 255, 0.4);
}
.wk-btn-action {
font-size: 12px;
font-weight: 500;
padding: 6px 12px;
border-radius: 8px;
border: 1px solid rgba(0, 0, 0, 0.1);
background: #ffffff;
color: #334155;
cursor: pointer;
transition: background 0.2s;
}
.wk-btn-action:hover {
background: #f8fafc;
}
/* Badge Indicator */
#wkMiniBadge {
display: inline-flex;
align-items: center;
justify-content: center;
background: #ef4444;
color: #ffffff;
font-size: 10px;
font-weight: 700;
padding: 2px 6px;
border-radius: 10px;
margin-left: 6px;
}
/* Dark Mode Adaptability */
@media (prefers-color-scheme: dark) {
#wkMiniPanel {
background: rgba(15, 23, 42, 0.8);
border-color: rgba(255, 255, 255, 0.08);
color: #f1f5f9;
box-shadow: 0 12px 32px rgba(0, 0, 0, 0.4);
}
.wk-m-head { border-bottom-color: rgba(255, 255, 255, 0.08); color: #f8fafc; }
.wk-m-tabs { background: rgba(0, 0, 0, 0.25); }
.wk-tab { color: #94a3b8; }
.wk-tab.active { background: rgba(255, 255, 255, 0.08); color: #f8fafc; box-shadow: inset 0 -2px 0 #60a5fa; }
.wk-m-item { background: rgba(255, 255, 255, 0.04); border-color: rgba(255, 255, 255, 0.05); }
.wk-m-item:hover { background: rgba(255, 255, 255, 0.08); }
.wk-m-body { color: #cbd5e1; }
.wk-m-body b { color: #f8fafc; }
.wk-m-filter, .wk-btn-action { background: rgba(30, 41, 59, 0.8); color: #f8fafc; border-color: rgba(255, 255, 255, 0.1); }
.wk-btn-action:hover { background: rgba(51, 65, 85, 0.8); }
}
</style>
<!-- HTML Container (Langsung Tampil di Halaman Postingan) -->
<div class="wk-container">
<div id="wkMiniPanel" role="region" aria-label="Notifikasi dan Komentar">
<div class="wk-m-head">
<div>
<span>Notifikasi</span>
<span id="wkMiniBadge" style="display:none;">0</span>
</div>
<select id="wkMiniFilter" class="wk-m-filter" aria-label="Filter Notifikasi">
<option value="all">Semua</option>
<option value="premium">Premium</option>
<option value="paid">Berbayar</option>
<option value="service">Jasa</option>
</select>
</div>
<div class="wk-m-tabs" role="tablist">
<div class="wk-tab active" data-tab="notif" role="tab" tabindex="0">Notifikasi</div>
<div class="wk-tab" data-tab="komentar" role="tab" tabindex="0">Komentar Terbaru</div>
</div>
<div id="wkMiniList" class="wk-m-list" aria-live="polite">Memuat data...</div>
<div class="wk-m-foot">
<span style="font-size:11px;color:#94a3b8;">Warkasa1919 Widget</span>
<button id="wkMiniMark" class="wk-btn-action">Tandai Dibaca</button>
</div>
</div>
</div>
<script>
(() => {
'use strict';
// Avatar Default
const DEFAULT_AVATAR = "https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEigbIWh7AOLVY8BwC1JFFHOx0yq5X6aicJvfjNbXKYjkaPa1CzWPnpbIPO08imNkly0q46c8fISjcQX4DOspKAETvhuXvLWw5bp1yFunYDufWi-7vSxfAyM_zEMPQN-o9XbSmYnRp0pi2_j3oprVMeXcSdCrjytAwOY09MhWQOfSbf0btK0x7CLMgGJlkMv/s500/ChatGPT_Image_12_Sep_2025__13.02.07-removebg-preview.webp";
// Data Static Notifikasi
const staticData = [
{id:"n1", type:"premium", title:"Member dan Informasi", body:"Akses artikel eksklusif dan layanan premium.", url:"https://www.warkasa1919.my.id/p/member-1919_13.html"},
{id:"n2", type:"paid", title:"Jasa Pembuatan Blogger", body:"Layanan pembuatan blog profesional siap pakai.", url:"https://www.warkasa1919.my.id/p/jasa-pembuatan-blog-siap-pakai.html"},
{id:"n3", type:"service", title:"Jasa Website WordPress", body:"Pembuatan website bisnis & personal teroptimasi.", url:"https://www.warkasa1919.my.id/p/jasa-pembuatan-website-1919.html"}
];
let read = JSON.parse(localStorage.getItem('wk_read') || '{}');
let notifData = [...staticData];
const $ = id => document.getElementById(id);
const badge = $('wkMiniBadge'), list = $('wkMiniList'), filter = $('wkMiniFilter'), mark = $('wkMiniMark');
// Time Formatter
const timeAgo = ts => {
if (!ts) return '';
const s = Math.floor((Date.now() - ts) / 1000);
if (s < 60) return s + 's lalu';
if (s < 3600) return Math.floor(s / 60) + 'm lalu';
if (s < 86400) return Math.floor(s / 3600) + 'j lalu';
return Math.floor(s / 86400) + 'h lalu';
};
// Render Notifikasi
function renderNotif() {
const f = filter.value;
const rows = notifData.filter(x => f === 'all' || x.type === f);
if (!rows.length) {
list.innerHTML = `<div style="padding:20px;text-align:center;color:#94a3b8;font-size:13px;">Tidak ada notifikasi</div>`;
badge.style.display = 'none';
return;
}
const fragment = document.createDocumentFragment();
rows.forEach(item => {
const unread = !read[item.id];
const div = document.createElement('div');
div.className = `wk-m-item ${unread ? 'unread' : ''}`;
div.onclick = () => {
read[item.id] = true;
localStorage.setItem('wk_read', JSON.stringify(read));
if (item.url) window.open(item.url, '_blank', 'noopener');
renderNotif();
};
div.innerHTML = `
<img class="wk-m-avatar" src="${item.avatar || DEFAULT_AVATAR}" alt="Avatar" loading="lazy" width="44" height="44" />
<div class="wk-m-body">
<b>${item.title}</b>
<div>${item.body || ''}</div>
<div class="wk-m-meta">${timeAgo(item.ts)} ${item.source ? '· ' + item.source : ''}</div>
</div>`;
fragment.appendChild(div);
});
list.replaceChildren(fragment);
const unreadCount = notifData.filter(x => !read[x.id]).length;
badge.style.display = unreadCount ? 'inline-flex' : 'none';
badge.textContent = unreadCount || '';
}
// Render Komentar Feed Blogger
async function renderComments() {
list.innerHTML = '<div style="padding:20px;text-align:center;color:#94a3b8;font-size:13px;">Memuat komentar terbaru...</div>';
try {
const res = await fetch('/feeds/comments/default?alt=json&max-results=10&orderby=published');
if (!res.ok) throw new Error('Network error');
const data = await res.json();
const entries = data.feed.entry || [];
if (!entries.length) {
list.innerHTML = '<div style="padding:20px;text-align:center;color:#94a3b8;font-size:13px;">Belum ada komentar</div>';
return;
}
const fragment = document.createDocumentFragment();
entries.forEach(k => {
const name = k.author?.[0]?.name?.$t || 'Anonim';
const ava = (k.author?.[0]?.gd$image?.src || '').replace('=s32', '=s80') || DEFAULT_AVATAR;
const link = k.link?.find(l => l.rel === 'alternate')?.href || '#';
const text = (k.content?.$t || '').replace(/<[^>]+>/g, '').slice(0, 90) + '…';
const div = document.createElement('div');
div.className = 'wk-m-item';
div.onclick = () => window.open(link, '_blank', 'noopener');
div.innerHTML = `
<img class="wk-m-avatar" src="${ava}" alt="${name}" loading="lazy" width="44" height="44" />
<div class="wk-m-body">
<b>${name}</b>
<div>${text}</div>
<div class="wk-m-meta">${timeAgo(new Date(k.published.$t).getTime())}</div>
</div>`;
fragment.appendChild(div);
});
list.replaceChildren(fragment);
} catch (err) {
list.innerHTML = `<div style="padding:20px;text-align:center;color:#ef4444;font-size:13px;">Tidak dapat memuat komentar.</div>`;
}
}
// Tab Navigation Handler
document.querySelectorAll('.wk-tab').forEach(tab => {
tab.onclick = () => {
document.querySelectorAll('.wk-tab').forEach(x => x.classList.remove('active'));
tab.classList.add('active');
if (tab.dataset.tab === 'notif') renderNotif();
else renderComments();
};
});
filter.onchange = renderNotif;
mark.onclick = () => {
notifData.forEach(x => read[x.id] = true);
localStorage.setItem('wk_read', JSON.stringify(read));
renderNotif();
};
// Jalankan render awal
renderNotif();
})();
</script>
<!-- =============== END WIDGET =============== -->
Cara Memasang di Postingan Blogger (Blogspot)
Buka dashboard Blogger $\rightarrow$ Postingan $\rightarrow$ Buat Postingan Baru (atau edit postingan yang ada).
Di pojok kiri atas editor, ubah mode dari Tampilan Menulis (Compose) ke Tampilan HTML (
< / >).Copy seluruh kode di atas dan paste di tempat yang Anda inginkan (misalnya di paling bawah artikel).
Klik Publikasikan / Perbarui.
