Sales happen quietly, but your page doesn’t have to. A small, tasteful order notification—the little toast that slides up saying “Raisa from Bandung just purchased Template X”—can boost perceived activity, reduce hesitation, and nudge visitors toward checkout. In this expanded tutorial you’ll build a Notification Order Messages component for Blogger using clean HTML, modern CSS, and lightweight JavaScript.
We’ll keep it copy-paste friendly, but still professional: accessible markup, smooth motion with respect for people who prefer reduced motion, mobile-first styles, dark-mode aware colors, and a simple data model you can swap later for any real data source (Google Sheets, Firebase, your cart). If you’ve ever customized a theme—maybe even tried a custom scrollbar tutorial or tweaked a Blogger CSS scrollbar—this will feel familiar and fast.
What Are Order Notifications (and When to Use Them)?
Order notifications are small, timed messages that appear on your page to highlight recent activity: someone purchased a product, joined a plan, or downloaded a file. Done well, they:
- Build social proof: Visitors see others taking action and feel safer to do the same.
- Reduce decision friction: That little nudge can move a “maybe later” into “add to cart.”
- Bring motion to quiet pages: Especially on landing pages or product posts with fewer elements.
Use them sparingly and ethically. Never fabricate orders. If you are still testing with sample data (as this guide uses), clearly mark or limit where it appears until you connect a real data source.
What You’ll Build
We’ll create a notification component that:
- Renders a rotating queue of purchase messages in the bottom-left corner.
- Shows an avatar, customer name, city, product, a link, and relative time (“3 minutes ago”).
- Auto-shows for a few seconds, hides, then rotates to the next entry.
- Lets users close a single message (or you can wire to “close all”).
- Respects
prefers-reduced-motionand dark mode classes (e.g.,.nightmode).
We’ll start with static sample data (dataOrder array) so you can see it working immediately. Later sections show how to plug in real data and guard against abuse.
Step-by-Step: Add Order Notifications to Blogger
1) Add the HTML placeholder
Place the container near the end of your template, ideally right after </head> or before </body> so it’s available when scripts run:
<!-- Live Sales / Order Notifications -->
<div class="livesales" aria-live="polite" aria-atomic="true"></div>
2) Paste the CSS (above </b:skin> or inside your theme’s stylesheet)
This is mobile-first, with subtle shadow, dark-mode awareness, and reduced-motion support. Feel free to adjust colors to match your brand.
/* === Live Sales Notification (Blogger) === */
.livesales{font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen,Ubuntu,Cantarell,"Open Sans","Helvetica Neue",sans-serif;font-weight:400;line-height:1.6}
.livesales .item{
position:fixed;bottom:0;left:0;display:flex;align-items:flex-start;
overflow:hidden;z-index:200;max-width:320px;font-size:15px;
background:rgba(255,255,255,.98);padding:14px 16px;border-radius:10px;
box-shadow:0 10px 30px rgba(0,0,0,.12);color:#1f2937;
transition:transform .4s ease,opacity .4s ease,visibility .4s ease;
transform:translate3d(-10px,10px,0);opacity:0;visibility:hidden
}
.livesales .item.active{left:20px;bottom:20px;transform:translate3d(0,0,0);opacity:1;visibility:visible}
.livesales .image{display:flex;margin-right:12px}
.livesales .img{
width:56px;height:56px;border-radius:999px;flex:none;
background:#e5e7eb url(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjhiFWUMvOQKZPicY7jaEoIySbBeScvTv5NU0jwZT8n7SHdOdhn-YhKUnv5vYQRe3InohBi9ag-pTXYNXGeuxisKGcWvYaPIr310t6sgY0MdeVBauCygaPWJPb_8JMVdRI-PUZRhZBASB4/h60/ava.png) center/cover no-repeat;
box-shadow:0 0 0 3px rgba(0,0,0,.04)
}
.livesales .content{position:relative;min-width:0}
.livesales .close{
appearance:none;border:0;background:transparent;cursor:pointer;
position:absolute;top:-8px;right:-8px;width:28px;height:28px;border-radius:999px;
display:grid;place-items:center;color:#6b7280;transition:background .2s ease
}
.livesales .close:hover{background:rgba(17,24,39,.06)}
.livesales .close:before{content:"×";font-size:18px;line-height:1}
.livesales .info b{color:#111827}
.livesales .info a{color:#10b981;text-decoration:none}
.livesales .info a:hover{text-decoration:underline}
.livesales small{
display:block;margin-top:6px;padding-top:6px;border-top:1px solid rgba(0,0,0,.06);
font-size:12px;color:#6b7280
}
/* Dark mode (attach to your theme's class) */
.nightmode .livesales .item{background:#111827;color:#e5e7eb;box-shadow:0 14px 28px rgba(0,0,0,.35)}
.nightmode .livesales .info b{color:#f9fafb}
.nightmode .livesales .info a{color:#34d399}
.nightmode .livesales small{border-top:1px solid rgba(255,255,255,.08);color:#9ca3af}
/* Respect reduced motion */
@media (prefers-reduced-motion: reduce){
.livesales .item{transition:none}
}
/* Small screens: keep the toast readable */
@media (max-width:480px){
.livesales .item{max-width:calc(100% - 24px)}
}
3) Add the JavaScript (before </body>)
The script below renders your data, rotates notifications (show → hide → move to end), supports pause-on-hover, handles the close button, and guards against missing containers. It uses plain JavaScript—no dependencies.
<script>/*<![CDATA[*/
(function(){
"use strict";
// 1) Sample data (replace with real records later)
const dataOrder = {
data: [
{
nama: "Andi Pratama",
image: "https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjhiFWUMvOQKZPicY7jaEoIySbBeScvTv5NU0jwZT8n7SHdOdhn-YhKUnv5vYQRe3InohBi9ag-pTXYNXGeuxisKGcWvYaPIr310t6sgY0MdeVBauCygaPWJPb_8JMVdRI-PUZRhZBASB4/h60/ava.png",
kota: "Bandung",
tanggal: "3 minutes ago",
produk: "Flet Banget — Responsive Blogger Theme",
url: "https://www.malestea.com/2021/02/flet-banget-responsive-blogger-theme.html"
},
{
nama: "Raisa K.",
image: "",
kota: "Surabaya",
tanggal: "12 minutes ago",
produk: "KodeRian Pro Template",
url: "#"
},
{
nama: "Bimo",
image: "",
kota: "Jakarta",
tanggal: "1 hour ago",
produk: "Minimal Blog Theme",
url: "#"
}
// Add more objects as needed
]
};
// 2) Utilities
const $ = (sel, root=document) => root.querySelector(sel);
const $$ = (sel, root=document) => Array.prototype.slice.call(root.querySelectorAll(sel));
function createItem(order){
const wrap = document.createElement("div");
wrap.className = "item";
const imgURL = order.image || "https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjhiFWUMvOQKZPicY7jaEoIySbBeScvTv5NU0jwZT8n7SHdOdhn-YhKUnv5vYQRe3InohBi9ag-pTXYNXGeuxisKGcWvYaPIr310t6sgY0MdeVBauCygaPWJPb_8JMVdRI-PUZRhZBASB4/h60/ava.png";
wrap.innerHTML =
'<div class="image"><span class="img" style="background-image:url(\''+ imgURL +'\')"></span></div>'+
'<div class="content">'+
'<button class="close" aria-label="Close notification"></button>'+
'<span class="info"><b>'+ escapeHTML(order.nama) +'</b> from <b>'+ escapeHTML(order.kota) +
'</b> purchased <a href="'+ (order.url||"#") +'" target="_blank" rel="noopener">'+ escapeHTML(order.produk) +'</a>'+
'<small>'+ escapeHTML(order.tanggal) +'</small></span>'+
'</div>';
return wrap;
}
function escapeHTML(str){
return String(str||"").replace(/[<&>"]/g, s => ({ "<":"<",">":">","&":"&","\"":""" }[s]));
}
// 3) Mount
const host = $(".livesales");
if(!host){ return; } // guard in case HTML wasn't added
// Render all items
dataOrder.data.forEach(d => host.appendChild(createItem(d)));
// Close button handler (event delegation)
host.addEventListener("click", function(e){
const btn = e.target.closest(".close");
if(!btn) return;
const item = btn.closest(".item");
if(!item) return;
item.classList.remove("active");
// If you prefer to remove permanently, uncomment:
// item.remove();
});
// Pause rotation on hover (for accessibility)
let paused = false;
host.addEventListener("mouseenter", () => paused = true);
host.addEventListener("mouseleave", () => paused = false);
// 4) Rotation loop
const SHOW_MS = 4000; // show for 4s
const INTERVAL = 10000; // every 10s, reveal next
function rotate(){
if(paused) return; // do nothing while hovered
const first = host.querySelector(".item");
if(!first) return;
first.classList.add("active");
setTimeout(() => {
first.classList.remove("active");
// Move to end of list for next cycle
host.appendChild(first);
}, SHOW_MS);
}
// Kick off
// Ensure only the first item is active initially
$$(".livesales > .item.active").forEach(el => el.classList.remove("active"));
// Start after a short delay to avoid flashing during page paint
setTimeout(rotate, 1200);
setInterval(rotate, INTERVAL);
})();
/*]]>*/</script>
Customize the Look & Feel
Styling is half the charm. Tweak the following to make the toast match your brand:
- Colors: Change link color (
.livesales .info a) and background of the toast (.livesales .item). - Corner radius: Adjust
border-radiusfor sharper or softer cards. - Position: Prefer bottom-right? Swap
leftwithrightand mirror the margin in the.activerule. - Motion: Tune
SHOW_MSandINTERVALtimings to your page rhythm. - Dark mode: If your template uses
.nightmode(or a similar class), you already have styling hooks in the CSS block. - Scrollbar polish: If you’re styling long lists or off-canvas carts, consider a customize scrollbar Blogger snippet to keep UI consistent with your brand.
Adding Your Own Data
Today we used a static array. Tomorrow you’ll likely want real events. Here are safe, simple ways to feed the widget:
- Static JSON file: Host
orders.jsonon your domain or a CDN. Fetch it on page load, then render. Cache withlocalStoragefor 5–10 minutes. - Google Sheets as JSON: Publish a sheet and read it via JSON. Sanitize on the server if you can.
- Firebase: Realtime Database/Firestore can push updates instantly. Add basic read rules and sanitize fields (name, city, product, time).
Simple fetch example (replace the array usage):
<script>
/* Pseudo-example: replace the local data with a fetch */
fetch("/path/to/orders.json")
.then(r => r.json())
.then(json => { /* render json.data using createItem(...) */ })
.catch(() => {/* fallback to a small hardcoded list */});
</script>
Accessibility & UX Considerations
- ARIA live region: The container uses
aria-live="polite", letting screen readers announce updates without interrupting reading. - Pause on hover: Gives visitors control; they can read at their own pace.
- Reduced motion: We disable complex transitions when users set “reduce motion” at OS level.
- Dismissal: The close button is keyboard accessible and visually clear.
Ethical Use (Important)
Order notifications are persuasive. Use them honestly:
- Don’t fake demand: If you must test with sample entries, keep them on staging or label them clearly.
- Respect privacy: Use first names/initials or anonymize by default. Avoid exposing full personal data.
- Local laws: If your region has privacy regulations, disclose your use of on-page activity messages.
Troubleshooting
- Nothing appears: Ensure the
<div class="livesales">exists before the script runs. Place the HTML container high enough in the template. - Console error “host is null”: The script couldn’t find the container. Double-check the class name and placement.
- Images not showing: Your
imageURLs may be blocked or invalid. Test them directly in a new tab; if empty, the script falls back to a default avatar. - Too many animations: Increase
INTERVAL(e.g., 15–20s) or reduceSHOW_MSto tighten the footprint. - Overlapping with chat widgets: Move notifications to bottom-right by flipping
lefttorightand adjusting the margin in CSS.
FAQ
1) Will this slow down my page?
The CSS+JS footprint is tiny and dependency-free. If you fetch data, cache it (localStorage or HTTP cache) and keep records short. Minify when you’re done.
2) Can I randomize entries?
Yes. Shuffle the array once before rendering, or pick a random starting index so visitors don’t always see the same name first.
3) How do I prevent repeat messages quickly?
Mark a message as “just shown” and push it to the end of the queue. The included rotation already cycles items while spacing appearances with INTERVAL.
4) Can I wire this to real orders?
Absolutely. Many stores expose a webhook on “order.created.” Pipe that to a small server that writes a cleaned JSON list your Blogger site can fetch. If you use Google Forms/Sheets for orders, publish a read-only JSON and sanitize content.
5) Does this help SEO?
Indirectly. The widget won’t change rankings, but it can improve engagement and conversions—signals that often correlate with stronger performance. Keep your page fast and accessible.
6) Can I style the scrollbar of a long notification list?
Yes—if you convert to a stacked panel or history drawer. Use a Blogger CSS scrollbar snippet to customize scrollbar Blogger while keeping contrast and size accessible.
Copy-Paste Reference
HTML
<div class="livesales" aria-live="polite" aria-atomic="true"></div>
CSS
.livesales .item{position:fixed;bottom:0;left:0;display:flex;align-items:flex-start;z-index:200;max-width:320px;font-size:15px;background:rgba(255,255,255,.98);padding:14px 16px;border-radius:10px;box-shadow:0 10px 30px rgba(0,0,0,.12);color:#1f2937;transition:transform .4s ease,opacity .4s ease,visibility .4s ease;transform:translate3d(-10px,10px,0);opacity:0;visibility:hidden}
.livesales .item.active{left:20px;bottom:20px;transform:translate3d(0,0,0);opacity:1;visibility:visible}
.livesales .img{width:56px;height:56px;border-radius:999px;background:#e5e7eb url(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjhiFWUMvOQKZPicY7jaEoIySbBeScvTv5NU0jwZT8n7SHdOdhn-YhKUnv5vYQRe3InohBi9ag-pTXYNXGeuxisKGcWvYaPIr310t6sgY0MdeVBauCygaPWJPb_8JMVdRI-PUZRhZBASB4/h60/ava.png) center/cover no-repeat}
.livesales .close{appearance:none;border:0;background:transparent;cursor:pointer;position:absolute;top:-8px;right:-8px;width:28px;height:28px;border-radius:999px;display:grid;place-items:center;color:#6b7280}
JavaScript (Rotation)
(function(){
const host = document.querySelector(".livesales");
if(!host) return;
// ...build items and rotation loop (see full script above)...
})();
Conclusion
Small element, big lift. With a few lines of CSS and JS, your Blogger store or landing page gets a living pulse: recent purchases appearing gently at the corner of the screen. Start with the static list to validate the look and timing. Then, when you’re ready, connect a real data source—Google Sheets, Firebase, or a tiny JSON feed. Keep it honest, fast, and accessible, and you’ll have a modern conversion pattern that respects your readers.
Found this useful? Bookmark this guide, share it with a fellow creator, and subscribe for more hands-on Blogger tweaks—Dark Mode, performance wins, and clean UI patterns (including that custom scrollbar tutorial you’ve been meaning to try).



kalau gambarnya biar otomatis sama semua gimana gan
ReplyDeletekalau otomatis harus pakai host, nanti kita bisa ambil dari host data gambarnya jadi bisa otomatis. paling nanti saya akan buat versi otomatis nya
Delete