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

BigCommerce LifeStyle主题:特色产品自定义字段添加及Widget调试

BigCommerce LifeStyle主题自定义字段展示问题及Widget调试方案

问题概述

  • 已在BigCommerce后台为产品添加自定义字段,但Stencil编辑器(首页场景)无可视化添加该字段的选项
  • 通过开发者工具确认首页目标展示区域对应home.html中的代码{{{region name="home_below_new_products"}}},但找不到可直接编辑的关联模板文件
  • 尝试通过API创建自定义Widget,无法正常输出内容,Widget核心代码如下:

Widget GraphQL查询代码

query ProductSet($productIds: [Int!], $activeCurrencyCode: currencyCode!) {
  site {
    settings {
      storeName
      tax {
        plp
      }
    }
    currency(currencyCode: $activeCurrencyCode) {
      display {
        symbol
        symbolPlacement
        decimalToken
        decimalPlaces
        thousandsToken
      }
    }
    products(entityIds: $productIds) {
      edges {
        node {
          brand {
            name
          }
          name
          entityId
          addToCartUrl
          addToWishlistUrl
          path
          sku
          priceWithTax: prices(includeTax: true, currencyCode: $activeCurrencyCode)  {
            price {
              currencyCode
              value
            }
          }
          priceWithoutTax: prices(includeTax: false, currencyCode: $activeCurrencyCode)  {
            price {
              currencyCode
              value
            }
          }
          reviewSummary {
            summationOfRatings
            numberOfReviews
          }
          defaultImage {
            url80wide: url(width: 80)
            url160wide: url(width: 160)
            url320wide: url(width: 320)
            url640wide: url(width: 640)
            url960wide: url(width: 960)
            url1280wide: url(width: 1280)
            url1920wide: url(width: 1920)
          }
        customFields {
        edges {
        node {
          name
          value}
        }
        }
        }
      }
    }
  }
}

Widget模板代码

<div id="sd-product-set-{{_.id}}"></div>

{{#each products as |product|}}
  {{#each ../_.data.site.products.edges as |productResource|}}
    {{#if productResource.node.entityId "===" product.productId}}
      <script type="application/ld+json">
        {
          "@context": "https://schema.org/",
          "@type": "Product",
          "name": "{{productResource.node.name}}",
          "image": "{{productResource.node.defaultImage.url}}",
          "description": "{{product.productDescription}}",
          "sku": "{{productResource.node.sku}}",
          "potency": "{{#each productResource.node.customFields.edges}}{{#if node.name "===" "potency"}}{{ node.value }}{{/if}}{{/each}}",
          "aggregateRating": {
            "@type": "AggregateRating",
            {{#if productResource.node.reviewSummary.summationOfRatings "===" 0}}
            "ratingValue": "0",
            {{else}}
            "ratingValue": "{{divide productResource.node.reviewSummary.summationOfRatings productResource.node.reviewSummary.numberOfReviews}}",
            {{/if}}
            "reviewCount": "{{productResource.node.reviewSummary.numberOfReviews}}"
          },
          "offers": {
            "@type": "Offer",
            "priceCurrency": "{{productResource.node.prices.price.currencyCode}}",
            "price": "{{productResource.node.prices.price.value}}",
            "seller": {
              "@type": "Organization",
              "name": "{{../../../_.data.site.settings.storeName}}"
            }
          }
        }
      </script>
    {{/if}}
  {{/each}}
{{/each}}

<script type="text/javascript">
  (function() {
    var widgetConfiguration = {{{json .}}};
    var dataIsNotPresent = typeof widgetConfiguration._.data === 'undefined' || Object.keys(widgetConfiguration._.data || {}).length === 0;
    var storefrontApiQueryData = widgetConfiguration._.queryData;

    function executeStorefrontApiQuery(queryData, callback) {
      var storefrontApiRequest = new XMLHttpRequest();
      storefrontApiRequest.onreadystatechange = function() {
        if (this.readyState == 4 && this.status == 200) {
          callback(JSON.parse(this.response).data);
        }
      };

      storefrontApiRequest.open('POST', `/graphql`, true);
      storefrontApiRequest.setRequestHeader('Authorization', `Bearer ${queryData.storefrontApiToken}`);
      storefrontApiRequest.setRequestHeader('Content-type', 'application/json');
      storefrontApiRequest.send(JSON.stringify({ query: queryData.storefrontApiQuery, variables: JSON.parse(queryData.storefrontApiQueryParamsJson) }));
    }

    function loadScript(src, onload) {
        const scriptTag = document.createElement('script');
        scriptTag.type = 'text/javascript';
        scriptTag.defer = true;
        scriptTag.src = src;
        if (onload) {
            scriptTag.onload = onload;
        }
        document.head.appendChild(scriptTag);
    }

    function executeWidget(configuration, storefrontApiData) {
      if (storefrontApiData) {
        configuration._.data = storefrontApiData;
      }
      {{#if _.context.isEditorMode '===' true}}
        var scriptPath = (build) => `https://microapps.bigcommerce.com/product-set-widget/b5bcd08d0f4673db814c9ad9a35c90873a9f2f58/${build}-bundle.js`;
        if (window.BigCommerce
                && window.BigCommerce.initializeProductSet
                && typeof window.BigCommerce.initializeProductSet === 'function'
                && window.BigCommerce.initializeProductSetPageBuilderComm
                && typeof window.BigCommerce.initializeProductSetPageBuilderComm === 'function') {
            const productSet = window.BigCommerce.initializeProductSet(configuration);
            window.BigCommerce.initializeProductSetPageBuilderComm(productSet);
        } else {
            loadScript(scriptPath('storefront'), () => {
                const productSet = window.BigCommerce.initializeProductSet(configuration);
                loadScript(scriptPath('pageBuilder'), () => {
                    window.BigCommerce.initializeProductSetPageBuilderComm(productSet);
                });
            });
        }
      {{else}}
        var storefrontScriptPath = "https://microapps.bigcommerce.com/product-set-widget/b5bcd08d0f4673db814c9ad9a35c90873a9f2f58/storefront-bundle.js";
        if (window.BigCommerce && window.BigCommerce.initializeProductSet && typeof window.BigCommerce.initializeProductSet === 'function') {
            window.BigCommerce.initializeProductSet(configuration).setup();
        } else {
            loadScript(storefrontScriptPath, () => window.BigCommerce.initializeProductSet(configuration).setup());
        }
      {{/if}}
    }

    if (dataIsNotPresent && storefrontApiQueryData) {
      executeStorefrontApiQuery(storefrontApiQueryData, function(storefrontApiData) { executeWidget(widgetConfiguration, storefrontApiData) });
    } else {
      executeWidget(widgetConfiguration);
    }
  })();
</script>

问题解决与调试方案

一、Stencil主题区域自定义字段展示

  1. 扩展主题模板区域

    • 若使用可编辑主题,在templates/components目录下新建custom文件夹,创建home-custom-fields.html文件,编写自定义字段展示逻辑:
      {{#each products}}
        <div class="product-custom-field">
          <span>Potency:</span> {{customFields['potency']}}
        </div>
      {{/each}}
      
    • 在home.html中,将{{{region name="home_below_new_products"}}}替换为{{> components/custom/home-custom-fields}},直接引入自定义模板
    • 若为托管不可编辑主题,需先克隆主题到本地修改,再重新上传发布
  2. 直接在产品卡片中添加字段
    找到templates/components/products/card.html(产品卡片模板),插入自定义字段代码:

    {{#if customFields['potency']}}
      <div class="product-potency">Potency: {{customFields['potency']}}</div>
    {{/if}}
    

二、自定义Widget输出问题修复

从代码来看,核心问题集中在数据匹配、模板逻辑和API调用上:

  1. 简化模板遍历逻辑
    原模板同时遍历两个产品数据集,逻辑冗余,改为直接遍历GraphQL返回的数据:
    {{#each _.data.site.products.edges as |edge|}}
      {{#with edge.node}}
        <div class="product-item">
          <h4>{{name}}</h4>
          {{#each customFields.edges}}
            {{#if node.name "===" "potency"}}
              <p>Potency: {{node.value}}</p>
            {{/if}}
          {{/each}}
        </div>
      {{/with}}
    {{/each}}
    
  2. 修正图片URL引用
    GraphQL查询中图片使用了url80wide等别名,模板中需对应改为{{productResource.node.defaultImage.url80wide}}
  3. 检查API权限与请求
    • 确认Storefront API Token拥有products_read权限
    • 在浏览器开发者工具Network标签中查看GraphQL请求状态,检查返回数据是否包含自定义字段
  4. 添加可见内容输出
    原模板仅输出JSON-LD脚本,需添加HTML代码展示自定义字段,才能在页面上看到内容

内容的提问来源于stack exchange,提问作者jesus g_force Harris

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 07:55:57