Wheel and Tire product variants on the search results and in the Verify Fitment widget
If a store has wheels and tires with variants, it is possible to display the variants as products in the search results after selecting a vehicle and check the variants for the selected vehicle.
1. Connect the WheelTireVariantsPlugin and add the wheel_tire_hierarchy_type field
Plugins:  - WheelTireUpsizeDownsizePluginFields:  wheel_tire_hierarchy_type:    Faceted: true    Scope: Internal    Visibility: Hide2. Override the ConvertVariant method
protected override void ConvertVariant(Item item, Item varItem, ProductVariant variant, Product product, int varNumber, ref bool skip){    base.ConvertVariant(item, varItem, variant, product, varNumber, ref skip);
    // call this again, the variant image is removed in ShopifyFitmentSearchItemConverter.ConvertVariant    ImageGraphQL variantImage = variant.Image ?? product.Images.FirstOrDefault()?.Image;    if (variantImage is not null)    {        AddImages(varItem, [variantImage]);    }
    varItem.Add("stock", FieldValues.All);    if (varItem.Get<bool>("available"))    {        varItem.Add("stock", FieldValues.Available);    }    else    {        varItem["out_of_stock"] = true;    }
    varItem["inventory_quantity"] = variant.InventoryQuantity;
    if (product.TracksInventory is true && variant.InventoryQuantity is > 0 and not 9999)    {        varItem.Add("stock", FieldValues.InStockOnly);    }}3. Create Wheel and Tire variants (please, follow the comments)
Wheel variants
protected override void AddWheels(Item item, Product product, IList<Item> productVariants){    if (product.HasOnlyDefaultVariant)    {        item[WheelTireVariantsPlugin.HierarchyField] = WheelTireVariantsPlugin.HierarchyType.Universal;
        // Add wheel attributes here    }    else    {        AddWheelVariants(item, productVariants);    }
    if (Store.Schema.Sources.ContainsKey(WheelTireFitmentHelper.SourceName))    {        item["Fitment"] = FitmentFieldValues.VehicleSpecific;    }}
private void AddWheelVariants(Item item, IList<Item> productVariants){    // Add needed fields as collections to item    item["wheel_diameter"] = new HashSet<string>();
    List<Item> processedVariants = [];
    foreach (Item variant in productVariants)    {        Item processedVariant = new(variant)        {            [WheelTireVariantsPlugin.HierarchyField] = WheelTireVariantsPlugin.HierarchyType.Variant,            // Add all needed item fields to the variant item            ["title"] = $"{item.Get("title")} {variant.Get("title")}",            ["vendor"] = item["vendor"],            ["vendor_url"] = item["vendor_url"],            ["published_at"] = item["published_at"],            ["collection_ids"] = item["collection_ids"],            ["category"] = item["category"],            ["YMMText"] = item["YMMText"],            [FitmentHelper.FitmentType] = new List<FitmentTypes>() { FitmentTypes.Wheel }        };
        // Add all variant attributes to the item        string diameter = "17";        variant.Add("wheel_diameter", diameter);        item.Add("wheel_diameter", diameter);
        processedVariants.Add(processedVariant);    }
    if (processedVariants.Count > 0)    {        item[WheelTireVariantsPlugin.HierarchyField] = WheelTireVariantsPlugin.HierarchyType.Product;        item["product_variants"] = processedVariants;    }    else    {        item[WheelTireVariantsPlugin.HierarchyField] = WheelTireVariantsPlugin.HierarchyType.Universal;    }}Tire variants
protected override void AddTires(Item item, Product product, IList<Item> productVariants){    if (product.HasOnlyDefaultVariant)    {        base.AddTires(item, product, productVariants);
        item[WheelTireVariantsPlugin.HierarchyField] = WheelTireVariantsPlugin.HierarchyType.Universal;    }    else    {        AddTireVariants(item, productVariants);    }}
private void AddTireVariants(Item item, IList<Item> productVariants){    // Add needed fields as collections to item    item["tire_width"] = new HashSet<string>();
    List<Item> processedVariants = [];
    foreach (Item variant in productVariants)    {        Item processedVariant = new(variant)        {            [WheelTireVariantsPlugin.HierarchyField] = WheelTireVariantsPlugin.HierarchyType.Variant,            // Add all needed item fields to the variant item            ["title"] = $"{item.Get("title")} ({variant.Get("title")})",            ["vendor"] = item["vendor"],            ["handle"] = item["handle"],            ["published_at"] = item["published_at"],            ["collection_ids"] = item["collection_ids"],            ["category"] = item["category"],            ["YMMText"] = item["YMMText"],            ["Fitment"] = item["Fitment"],            [FitmentHelper.FitmentType] = new List<FitmentTypes>() { FitmentTypes.Tire }        };
        // Add all variant attributes to the item        string width = "30";        variant.Add("tire_width", width);        item.Add("tire_width", width);
        processedVariants.Add(processedVariant);    }
    if (processedVariants.Count > 0)    {        item[WheelTireVariantsPlugin.HierarchyField] = WheelTireVariantsPlugin.HierarchyType.Product;        item["product_variants"] = processedVariants;    }    else    {        item[WheelTireVariantsPlugin.HierarchyField] = WheelTireVariantsPlugin.HierarchyType.Universal;    }}4. Override the GetProducts method to add variants to the index
public override async IAsyncEnumerable<IEnumerable<Item>> GetProducts(){    await foreach (IEnumerable<Item> batch in base.GetProducts())    {        List<Item> products = [];
        foreach (Item item in batch)        {            if (item.ContainsKey("product_variants"))            {                products.AddRange((List<Item>)item["product_variants"]);                item.Remove("product_variants");            }
            products.Add(item);        }
        yield return products;    }}5. Use variants for the Verify Fitment widget
Override the getItemId function and update the Verify Fitment widget on a variant selection
const getItemId = ({ getItemId, getVariantId }) => {  // check if the product has variants  // e.g. 'body.page-type-product variant-selects'  if (window.document.querySelector('PRODUCT OPTIONS SELECTOR')) {    const variantId = getVariantId();    if (variantId) {      return `${variantId}`;    }  }
  return getItemId();};
const InitFunc = () => {  // e.g. 'body.page-type-product variant-selects input'  const productOptions = window.document.querySelectorAll('OPTION INPUTS SELECTOR');
  productOptions?.forEach((element) => {    element.addEventListener('change', () => {      setTimeout(() => {        window.Convermax.updateVerifyFitmentWidget(getItemId());      }, 300);    });  });};
export default {  ...  InitFunc,  product: {    ...,    getItemId,  },  ...}; 
 