Custom Buy Now Buttons

Build fully custom purchase buttons for Astro, Next.js, and static sites

Quick Start

The BMOS embed script provides multiple ways to add Buy Now functionality to your site. Choose the method that fits your needs:

Method 1: Standard Embed (Recommended)

Drop in a div with data attributes and let the script handle everything:

<!-- Add this div where you want the button -->
<div class="bmos-product" 
     data-sku="YOUR-SKU" 
     data-store="YOUR-STOREFRONT-UUID" 
     data-style="button">
</div>

<!-- Include the embed script (once per page) -->
<script src="https://app.buildmyonlinestore.com/embed.js"></script>

Method 2: Custom Button with addProduct() NEW

Design your own button and trigger checkout programmatically:

<!-- Your custom-designed button -->
<button onclick="BMOSEmbed.addProduct('YOUR-SKU', 'YOUR-STOREFRONT-UUID')">
    Buy Now - $29.99
</button>

<!-- Include the embed script -->
<script src="https://app.buildmyonlinestore.com/embed.js"></script>
Tip: The embed script automatically handles Astro, Next.js, SvelteKit, and other static site generators. It retries initialization up to 10 times if elements aren't found immediately.

Instant First-Click Performance v2.1

By default, the first button click takes 3-6 seconds because it must fetch product data and load the checkout widget. Use prefetch to make first-click instant:

Method 1: Auto-Prefetch with Data Attributes

Add data-bmos-sku and data-bmos-store to your custom buttons:

<button 
    onclick="BMOSEmbed.addProduct('MM001', 'ddd7af53-...')"
    data-bmos-sku="MM001"
    data-bmos-store="ddd7af53-792d-4ed8-891b-1adfe4f94f53">
    Buy Now
</button>

<script src="https://app.buildmyonlinestore.com/embed.js"></script>

The embed script automatically detects these attributes and prefetches on page load.

Method 2: Explicit Prefetch Call

Call BMOSEmbed.prefetch() after the script loads:

<script src="https://app.buildmyonlinestore.com/embed.js"></script>
<script>
    // Prefetch product data and checkout widget on page load
    BMOSEmbed.prefetch([
        { sku: 'MM001', store: 'ddd7af53-792d-4ed8-891b-1adfe4f94f53' },
        { sku: 'MM002', store: 'ddd7af53-792d-4ed8-891b-1adfe4f94f53' }
    ]);
</script>

For Astro Sites

<!-- src/pages/product.astro -->
---
const STORE_ID = 'ddd7af53-792d-4ed8-891b-1adfe4f94f53';
const SKU = 'MM001';
---

<button 
    onclick={`BMOSEmbed.addProduct('${SKU}', '${STORE_ID}')`}
    data-bmos-sku={SKU}
    data-bmos-store={STORE_ID}>
    Book Now
</button>

<script is:inline src="https://app.buildmyonlinestore.com/embed.js"></script>
What prefetch does:
  • Adds preconnect hints for faster TLS handshake
  • Fetches product data from the API in the background
  • Loads the checkout.best widget script (~200KB)
  • First button click becomes instant (<100ms)

JavaScript API Reference

The embed script exposes a global window.BMOSEmbed object with these methods:

BMOSEmbed.addProduct(sku, storefrontId, quantity)

Add a product to cart and open checkout. Perfect for custom buttons.

Parameter Type Required Description
sku string Required Product SKU from your catalog
storefrontId string Optional* Your storefront UUID. Optional if a .bmos-product element exists on page
quantity number Optional Quantity to add (default: 1)
// Basic usage
BMOSEmbed.addProduct('MM001', 'ddd7af53-792d-4ed8-891b-1adfe4f94f53');

// With quantity
BMOSEmbed.addProduct('MM001', 'ddd7af53-792d-4ed8-891b-1adfe4f94f53', 3);

// Returns a Promise
const result = await BMOSEmbed.addProduct('MM001', 'ddd7af53-...');
console.log(result); // { success: true, product: {...} }

BMOSEmbed.getProduct(sku, storefrontId)

Fetch product data without adding to cart. Useful for displaying prices.

const product = await BMOSEmbed.getProduct('MM001', 'ddd7af53-...');

console.log(product);
// {
//   sku: "MM001",
//   name: "Power Hour Timer",
//   price: 29.99,
//   currency: "USD",
//   image: "https://...",
//   brand_color: "#667eea"
// }

BMOSEmbed.init()

Manually trigger initialization. Called automatically, but useful after dynamically adding elements.

// After dynamically adding a .bmos-product element
document.body.innerHTML += '<div class="bmos-product" data-sku="NEW-SKU" data-store="..."></div>';
BMOSEmbed.init();

BMOSEmbed.clearCache()

Clear the product data cache. Useful during development.

BMOSEmbed.clearCache();

Embed Styles

When using the standard .bmos-product div, set data-style to control appearance:

Style Description Best For
button Simple "Buy Now" button with price Inline purchase CTAs, blog posts
card Product card with image, name, price Product showcases, landing pages
rich Full card with description and variants Detailed product pages
<!-- Minimal button -->
<div class="bmos-product" data-sku="MM001" data-store="..." data-style="button"></div>

<!-- Product card -->
<div class="bmos-product" data-sku="MM001" data-store="..." data-style="card"></div>

<!-- Rich product card -->
<div class="bmos-product" data-sku="MM001" data-store="..." data-style="rich"></div>

Real-World Examples

Astro Site with Custom Button

<!-- src/pages/products/power-hour.astro -->
---
const STORE_ID = 'ddd7af53-792d-4ed8-891b-1adfe4f94f53';
const SKU = 'MM001';
---

<Layout title="Power Hour Timer">
  <section class="hero">
    <h1>Power Hour Timer</h1>
    <p>Stay focused and productive</p>
    
    <!-- Custom styled button -->
    <button 
      class="cta-button"
      onclick={`BMOSEmbed.addProduct('${SKU}', '${STORE_ID}')`}
    >
      Get It Now - $29.99
    </button>
  </section>
  
  <!-- Load embed script -->
  <script is:inline src="https://app.buildmyonlinestore.com/embed.js"></script>
</Layout>

<style>
  .cta-button {
    background: linear-gradient(135deg, #667eea, #764ba2);
    color: white;
    padding: 16px 32px;
    border: none;
    border-radius: 8px;
    font-size: 18px;
    font-weight: 600;
    cursor: pointer;
    transition: transform 0.2s;
  }
  .cta-button:hover {
    transform: scale(1.05);
  }
</style>

Next.js with Dynamic Price Display

// pages/product/[sku].jsx
import { useEffect, useState } from 'react';
import Script from 'next/script';

export default function ProductPage({ sku, storeId }) {
  const [product, setProduct] = useState(null);
  const [loading, setLoading] = useState(true);
  
  useEffect(() => {
    // Wait for embed script to load
    const checkEmbed = setInterval(() => {
      if (window.BMOSEmbed) {
        clearInterval(checkEmbed);
        loadProduct();
      }
    }, 100);
    
    async function loadProduct() {
      const data = await window.BMOSEmbed.getProduct(sku, storeId);
      setProduct(data);
      setLoading(false);
    }
  }, [sku, storeId]);
  
  const handleBuy = () => {
    window.BMOSEmbed.addProduct(sku, storeId);
  };
  
  return (
    <>
      <Script src="https://app.buildmyonlinestore.com/embed.js" />
      
      <div className="product-page">
        {loading ? (
          <p>Loading...</p>
        ) : (
          <>
            <img src={product?.image} alt={product?.name} />
            <h1>{product?.name}</h1>
            <p className="price">${product?.price}</p>
            <button onClick={handleBuy}>
              Add to Cart
            </button>
          </>
        )}
      </div>
    </>
  );
}

Vanilla HTML with Multiple Products

<!DOCTYPE html>
<html>
<head>
    <title>My Store</title>
    <style>
        .product-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; }
        .product-card { border: 1px solid #ddd; padding: 20px; text-align: center; }
        .buy-btn { background: #667eea; color: white; padding: 10px 20px; border: none; cursor: pointer; }
    </style>
</head>
<body>
    <div class="product-grid">
        <div class="product-card">
            <h3>Product A</h3>
            <button class="buy-btn" onclick="BMOSEmbed.addProduct('PROD-A', 'your-store-id')">
                Buy - $19.99
            </button>
        </div>
        
        <div class="product-card">
            <h3>Product B</h3>
            <button class="buy-btn" onclick="BMOSEmbed.addProduct('PROD-B', 'your-store-id')">
                Buy - $29.99
            </button>
        </div>
        
        <div class="product-card">
            <h3>Product C</h3>
            <button class="buy-btn" onclick="BMOSEmbed.addProduct('PROD-C', 'your-store-id')">
                Buy - $39.99
            </button>
        </div>
    </div>
    
    <script src="https://app.buildmyonlinestore.com/embed.js"></script>
</body>
</html>

Variant Selector

For products with multiple variants (sizes, colors, etc.), use the variant selector:

<div class="bmos-variant-selector"
     data-store="your-storefront-uuid"
     data-parent-title="T-Shirt Sizes"
     data-variants="TSHIRT-S,TSHIRT-M,TSHIRT-L,TSHIRT-XL">
</div>

<script src="https://app.buildmyonlinestore.com/embed.js"></script>

This renders a grid of variant cards with images, prices, and individual Buy Now buttons.

Troubleshooting

Button not appearing on Astro/Next.js

The embed script v2.0 automatically retries initialization every 500ms for up to 5 seconds. If your element is added after that, call BMOSEmbed.init() manually.

Custom button does nothing

Make sure:

  • The embed script is loaded before clicking
  • You're passing the correct storefront UUID (not store name)
  • The SKU exists in your storefront's attached catalogs

Check browser console

The embed script logs helpful debug messages:

[BMOS Embed] Script loaded v2.0. API: init(), addProduct(sku, storeId), getProduct(sku, storeId)
[BMOS Embed] Found 2 product element(s) and 0 selector(s) to initialize
[BMOS Embed] addProduct: Fetching MM001 from store ddd7af53-...
[BMOS Embed] addProduct: Added to cart via CheckoutBest.addItem()

Cache issues

If product data seems stale, clear the cache:

BMOSEmbed.clearCache();
BMOSEmbed.init();

Finding Your Store ID

Your storefront UUID is shown in the dashboard and Buttons Manager:

  1. Log in to app.buildmyonlinestore.com
  2. Click on your storefront
  3. Go to "Manage Buttons"
  4. Copy the Store ID from the embed code examples
Pro tip: The Store ID is a UUID like ddd7af53-792d-4ed8-891b-1adfe4f94f53. Don't confuse it with your product SKUs or catalog IDs.