![]() |
| How to Add Related Posts in the Middle of Blogger Articles: Responsive CSS and JavaScript Tutorial |
Have you ever published a great article, only to watch visitors read one page and disappear without exploring anything else? It feels like opening a restaurant where customers eat one spoonful and immediately run back to the parking lot.
If you run a Blogger website, adding related posts inside your articles can make content discovery easier. Instead of forcing readers to return to your homepage, you can show relevant article cards directly between paragraphs.
In this tutorial, we will install an inline related posts widget using two separate steps: CSS for the design and JavaScript for automatic article selection and placement. The result is a responsive layout for desktop, tablet, and mobile devices, with support for dark mode styling.
What Is an Inline Related Posts Widget?
An inline related posts widget displays recommended articles inside the main content of a blog post. Unlike a widget placed only at the bottom of an article, this system can insert recommendations at several positions throughout longer content.
For example, a visitor reading about Blogger customization might discover another tutorial about SEO, responsive layouts, or website performance. This gives readers a convenient way to continue exploring your website.
Think of it as a friendly tour guide for your blog. It points visitors toward another useful article instead of shouting, "Hey, you forgot to visit page number seventeen!"
Features of This Blogger Related Posts System
- Responsive desktop layout: Four article cards per row.
- Tablet layout: Three visible cards per row when using the default four-card configuration.
- Mobile layout: Four cards arranged in two columns.
- Automatic article retrieval: Uses the Blogger posts feed to find recommendations.
- Duplicate protection: Avoids repeating the same article URL in the retrieved list.
- Inline placement: Inserts recommendation boxes between eligible content blocks.
- Dark mode styling: Supports system preferences and several common theme classes.
- Lazy-loaded thumbnails: Recommendation images use browser lazy loading.
These features can improve navigation and help visitors discover more content. They do not guarantee higher Google rankings, more pageviews, or AdSense approval. Those outcomes depend on the quality of your website and how readers actually use it.
Before You Start: Back Up Your Blogger Theme
Before editing the template, create a backup of your current Blogger theme. If a change causes a layout problem, you will have a clean version to restore.
Open your Blogger dashboard, select Theme, and open Edit HTML. You will install the widget in two separate locations. Follow the steps in order and do not mix the CSS with the JavaScript.
Step 1: Install the Related Posts CSS
The first step controls the appearance of the related posts widget. It defines card dimensions, spacing, thumbnail proportions, typography, hover effects, responsive columns, and light or dark color schemes.
- Open Blogger Dashboard.
- Go to Theme > Edit HTML.
- Search for the old comment
/* RELATED POSTS TENGAH ARTIKEL */. - Delete the entire old related posts CSS block.
- Replace it with the complete CSS code below.
- Place the new code immediately before
]]></b:skin>. - Save your theme.
Important: This step changes the CSS only. Do not modify the JavaScript in Step 2 while performing this replacement.
Complete CSS Code
/* RELATED POSTS TENGAH ARTIKEL */
.rp-mid{--rp-bg:#f8fafc;--rp-bd:#e2e8f0;--rp-tx:#1e293b;--rp-mt:#64748b;--rp-ac:#2563eb;--rp-ph:#e2e8f0;
margin:28px 0;padding:16px;background:var(--rp-bg);border:1px solid var(--rp-bd);border-radius:12px;clear:both;box-sizing:border-box;width:100%}
.rp-mid *{box-sizing:border-box}
.rp-mid .rp-head{margin:0 0 12px;font-size:15px;font-weight:700;color:var(--rp-tx);padding-left:10px;border-left:4px solid var(--rp-ac);line-height:1.3}
/* PC: 4 kolom */
.rp-mid .rp-grid{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:12px}
.rp-mid .rp-item{display:block;min-width:0;text-decoration:none!important;color:var(--rp-tx);border-radius:10px;overflow:hidden;background:var(--rp-bg);border:1px solid var(--rp-bd);transition:transform .2s,box-shadow .2s}
.rp-mid .rp-item:hover{transform:translateY(-3px);box-shadow:0 6px 16px rgba(0,0,0,.15)}
.rp-mid .rp-img{display:block!important;width:100%!important;height:auto!important;max-width:100%!important;aspect-ratio:16/9;object-fit:cover;margin:0!important;padding:0!important;border:0!important;background:var(--rp-ph)}
.rp-mid .rp-ttl{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;margin:0;padding:8px 10px 10px;font-size:13px;font-weight:600;line-height:1.4;color:var(--rp-tx)}
.rp-mid .rp-item:hover .rp-ttl{color:var(--rp-ac)}
/* Tablet: 3 kolom (item ke-4 disembunyikan agar rapi) */
@media (max-width:991px){
.rp-mid .rp-grid{grid-template-columns:repeat(3,minmax(0,1fr))}
.rp-mid .rp-item:nth-child(n+4){display:none}
}
/* HP: 2 kolom (4 item tampil kembali) */
@media (max-width:600px){
.rp-mid{padding:12px;margin:22px 0}
.rp-mid .rp-grid{grid-template-columns:repeat(2,minmax(0,1fr));gap:10px}
.rp-mid .rp-item:nth-child(n+4){display:block}
.rp-mid .rp-ttl{font-size:12.5px;padding:7px 8px 9px}
}
/* Dark mode otomatis (mengikuti perangkat) */
@media (prefers-color-scheme:dark){
.rp-mid{--rp-bg:#1e293b;--rp-bd:#334155;--rp-tx:#e2e8f0;--rp-mt:#94a3b8;--rp-ac:#60a5fa;--rp-ph:#334155}
}
/* Dark mode via class/atribut tema */
body.dark .rp-mid,body.dark-mode .rp-mid,body.darkmode .rp-mid,
html.dark .rp-mid,html.dark-mode .rp-mid,[data-theme="dark"] .rp-mid,[data-mode="dark"] .rp-mid{
--rp-bg:#1e293b;--rp-bd:#334155;--rp-tx:#e2e8f0;--rp-mt:#94a3b8;--rp-ac:#60a5fa;--rp-ph:#334155}
/* Paksa light jika template punya toggle light */
body.light .rp-mid,html.light .rp-mid,[data-theme="light"] .rp-mid{
--rp-bg:#f8fafc;--rp-bd:#e2e8f0;--rp-tx:#1e293b;--rp-mt:#64748b;--rp-ac:#2563eb;--rp-ph:#e2e8f0}
How the Responsive Layout Works
On desktop screens, the widget uses four columns. On tablet screens up to 991 pixels wide, the fourth card is hidden to keep a three-column layout. On mobile screens up to 600 pixels wide, the fourth card becomes visible again and the grid changes to two columns.
This produces four cards in one desktop row, three visible cards on a tablet, and four cards across two rows on a phone.
If you want six cards per box, the tablet rule must be adjusted to hide cards starting from the seventh item rather than the fourth. The JavaScript configuration must also be changed to request six cards per box.
Step 2: Install the Related Posts JavaScript
Once the CSS is installed, the second step adds the functionality that retrieves article data and inserts the related posts boxes into the article body.
- Open Blogger Dashboard > Theme > Edit HTML.
- Find the existing block beginning with
<b:if cond='data:blog.pageType == "item"'>. - Locate its matching closing
</b:if>. - Delete the entire old related posts script block.
- Replace it with the complete JavaScript code below.
- Place the replacement block immediately before
</body>. - Save the theme and test a published article.
Important: Do not change the CSS from Step 1. The JavaScript uses the CSS classes defined in that step, so both parts must be installed correctly.
Complete JavaScript Code
<b:if cond='data:blog.pageType == "item"'>
<script>
//<![CDATA[
(function(){
var CFG = {
titles: ['Read Also', 'Related Posts', 'You May Also Like'], // box titles
perBox: 4, // articles per box
posisi: [0.25, 0.5, 0.75], // positions inside the post (never top/bottom)
minParagraf: 8, // fewer content blocks than this = only 1 box in the middle
minTotal: 3 // fewer blocks than this = no box at all
};
function getLink(e){
for(var i = 0; i < e.link.length; i++){
if(e.link[i].rel === 'alternate') return e.link[i].href;
}
return '';
}
function ambil(url, here, seen, out, need){
return fetch(url).then(function(r){ return r.json(); }).then(function(d){
var entries = (d.feed && d.feed.entry) || [];
entries.forEach(function(e){
if(out.length >= need) return;
var link = getLink(e);
if(!link || link.indexOf(here) !== -1 || seen[link]) return;
seen[link] = 1;
var img = e['media$thumbnail'] ? e['media$thumbnail'].url.replace(/\/s\d+(-c)?\//, '/s400-c/') : '';
out.push({t: e.title.$t, l: link, i: img});
});
});
}
function buatKotak(judul, items){
var box = document.createElement('div');
box.className = 'rp-mid';
var h = document.createElement('p');
h.className = 'rp-head';
h.textContent = judul;
var grid = document.createElement('div');
grid.className = 'rp-grid';
items.forEach(function(p){
var a = document.createElement('a');
a.className = 'rp-item';
a.href = p.l;
var im = document.createElement('img');
im.className = 'rp-img';
im.loading = 'lazy';
im.alt = p.t;
if(p.i) im.src = p.i;
var t = document.createElement('span');
t.className = 'rp-ttl';
t.textContent = p.t;
a.appendChild(im);
a.appendChild(t);
grid.appendChild(a);
});
box.appendChild(h);
box.appendChild(grid);
return box;
}
function init(){
var body = document.querySelector('.post-body, .entry-content, .post-body-container');
if(!body || document.querySelector('.rp-mid')) return;
var need = CFG.perBox * CFG.posisi.length;
var here = location.pathname;
var seen = {}, list = [];
var lb = document.querySelectorAll('.post-labels a, a[rel="tag"]');
var label = lb.length ? lb[0].textContent.trim() : '';
var urlLabel = '/feeds/posts/default/-/' + encodeURIComponent(label) + '?alt=json&max-results=' + (need + 6);
var urlAll = '/feeds/posts/default?alt=json&max-results=' + (need + 6);
var p = label ? ambil(urlLabel, here, seen, list, need).catch(function(){}) : Promise.resolve();
p.then(function(){
if(list.length < need) return ambil(urlAll, here, seen, list, need);
}).then(function(){
if(!list.length) return;
var tags = /^(P|DIV|H2|H3|H4|UL|OL|BLOCKQUOTE)$/;
var kids = [].filter.call(body.children, function(el){
return tags.test(el.tagName) && el.textContent.trim().length > 20;
});
var n = kids.length;
if(n < CFG.minTotal) return;
var posisi = n >= CFG.minParagraf ? CFG.posisi : [0.5];
var used = {};
posisi.forEach(function(pos, idx){
var items = list.slice(idx * CFG.perBox, (idx + 1) * CFG.perBox);
if(!items.length) return;
// keep box between the first and last block (never top/bottom)
var k = Math.min(n - 2, Math.max(0, Math.round(n * pos) - 1));
if(used[k]) return;
used[k] = 1;
var box = buatKotak(CFG.titles[idx] || CFG.titles[0], items);
kids[k].parentNode.insertBefore(box, kids[k].nextSibling);
});
}).catch(function(){});
}
if(document.readyState === 'loading') document.addEventListener('DOMContentLoaded', init);
else init();
})();
//]]>
</script>
</b:if>
Understanding the JavaScript Settings
1. Box Titles
The titles array defines the heading displayed above each recommendation box. The default headings are Read Also, Related Posts, and You May Also Like. You can replace them with other short, descriptive labels.
2. Articles Per Box
The perBox: 4 setting requests four articles per box. Since the default configuration contains three positions, the script attempts to collect up to twelve unique recommendations.
Having twelve available posts does not guarantee that all twelve will be displayed. The insertion logic, available content blocks, and the number of unique articles can affect the final result.
3. Insertion Positions
The posisi: [0.25, 0.5, 0.75] setting defines approximate insertion points based on the eligible content blocks. It aims to distribute the recommendation boxes throughout longer articles rather than placing everything at the beginning or end.
These values represent approximate positions in the list of content elements, not exact percentages of the rendered page height.
4. Minimum Content Blocks
The minParagraf: 8 setting switches to a single middle box when fewer than eight eligible content blocks are found. The minTotal: 3 setting prevents insertion when fewer than three eligible blocks exist.
These counts include supported elements such as paragraphs, headings, lists, and blockquotes. They do not represent a minimum word count.
Important Technical Notes
The supplied JavaScript contains a placement check that skips a box when two configured positions resolve to the same content index. Therefore, three boxes are not guaranteed on every article, even when the article is long enough.
The script also searches for the first available post label. If that label is broad or unrelated to the article's topic, the recommendations may not be as relevant as expected.
Another consideration is the Blogger feed response. Network errors, feed access restrictions, missing thumbnail data, or differences in the theme's article container can prevent the widget from displaying correctly.
How to Test the Widget After Installation
- Open a published Blogger article with several paragraphs.
- Check that the related posts boxes appear inside the article body.
- Verify that each card opens the intended article.
- Test the layout on desktop, tablet, and mobile screens.
- Check both light and dark mode where supported.
- Inspect the browser console if the boxes do not appear.
- If necessary, clear the browser cache or test in a private window.
Do not judge the result from the theme editor alone. Always test the published page because the live template, feed responses, and actual article structure determine how the script behaves.
Can Related Posts Help SEO and AdSense?
Relevant internal links can help visitors discover additional content and can make a website easier to navigate. They may also help search engines discover linked pages, provided those links are accessible and crawlable.
However, adding related posts does not guarantee better rankings or increased advertising revenue. Results depend on the relevance of the recommendations, content quality, traffic, reader behavior, and other factors.
For AdSense, focus on original and useful articles, clear navigation, a good user experience, and compliance with applicable policies. A well-designed widget is an improvement to the site, not a replacement for valuable content.
Frequently Asked Questions
Do I need to modify both the CSS and JavaScript?
For this installation, yes. Step 1 provides the styling, while Step 2 provides the article retrieval and insertion logic. Both must be installed in their designated locations.
Will the widget show four articles on mobile?
The default CSS restores the fourth card on mobile and displays the cards in two columns. The number actually available depends on the JavaScript results and successful insertion of the box.
Can I display six articles per box?
Yes, but update the JavaScript's perBox setting and adjust the tablet CSS so cards are hidden starting from the seventh item rather than the fourth. Test the resulting layout carefully.
Why might a recommendation box be missing?
Possible causes include a missing article container, insufficient content blocks, failed feed requests, duplicate insertion positions, or a lack of eligible articles.
Conclusion
This two-step installation gives your Blogger website a responsive inline related posts widget using CSS and JavaScript. The CSS controls the appearance, while the JavaScript retrieves article data and attempts to insert recommendation boxes throughout the content.
Install each part in the correct location, preserve a theme backup, and test the live page before considering the job finished. The goal is simple: make it easier for readers to find another useful article without turning your blog into a maze.
Because the best related posts widget is not the one with the most boxes. It is the one that helps readers discover something genuinely worth reading.

Comments
Post a Comment