You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在React(NextJS+TypeScript)的.tsx文件中嵌入Shopify购买按钮

在 Next.js + TypeScript 中嵌入 Shopify 购买按钮的实现方案

针对你的场景,直接在.tsx文件中粘贴原生HTML脚本会因为React的DOM渲染机制和脚本执行时机问题导致组件无法正常初始化,下面提供两种适配Next.js + TypeScript的可行方案:


方案一:使用 React useEffect 动态加载脚本

利用React的useEffect钩子在组件挂载后完成脚本加载和Shopify组件初始化,完美贴合React生命周期:

import { useEffect, useRef } from 'react';

// 声明ShopifyBuy的全局类型,避免TypeScript报错
declare global {
  interface Window {
    ShopifyBuy: any;
  }
}

export default function ShopifyCollection() {
  // 用useRef获取容器元素,避免重复查询DOM
  const collectionRef = useRef<HTMLDivElement>(null);

  useEffect(() => {
    if (!collectionRef.current) return;

    const scriptURL = 'https://sdks.shopifycdn.com/buy-button/latest/buy-button-storefront.min.js';

    // 初始化Shopify组件的逻辑
    const initShopify = () => {
      const client = window.ShopifyBuy.buildClient({
        domain: 'xxxxxxxxxxx.myshopify.com',
        storefrontAccessToken: 'xxxxxxxxxxxxxxxxxxxxxx',
      });

      window.ShopifyBuy.UI.onReady(client).then((ui: any) => {
        ui.createComponent('collection', {
          id: 'xxxxxxxxxxxxx',
          node: collectionRef.current,
          moneyFormat: '%24%7B%7Bamount%7D%7D',
          options: {
            "product": {
              "styles": {
                "product": {
                  "@media (min-width: 601px)": {
                    "max-width": "calc(25% - 20px)",
                    "margin-left": "20px",
                    "margin-bottom": "50px",
                    "width": "calc(25% - 20px)"
                  },
                  "img": {
                    "height": "calc(100% - 15px)",
                    "position": "absolute",
                    "left": "0",
                    "right": "0",
                    "top": "0"
                  },
                  "imgWrapper": {
                    "padding-top": "calc(75% + 15px)",
                    "position": "relative",
                    "height": "0"
                  }
                },
                "title": {
                  "font-size": "14px",
                  "color": "#000000"
                },
                "button": {
                  ":hover": {
                    "background-color": "#10002b"
                  },
                  "background-color": "#100030",
                  ":focus": {
                    "background-color": "#10452b"
                  },
                  "padding-left": "35px",
                  "padding-right": "35px"
                },
                "price": {
                  "color": "#086cce"
                },
                "compareAt": {
                  "color": "#0000ce"
                },
                "unitPrice": {
                  "color": "#0000ce"
                }
              },
              "text": {
                "button": "Add to cart"
              }
            },
            "productSet": {
              "styles": {
                "products": {
                  "@media (min-width: 601px)": {
                    "margin-left": "-20px"
                  }
                }
              }
            },
            "modalProduct": {
              "contents": {
                "img": false,
                "imgWithCarousel": true,
                "button": false,
                "buttonWithQuantity": true
              },
              "styles": {
                "product": {
                  "@media (min-width: 601px)": {
                    "max-width": "100%",
                    "margin-left": "0px",
                    "margin-bottom": "0px"
                  }
                },
                "button": {
                  ":hover": {
                    "background-color": "#10452b"
                  },
                  "background-color": "#124d30",
                  ":focus": {
                    "background-color": "#10452b"
                  },
                  "padding-left": "35px",
                  "padding-right": "35px"
                },
                "title": {
                  "font-family": "Helvetica Neue, sans-serif",
                  "font-weight": "bold",
                  "font-size": "26px",
                  "color": "#40004c"
                },
                "price": {
                  "font-family": "Helvetica Neue, sans-serif",
                  "font-weight": "normal",
                  "font-size": "14px",
                  "color": "#40004c"
                },
                "compareAt": {
                  "font-family": "Helvetica Neue, sans-serif",
                  "font-weight": "normal",
                  "font-size": "11.9px",
                  "color": "#40004c"
                },
                "unitPrice": {
                  "font-family": "Helvetica Neue, sans-serif",
                  "font-weight": "normal",
                  "font-size": "11.9px",
                  "color": "#40004c"
                }
              },
              "text": {
                "button": "Add to cart"
              }
            },
            "option": {},
            "cart": {
              "styles": {
                "button": {
                  ":hover": {
                    "background-color": "#10002b"
                  },
                  "background-color": "#100000",
                  ":focus": {
                    "background-color": "#10002b"
                  }
                }
              },
              "text": {
                "total": "Subtotal",
                "button": "Checkout"
              },
              "popup": false
            },
            "toggle": {
              "styles": {
                "toggle": {
                  "background-color": "#120030",
                  ":hover": {
                    "background-color": "#10002b"
                  },
                  ":focus": {
                    "background-color": "#10002b"
                  }
                }
              }
            }
          },
        });
      });
    };

    // 检查ShopifyBuy是否已加载
    if (window.ShopifyBuy) {
      if (window.ShopifyBuy.UI) {
        initShopify();
      } else {
        // 动态创建脚本标签加载Shopify SDK
        const script = document.createElement('script');
        script.async = true;
        script.src = scriptURL;
        script.onload = initShopify;
        document.head.appendChild(script);
      }
    } else {
      const script = document.createElement('script');
      script.async = true;
      script.src = scriptURL;
      script.onload = initShopify;
      document.head.appendChild(script);
    }

    // 清理函数:组件卸载时移除脚本(可选,避免重复加载)
    return () => {
      const existingScript = document.querySelector(`script[src="${scriptURL}"]`);
      if (existingScript) {
        document.head.removeChild(existingScript);
        // 清空全局变量,避免下次加载冲突
        delete window.ShopifyBuy;
      }
    };
  }, []);

  return <div ref={collectionRef} id="collection-component-XXXXXXXXXX9"></div>;
}

方案二:使用 Next.js Script 组件(推荐)

Next.js 提供的Script组件支持脚本加载策略优化(如懒加载、预加载),更适合Next.js项目:

import { useRef } from 'react';
import Script from 'next/script';

declare global {
  interface Window {
    ShopifyBuy: any;
  }
}

export default function ShopifyCollection() {
  const collectionRef = useRef<HTMLDivElement>(null);

  const initShopify = () => {
    if (!collectionRef.current) return;

    const client = window.ShopifyBuy.buildClient({
      domain: 'xxxxxxxxxxx.myshopify.com',
      storefrontAccessToken: 'xxxxxxxxxxxxxxxxxxxxxx',
    });

    window.ShopifyBuy.UI.onReady(client).then((ui: any) => {
      ui.createComponent('collection', {
        id: 'xxxxxxxxxxxxx',
        node: collectionRef.current,
        moneyFormat: '%24%7B%7Bamount%7D%7D',
        options: {
          // 粘贴你原有的options配置,与方案一完全一致即可
        },
      });
    });
  };

  return (
    <>
      <div ref={collectionRef} id="collection-component-XXXXXXXXXX9"></div>
      {/* 使用Next.js Script组件加载Shopify SDK,策略选afterInteractive确保页面交互后加载 */}
      <Script
        src="https://sdks.shopifycdn.com/buy-button/latest/buy-button-storefront.min.js"
        strategy="afterInteractive"
        onLoad={initShopify}
      />
    </>
  );
}

注意事项

  • 替换代码中所有xxxxxxxxxxx占位符为你实际的Shopify店铺域名、AccessToken和集合ID
  • TypeScript类型声明可以安装@types/shopify-buy包获得更精确的类型,上述代码中的any为简化处理
  • 用useRef获取DOM元素比getElementById更可靠,避免React渲染时DOM未就绪的问题
  • 测试时注意清理浏览器缓存,避免旧脚本影响加载效果

内容的提问来源于stack exchange,提问作者Crunchy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 08:50:44