Cara Membuat Daftar Isi Otomatis Untuk Semua Artikel Berdasarkan Label di Blogger

Cara Membuat Daftar Isi (TOC) Otomatis di Blogger yang Selalu Update & Menampilkan Semua Postingan

Halo sahabat blogger! Pada artikel ini saya ingin berbagi tutorial **cara membuat daftar isi (TOC) otomatis di Blogger** yang secara otomatis menampilkan **semua postingan** blog Anda, lengkap dengan jumlah artikel, pengelompokan per bulan, fitur sembunyikan/tampilkan daftar per bulan, dan animasi hover pada link.  
Tutorial ini cocok untuk Anda yang punya banyak artikel (bahkan ratusan!) dan ingin TOC selalu update tanpa perlu edit manual setiap kali ada postingan baru.

Fitur Daftar Isi Otomatis Ini

- **Selalu update otomatis**: TOC akan selalu menampilkan semua postingan, tanpa perlu edit manual.
- **Menampilkan jumlah artikel** di bagian atas.
- **Semua post** akan tampil, bukan cuma sebagian, meski blog Anda punya ratusan post.
- **Dikelompokkan per bulan & tahun**, ada tombol hide/tampilkan daftar per bulan.
- **Nomor urut bulat** di samping judul artikel (tidak pakai bullet/titik).
- **Animasi saat hover link** (keren!).
- **Desain elegan**, responsif, dan bisa dipasang di halaman statis Blogger.

Cara Pasang Daftar Isi Otomatis di Blogger

1. **Buka Blogger > Laman > Laman Baru**  
   Pilih mode HTML.

2. **Copy seluruh kode script di bawah ini** lalu tempelkan ke laman tersebut.

3. **Simpan dan publikasikan**.  
   Selesai! Daftar isi otomatis sudah jadi dan selalu update setiap ada postingan baru.

Kode Script Daftar Isi Blogger Otomatis

<!DOCTYPE html>
<html lang="id">
<head>
  <meta charset="UTF-8">
  <title>Daftar Isi Blog Otomatis</title>
  <style>
    body { font-family: Arial, sans-serif; background: #f8f8f8; }
    .toc-container { background: #fff; max-width: 720px; margin: 32px auto; padding: 28px 32px 24px 32px; border-radius: 14px; box-shadow: 0 2px 16px rgba(0,0,0,0.09); }
    .toc-title { font-size: 1.6em; margin-bottom: 8px; font-weight: bold; }
    .toc-count { font-weight: bold; margin-bottom: 20px; color: #2274a5; }
    .toc-month { margin-top: 22px; }
    .toc-month-title { font-size: 1.1em; font-weight: 600; cursor: pointer; user-select: none; background: #ececec; padding: 9px 13px; border-radius: 7px; display: flex; align-items: center; justify-content: space-between; transition: background 0.18s; }
    .toc-month-title:hover { background: #d0ebff; }
    .btn-toggle {
      background: none; border: none; color: #2274a5; font-weight: bold; margin-left: 10px; cursor: pointer;
      font-size: 0.98em; outline: none; transition: color 0.18s;
    }
    .btn-toggle:hover { color: #23d160; }
    .toc-list { margin: 12px 0 18px 8px; padding-left: 0; }
    .toc-list li {
      list-style: none;
      display: flex; align-items: center;
      margin-bottom: 6px;
      font-size: 1em;
      position: relative;
    }
    .toc-list li .toc-num {
      background: #2274a5;
      color: #fff;
      border-radius: 50%;
      width: 26px; height: 26px;
      display: flex; align-items: center; justify-content: center;
      font-size: 0.98em;
      margin-right: 13px;
      font-weight: bold;
      box-shadow: 0 1px 4px rgba(34,116,165,0.09);
      flex-shrink: 0;
    }
    .toc-link {
      text-decoration: none; color: #2274a5; font-weight: 500; position: relative;
      transition: color 0.18s;
      outline: none;
      padding: 2px 2px;
      border-radius: 4px;
      display: inline-block;
      z-index: 1;
    }
    .toc-link:before {
      content: '';
      position: absolute;
      left: 0; bottom: 0;
      width: 100%; height: 100%;
      background: linear-gradient(90deg, #2274a5 50%, #23d160 100%);
      border-radius: 4px;
      z-index: -1;
      opacity: 0.1;
      transform: scaleX(0) scaleY(1);
      transition: transform 0.35s cubic-bezier(.4,1.4,.7,1.01), opacity 0.18s;
    }
    .toc-link:hover, .toc-link:focus {
      color: #23d160;
    }
    .toc-link:hover:before, .toc-link:focus:before {
      transform: scaleX(1) scaleY(1.15);
      opacity: 0.25;
    }
    .hide { display: none; }
    @media (max-width: 600px) {
      .toc-container { padding: 12px 2vw; }
    }
  </style>
</head>
<body>
<div class="toc-container">
  <div class="toc-title">Daftar Isi Blog</div>
  <div class="toc-count">Jumlah Artikel: <span id="total-count">...</span></div>
  <div id="toc-content">Memuat daftar isi...</div>
</div>
<script>
const FEED_BASE = "https://alkandiri.blogspot.com/feeds/posts/default?alt=json";
const MAX_PER_PAGE = 150;
let allPosts = [];

function fetchAllPosts(start=1) {
  return fetch(`${FEED_BASE}&start-index=${start}&max-results=${MAX_PER_PAGE}`)
    .then(r=>r.json())
    .then(data => {
      const entries = data.feed.entry || [];
      let posts = entries.map(e => ({
        title: e.title.$t,
        url: e.link.find(l=>l.rel==="alternate").href,
        date: new Date(e.published.$t)
      }));
      allPosts = allPosts.concat(posts);
      // Cek apakah jumlah post yang diambil sudah sama dengan totalResults
      let total = data.feed.openSearch$totalResults.$t;
      if (allPosts.length < total) {
        // Ambil halaman berikutnya
        return fetchAllPosts(allPosts.length+1);
      } else {
        return allPosts;
      }
    });
}

function renderTOC(posts) {
  // Urutkan terbaru ke terlama
  posts.sort((a,b)=>b.date-a.date);
  // Kelompokkan per bulan dan tahun
  let group = {};
  posts.forEach(p => {
    let y = p.date.getFullYear();
    let m = p.date.toLocaleString('id-ID', {month:'long'});
    let key = `${m} ${y}`;
    if (!group[key]) group[key] = [];
    group[key].push(p);
  });
  // Buat HTML TOC
  let html = '';
  let globalNum = 1;
  Object.keys(group).sort((a,b)=>{
    // urutkan descending (terbaru dulu)
    let [ma,ya] = a.split(" "); let [mb,yb] = b.split(" ");
    return yb-ya || new Date('1 '+mb+' 2000')-new Date('1 '+ma+' 2000');
  }).forEach(month => {
    html += `<div class="toc-month">`;
    html += `<div class="toc-month-title">${month} <button class="btn-toggle" onclick="toggleMonth(this)">Sembunyikan</button></div>`;
    html += `<ul class="toc-list">`;
    group[month].forEach((p,i)=>{
      html += `<li><span class="toc-num">${globalNum++}</span><a class="toc-link" href="${p.url}" target="_blank" rel="noopener">${p.title}</a></li>`;
    });
    html += `</ul></div>`;
  });
  document.getElementById('toc-content').innerHTML = html;
  document.getElementById('total-count').textContent = posts.length;
}

function toggleMonth(btn) {
  var ul = btn.parentElement.nextElementSibling;
  if (ul.classList.contains('hide')) {
    ul.classList.remove('hide');
    btn.textContent = 'Sembunyikan';
  } else {
    ul.classList.add('hide');
    btn.textContent = 'Tampilkan';
  }
}

fetchAllPosts().then(renderTOC).catch(()=>{
  document.getElementById('toc-content').innerHTML = "<em>Gagal memuat daftar isi.</em>";
  document.getElementById('total-count').textContent = "-";
});
</script>
</body>
</html>

FAQ

**Q:** Apakah TOC ini bisa untuk semua blog Blogger?  
**A:** Ya, Anda hanya perlu mengganti bagian `FEED_BASE` dengan alamat feed JSON blog Anda jika memakai domain custom.

**Q:** Apakah TOC ini akan update otomatis saat ada post baru?  
**A:** Ya, TOC akan selalu update otomatis. Tidak perlu edit manual.

**Q:** Kenapa kode ini lebih unggul dari TOC Blogger biasa?  
**A:** Kode ini mengambil **semua postingan** per batch (bukan cuma 150 post), tampil per bulan, bisa di-hide, dan desainnya menarik.

Penutup

Itulah cara membuat daftar isi otomatis di Blogger yang benar-benar menampilkan semua postingan dan selalu update.  
Jika tutorial ini bermanfaat, silakan bagikan ke teman-teman blogger lain.  
Semoga blog Anda makin rapi, mudah dinavigasi, dan pengunjung makin betah!


Next Post Previous Post
No Comment
Add Comment
comment url