Mighil

script to sort posts by month on bear blog

Use this script if you want to display all your blog posts grouped by month.

Step 1: Create a new page

  1. Go to your Bear Blog dashboard
  2. Navigate to PagesNew Page
  3. Set the page slug to something like archive or blog (if blog is not your reserved blog path on bear)

Step 2: Add the post embed code

In the editor, add the post embed code:

<h2 class="archive">Loading posts...</h2>
 {{posts}}

Why the placeholder header? The <h2 class="archive"> placeholder prevents layout shift (CLS) when the JavaScript runs.

Step 3: Add the JavaScript

You have two options:

Option 1: Inline minified script (easiest)

Add the JavaScript directly:

<h2 class="archive">Loading posts...</h2>
{{posts}}
<script>
(function(){'use strict';function groupPostsByMonth(){const postsList=document.querySelector('ul.embedded.blog-posts');if(!postsList)return;const listItems=Array.from(postsList.querySelectorAll('li'));if(listItems.length===0)return;const totalPosts=listItems.length;let lastUpdatedDate=null;let lastUpdatedDateString=null;const groupedPosts={};listItems.forEach(li=>{const timeElement=li.querySelector('time[datetime]');if(!timeElement)return;const dateString=timeElement.getAttribute('datetime');if(!dateString)return;const date=new Date(dateString);if(isNaN(date.getTime()))return;if(!lastUpdatedDate||date>lastUpdatedDate){lastUpdatedDate=date;lastUpdatedDateString=dateString}
const monthYear=date.toLocaleDateString('en-US',{month:'long',year:'numeric'});if(!groupedPosts[monthYear]){groupedPosts[monthYear]=[]}
groupedPosts[monthYear].push(li)});const monthDates={};Object.keys(groupedPosts).forEach(monthYear=>{const firstPost=groupedPosts[monthYear][0];const timeElement=firstPost.querySelector('time[datetime]');if(timeElement){const dateString=timeElement.getAttribute('datetime');const date=new Date(dateString);monthDates[monthYear]=date}});const sortedMonths=Object.keys(groupedPosts).sort((a,b)=>{const dateA=monthDates[a]||new Date(0);const dateB=monthDates[b]||new Date(0);return dateB-dateA});if(lastUpdatedDate&&lastUpdatedDateString){let header=postsList.parentNode.querySelector('h2.archive');if(!header){header=document.createElement('h2');header.className='archive';postsList.parentNode.insertBefore(header,postsList)}
const formattedDate=lastUpdatedDate.toLocaleDateString('en-US',{month:'long',day:'numeric',year:'numeric'});const span=document.createElement('span');span.id='last-updated';span.setAttribute('data-date',lastUpdatedDateString);span.textContent=formattedDate;header.textContent=`${totalPosts} entries. Last updated on `;header.appendChild(span);header.appendChild(document.createTextNode('.'))}
postsList.innerHTML='';sortedMonths.forEach(monthYear=>{const monthHeader=document.createElement('h3');monthHeader.className='archive-h3';monthHeader.textContent=monthYear;postsList.parentNode.insertBefore(monthHeader,postsList);const monthList=document.createElement('ul');monthList.className='blog-posts';groupedPosts[monthYear].forEach(li=>{monthList.appendChild(li)});postsList.parentNode.insertBefore(monthList,postsList)});if(postsList.parentNode&&postsList.children.length===0){postsList.remove()}}
if(document.readyState==='loading'){document.addEventListener('DOMContentLoaded',groupPostsByMonth)}else{groupPostsByMonth()}})()
</script>

Option 2: External script (better for reusability)

If you want to host the script elsewhere and load it:

  1. Upload the sort-posts-by-month.js to a CDN or your own hosting
  2. Replace the inline script with:
<h2 class="archive">Loading posts...</h2>
 {{posts}}
<script src="https://your-domain.com/path/to/archive-sort.js"></script>

How it works

  1. Initial Load: Bear Blog renders all your posts using the {{posts}} embed code
  2. JavaScript Execution: When the page loads, the script:
    • Finds all post list items
    • Groups them by month and year
    • Finds the most recent post date
    • Creates a header showing total count and last updated date
    • Reorganizes posts under month headers (newest months first)
    • Removes the original flat list

The result

Your archive page will display like this:

{n} entries. Last updated on {lastUpdatedDate}.

November, 2025
- Post title 1
- Post title 2

October, 2025
- Post title 3
...

Customization

You can customize the styling by targeting .archive:

.archive {
    margin-bottom: 2rem;
}

.archive-h3 {
    margin-top: 2rem;
    margin-bottom: 1rem;
}

.blog-posts {
    list-style: none;
    padding-left: 0;
}

Tagged in bear blog, tech