• KodeRian
    KodeRian — A place to share tips, tricks, SEO insights, coding guides, and Blogger tutorials covering HTML, CSS, JavaScript, and AdSense.

    How to Add Order Notification Messages in Blogger (Copy-Paste CSS & JS)

    Add live order notifications to Blogger with copy-paste HTML, CSS, and JS. Rotate purchases, style easily, and boost trust with ethical, lightweight.
    How to Add Order Notification Messages in Blogger (Copy-Paste CSS & JS)

    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-motion and 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 => ({ "<":"&lt;",">":"&gt;","&":"&amp;","\"":"&quot;" }[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-radius for sharper or softer cards.
    • Position: Prefer bottom-right? Swap left with right and mirror the margin in the .active rule.
    • Motion: Tune SHOW_MS and INTERVAL timings 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:

    1. Static JSON file: Host orders.json on your domain or a CDN. Fetch it on page load, then render. Cache with localStorage for 5–10 minutes.
    2. Google Sheets as JSON: Publish a sheet and read it via JSON. Sanitize on the server if you can.
    3. 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 image URLs 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 reduce SHOW_MS to tighten the footprint.
    • Overlapping with chat widgets: Move notifications to bottom-right by flipping left to right and 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).

    2 comments

    Comment Guidelines

    Please keep your comments relevant to the topic (Blogger, SEO, coding, etc.).

    Be respectful — no spam, offensive language, or personal attacks.

    You may share suggestions, bug reports, or tutorial requests.

    External links are allowed only if they are truly helpful and not for promotion.

    Feedback will be reviewed, and I will try to reply as soon as possible.

    By commenting here, you help improve KodeRian and keep the discussion useful for everyone.
    1. kalau gambarnya biar otomatis sama semua gimana gan

      ReplyDelete
      Replies
      1. kalau otomatis harus pakai host, nanti kita bisa ambil dari host data gambarnya jadi bisa otomatis. paling nanti saya akan buat versi otomatis nya

        Delete