Things to Keep in Mind

When building custom blocks with VajroSDK, here are a few technical considerations and best practices:

  1. Always Resize the Block after DOM Updates

    Since the mobile app embeds your block inside an iframe, its height won’t automatically adjust if your content changes (e.g., fetching products, expanding accordions, etc.).
    <div id="accordion">
      <button id="toggle">Toggle Content</button>
      <div id="content" style="display:none">
        <t4>Dynamic content goes here…</t4>
      </div>
    </div>
    
    <script>
      document.getElementById("toggle").addEventListener("click", async () => {
        const content = document.getElementById("content");
        const isVisible = content.style.display === "block";
        content.style.display = isVisible ? "none" : "block";
    
        // ✅ Ensure block resizes after toggle
        await VajroSDK.actions.resizeBlock();
      });
    </script>
    
  2. Use Async/Await for SDK Actions

    Most SDK actions return Promises. Handle them properly with async/await or .then().
    async function openProduct(productHandle) {
      try {
        await VajroSDK.actions.openProduct({ productHandle });
      } catch (err) {
        console.error("Failed to open product", err);
      }
    }
    
  3. Use Typography Components (t1–t6) and Buttons (<filled-button>, <outlined-button>)

    For consistency with your brand's theming, always use SDK components (since they take the theme directly from the theme style) instead of raw <h1-h6>,<p>,<button>.
    <t2>Featured Products</t2>
    <filled-button onclick="addToCart()">Add to Cart</filled-button>
    
  4. Use Listeners to React to Real-Time Events

    Listeners keep your block in sync with what the user does in the app (like changing a variant or adding/removing products from the cart).
    They’re better than polling because they trigger only when something changes.
    <div>
      <img id="product-image" />
      <t4 id="product-price"></t4>
    
      <div>
        <span id="cart-count">0</span> items in cart
      </div>
    </div>
    
    <script>
      // 🔄 Render product price & image
      function renderProduct() {
        const variant = VajroSDK.variables.product?.selectedVariant;
        document.getElementById("product-price").textContent = variant?.price
          ? `₹${variant.price}`
          : "—";
        if (variant?.image) {
          document.getElementById("product-image").src = variant.image.src;
        }
      }
    
      // 🛒 Render cart count
      function renderCart() {
        const cart = VajroSDK.variables.cart;
        document.getElementById("cart-count").textContent =
          cart?.items?.length || 0;
      }
    
      // 👂 Listeners
      VajroSDK.listeners.onVariantChanged(() => {
        renderProduct();
        VajroSDK.actions.resizeBlock();
      });
    
      VajroSDK.listeners.onCartUpdated(() => {
        renderCart();
        VajroSDK.actions.resizeBlock();
      });
    
      // Initial render
      renderProduct();
      renderCart();
    </script>