Translate

How to Create a Dynamic Sitemap Using JavaScript for Blogger

How to Create a Dynamic Sitemap Using JavaScript for Blogger

In this tutorial, you’ll learn how to create a dynamic HTML sitemap for your Blogger website. This sitemap automatically fetches your latest posts using the Blogger JSON feed and neatly organizes them by category/label.

✅ Features

  • Automatically fetches up to 500 posts from your blog
  • Groups posts by label (category)
  • Accordion-style layout for easy browsing
  • Built-in search bar for quick post filtering
  • Clean, responsive design that’s easy to customize

The best part? It’s powered entirely by JavaScript — no plugins or manual updates required. This dynamic sitemap is perfect for Blogger users who want a searchable and organized content list that helps visitors find posts faster.

To use this on your blog, just copy the code below and paste it into a new Page in your Blogger dashboard (use the HTML view). Replace the highlighted parts in red with your own site details.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Sitemap - <span style="color:red;">Your Title</span></title>
  <style>
    body {
      font-family: Arial, sans-serif;
      padding: 20px;
      max-width: 1000px;
      margin: auto;
      background: #f4f4f4;
    }
    h1 { text-align: center; color: #222; }
    input[type="text"] {
      width: 100%;
      padding: 10px;
      margin: 20px 0;
      font-size: 16px;
      border: 1px solid #ccc;
      border-radius: 6px;
    }
    .accordion {
      background-color: #0073e6;
      color: white;
      cursor: pointer;
      padding: 14px 20px;
      width: 100%;
      text-align: left;
      font-size: 18px;
      border: none;
      border-radius: 6px;
      margin-top: 10px;
    }
    .accordion.active, .accordion:hover {
      background-color: #005bb5;
    }
    .panel {
      padding: 0 20px;
      background-color: white;
      max-height: 0;
      overflow: hidden;
      transition: max-height 0.3s ease-out;
      border: 1px solid #ddd;
      border-top: none;
      border-radius: 0 0 6px 6px;
    }
    ul { list-style: none; padding: 10px 0; margin: 0; }
    li { padding: 6px 0; border-bottom: 1px dashed #ccc; }
    a { color: #333; text-decoration: none; }
    a:hover { color: #0073e6; }
    small { color: #888; font-size: 13px; }
  </style>
</head>
<body>
  <h1><span style="color:red;">Your Site Sitemap (By Category)</span></h1>
  <input type="text" id="search" placeholder="Search post titles...">
  <div id="sitemap">Loading posts...</div>

  <script>
    const blogURL = '<span style="color:red;">https://yoursite.blogspot.com</span>';
    const maxPosts = 500;

    fetch(`${blogURL}/feeds/posts/default?alt=json&max-results=${maxPosts}`)
      .then(res => res.json())
      .then(data => {
        const entries = data.feed.entry || [];
        const postsByLabel = {};

        entries.forEach(post => {
          const title = post.title.$t;
          const link = post.link.find(l => l.rel === 'alternate').href;
          const date = new Date(post.published.$t).toLocaleDateString('en-US', {
            year: 'numeric', month: 'long', day: 'numeric'
          });
          const labels = post.category ? post.category.map(c => c.term) : ['Unlabeled'];

          labels.forEach(label => {
            if (!postsByLabel[label]) postsByLabel[label] = [];
            postsByLabel[label].push({ title, link, date });
          });
        });

        let output = '';
        const sortedLabels = Object.keys(postsByLabel).sort();

        sortedLabels.forEach(label => {
          output += `
            <button class="accordion">${label}</button>
            <div class="panel"><ul>
              ${postsByLabel[label].map(post => `
                <li><a href="${post.link}" target="_blank">${post.title}</a>
                <small>(${post.date})</small></li>
              `).join('')}
            </ul></div>
          `;
        });

        document.getElementById('sitemap').innerHTML = output;

        // Accordion
        const acc = document.getElementsByClassName("accordion");
        for (let i = 0; i < acc.length; i++) {
          acc[i].addEventListener("click", function () {
            this.classList.toggle("active");
            const panel = this.nextElementSibling;
            panel.style.maxHeight = panel.style.maxHeight ? null : panel.scrollHeight + "px";
          });
        }

        // Search Filter
        document.getElementById('search').addEventListener('input', function () {
          const query = this.value.toLowerCase();
          const items = document.querySelectorAll('.panel ul li');
          items.forEach(li => {
            const text = li.textContent.toLowerCase();
            li.style.display = text.includes(query) ? '' : 'none';
          });
        });
      })
      .catch(err => {
        console.error(err);
        document.getElementById('sitemap').innerHTML = 'Failed to load sitemap.';
      });
  </script>
</body>
</html>
  

Post a Comment

Previous Post Next Post