[{"t":"What WySync Fitment is","g":"Start here","u":"/docs/start/what-is-wysync","d":"The problem it solves, and every category it solves it for.","h":["What it actually does","What it is not","Who it's for","The shape of the rest of these docs"],"b":"WySync Fitment is a Shopify app for stores whose products only fit some vehicles. It answers one question everywhere in the storefront — does this fit the vehicle I drive? — and it answers it the same way on every surface, from the homepage to the checkout button. It does not care what the part is. Lift kits, brake kits, coilovers, light bars, tonneau covers, intakes, hitches, wipers, filters, wheels, tires — if the answer depends on the shopper's vehicle, it is the same problem, and WySync solves it the same way. Spec fields in the index are typed, not hard-coded, so blade length and hitch class behave exactly like diameter and offset do. We started with wheels because wheel fitment is the hardest version of the problem in the aftermarket — five interacting measurements, none of them exact. Anything that handles that handles a direct-fit brake pad without breaking a sweat. What it actually does Indexes your catalog every product, variant, price, inventory level, collection and metafield, into a search index that belongs to your shop alone. Resolves fitment merges every source you connect into one set of vehicles per SKU. Renders nine widgets theme blocks that read one shared vehicle and answer for it. Captures the vehicle on the order so your warehouse and your support team see what the customer was buying for. What it is not It is not a data subscription. The app indexes the "},{"t":"How it works","g":"Start here","u":"/docs/start/how-it-works","d":"Shopify → indexer → Typesense → widgets, end to end.","h":["1. Ingest","2. Resolve","3. Index","4. Serve","What happens when something is down"],"b":"Four stages, in this order. Everything else in these docs is a detail of one of them. 1. Ingest On install — and on every full reindex after that — the app runs a Shopify GraphQL bulk operation that pulls your entire catalog: products, variants, SKUs, prices, compare-at prices, inventory levels, vendor, product type, collection memberships and metafields. Nothing is copied into a WySync product table. Shopify remains the source of truth for your catalog; we hold only the derived search documents plus your app configuration. On Growth and above the app also subscribes to products/create, products/update, products/delete and inventorylevels/update webhooks, so individual changes flow through within seconds instead of waiting for the next scheduled run. 2. Resolve Each product's fitment is computed by merging every source you've connected: product tags matching the fits… grammar CSV uploads and Google Sheets rows, expanded across year ranges metafield specs, canonicalised (lengths, diameters, positions — and bolt patterns and offsets where you sell wheels) vendor feed rows for the SKUs the supplier recognises fitment editor overlays — your manual additions, exclusions, universal flags and notes The merge is a union: if any source confirms a SKU fits a vehicle, it fits. There is no precedence order to configure and no \"winning\" source, because in practice every source is incomplete"},{"t":"Installing the app","g":"Start here","u":"/docs/start/install","d":"Scopes, first index, and the theme install.","h":["Before you start","The scopes we ask for","What happens immediately after install","Installing the storefront widgets","Uninstalling"],"b":"Installing takes a few minutes. Getting a good first result takes about ten — see the quickstart once you're through this page. Before you start Shopify plan any plan that supports apps. Shopify Plus is not required. Theme any Online Store 2.0 theme. Vintage themes can run the app embeds but not the section blocks. Access you need to be able to install apps and edit the theme, or have someone who can. The scopes we ask for Catalog access — readproducts, writeproducts, readproductlistings, readinventory Titles, variants, SKUs, prices, inventory and product metafields: the data that gets indexed. The write scope creates two metafield definitions (wysync.universalfit, wysync.fitmentnote) so the fitment editor has somewhere to store your overrides. Fitment storage — readmetaobjects, writemetaobjects Holds your fitment sources and mapping configuration inside your own store. Theme — readthemes Detects whether the app's blocks are installed on your published theme. We never modify your theme's own templates. Orders — readorders Reads back the vehicle and verdict the app itself wrote as line item properties, for merchant reporting. Customers — readcustomers, writecustomers One metafield, wysync.garage, so a logged-in shopper's saved vehicles follow them across devices. No other customer field is touched. Publications — readpublications, writepublications Publishes generated vehicle la"},{"t":"Quickstart: first vehicle search","g":"Start here","u":"/docs/start/quickstart","d":"Ten minutes from install to a working YMMS search.","h":["1. Confirm the index is healthy","2. Connect one fitment source","3. Map your collections","4. Place three widgets","5. Test it like a customer","6. Then add the rest"],"b":"This gets a shopper from \"I drive a 2019 F-150\" to a grid of parts that actually fit. It assumes the app is installed and the first index has finished. The slow part is deciding which collections to map. Everything else here is a few clicks. 1. Confirm the index is healthy Open Indexing. You want a completed job with a product count close to what Shopify reports. If products failed, each failure lists a reason — most commonly a malformed spec metafield. 2. Connect one fitment source Start with whatever you already have. In order of least effort: Already tagging products? Go to Fitment data → Sources and enable tag parsing. If your tags match the fits… grammar, you're done in one click. Have a supplier CSV? Upload it. Columns are SKU, Years, Make, Model, Submodel, Note. Keep a sheet? Paste the Google Sheets URL and the app re-reads it on a schedule. Have none of the above? Ask your suppliers for a fitment export — most have one. If you sell wheels or tires, the Fitment Data add-on can judge their specs with no mappings at all. Save, then run Reindex so the mappings are resolved into the index. Fitment coverage on the Dashboard should climb. 3. Map your collections Under Storefront → Collections, add the collections a shopper should see after they pick a vehicle — your top-level categories, whatever they are: Suspension, Brakes, Lighting, Wheels, Exhaust, Interior, Towing. Order "},{"t":"Choosing a plan","g":"Start here","u":"/docs/start/choose-a-plan","d":"What actually differs between the four plans.","h":["The short version","The question that actually decides it","Source limits, precisely","Things that are not gated","The add-on is a separate decision","Changing your mind"],"b":"Every plan ships all nine widgets, the fitment editor, the analytics dashboard, the YMMS taxonomy, free setup and a 30-day trial. Plans differ on three things only: how many supplier integrations you connect, how fast the index refreshes, and how much of our time you get. The short version Starter — $99 One or two suppliers, and you're comfortable with a six-hourly index. Most single-category and boutique stores. Growth — $299 You want realtime price and stock accuracy, and auto-generated vehicle pages for SEO. Most stores land here. Pro — $549 You carry a lot of brands and want every standard adapter plus unlimited sources and phone support. Enterprise — $999 Your suppliers need adapters that don't exist yet, and you want development time without a meter. The question that actually decides it How wrong can your prices and stock be for six hours? Starter reindexes on a six-hour cycle plus a manual button. That is fine for a catalog where prices move monthly. It is not fine on a Friday when a supplier drops MAP and you're running ads: for six hours your storefront can advertise the old price and take orders for stock you just sold out of. From Growth, the app subscribes to product, inventory and price webhooks, so those changes land in seconds. Everything else in the ladder is secondary to that. Source limits, precisely Starter Growth Pro Enterprise Vendor integrations 2 5 All 1"},{"t":"Glossary","g":"Start here","u":"/docs/start/glossary","d":"YMMS, submodel, envelope, universal, verdict.","h":[],"b":"The words these docs and the admin use, defined once. YMMS Year, Make, Model, Submodel. The four-level cascade the app uses to identify a vehicle. Every vehicle in the taxonomy resolves to a numeric vehicleid; widgets pass that ID around, never the strings. Submodel The trim or variant level: Lariat, Rubicon, TRD Off-Road, Si. A mapping with the submodel left blank applies to every submodel of that year, make and model. Vehicle ID The stable numeric identifier for one exact YMMS combination. What actually gets stored on a product document and compared at query time. Fitment source Anywhere a SKU-to-vehicle claim comes from: tags, CSV, Sheets, metafields, a vendor feed, the WySync data add-on, or the editor. Union The merge rule. A SKU fits a vehicle if any connected source says so. No precedence, no winner. Overlay An editor change applied after the union: an addition, an exclusion, a universal flag or a note. Survives every reindex. Universal A SKU that fits everything: cleaner, a universal hitch pin, a torque wrench. Flagged rather than mapped, and never filtered out by a vehicle. Verdict The answer shown to a shopper: fits, does not fit, or unconfirmed. Copy is yours; the three states are not. Envelope A range of acceptable values for a vehicle rather than a single number — diameter 17\"–24\", offset −24 to +45mm, lift height 4–6\". Real fitment is ranges, which is why exact-va"},{"t":"Fitment data overview","g":"Fitment data","u":"/docs/data/overview","d":"The union model: any source can confirm a fit.","h":["The union rule","The sources","When resolution happens","The three verdicts","Coverage, measured"],"b":"Fitment data is the set of claims that link a SKU to a vehicle. WySync does not invent those claims — it collects them from wherever you keep them, merges them, and puts the result in front of the shopper. The union rule A SKU fits a vehicle if any connected source says it does. That is the whole model. There is no precedence order to configure, no source ranked above another, and no conflict resolution screen. It works because in practice every source is incomplete in a different direction: your tags cover the bestsellers, the supplier feed covers their own catalog, the spec data covers everything with clean measurements, and none of them covers all three. The trade-off is honest and worth stating: a union propagates a source's mistakes as readily as its coverage. That is what the fitment editor is for — exclusions are applied after the merge and win. The sources Source Setup effort Best for Plan Product tags None if you already tag Stores already using a tag scheme All CSV upload Minutes A supplier's fitment export All (count varies) Google Sheets Minutes Mappings a person maintains by hand All, unlimited Metafields Mapping step Catalogs with clean spec data All, unlimited Vendor integrations We connect it Turn 14, WheelPros and friends 2 / 5 / all 16 / unlimited WySync Fitment Data One toggle Wheels & tires with no mappings +$150/mo When resolution happens Fitment resolves a"},{"t":"Product tags","g":"Fitment data","u":"/docs/data/product-tags","d":"The zero-setup source that already works with your catalog.","h":["The grammar","How they're parsed","Strengths and limits","Migrating an existing tag scheme"],"b":"Tags are the fastest source to switch on, because a lot of stores already have them. If your products carry tags in the supported grammar, enabling tag parsing turns them into real fitment with no upload and no mapping step. The grammar Examples: The grammar is category-neutral — the same tag says a brake kit, a light bar or a set of wheels fits that vehicle. Prefix fits is required, lowercase. Tags without it are ignored entirely, so your merchandising tags are safe. Years one year (2018), or an underscore-separated range meaning inclusive from–to (20102015). Make and model lowercase, spaces and slashes become hyphens. F-150 becomes f-150. Submodel optional. Omit it and the tag applies to every submodel of that year, make and model. How they're parsed On every index run, each product's tags are scanned for the prefix, split, normalized against the synonym rules, and resolved against the vehicle taxonomy. Matches become vehicle IDs on the product's document; unmatched tags are reported in the Sources screen with what they did not resolve to. That report is the useful part. A tag like fits20152026-chevy-silverado resolves fine because chevy → chevrolet is a default synonym — but fits2015-ford-f150 will show up as unresolved, because the taxonomy spells it f-150. Fixing that is either a tag edit or a one-line synonym. Strengths and limits Good, because: Nothing to upload, nothing"},{"t":"CSV upload","g":"Fitment data","u":"/docs/data/csv","d":"Bulk mapping from a spreadsheet export.","h":["Columns","Uploading","Common failure modes","Plan limits"],"b":"The CSV source is the workhorse: one row per SKU-and-vehicle claim, expanded across year ranges at import. Columns SKU required. Matched against the variant SKU in Shopify, case-insensitively, whitespace trimmed. Years required. A single year, a hyphenated range (2010-2023), or a pipe-separated list (2015|2017|2019). Ranges are inclusive. Make required. Normalized before lookup, so Chevy resolves. Model required. Submodel optional. Blank means every submodel of that year, make and model. Note optional. Shown to the shopper on the product page and in the fitment table for that vehicle. \"Requires trimming\", \"Not with factory tow package\" and \"Front axle only\" belong here. Extra columns are ignored, so you can upload a supplier export unmodified as long as the six above exist by name. Header matching is case-insensitive. Uploading Fitment data → Sources → Add CSV Upload the file. Files up to 50 MB are accepted; larger exports should be split. Review the import summary Rows imported, rows skipped, and every reason. Unknown SKUs and unresolvable vehicles are listed individually — this is where you find out your supplier spells it F150. Reindex The mappings are resolved into the search index. Coverage on the Dashboard updates when it finishes. Re-uploading a file with the same name replaces that source's rows rather than appending, which is what you want for a monthly supplier refres"},{"t":"Google Sheets","g":"Fitment data","u":"/docs/data/google-sheets","d":"A live sheet the app re-reads on a schedule.","h":["Setup","Polling","Why teams pick this over CSV","Why teams move off it","Errors you'll actually see"],"b":"A Google Sheet is a CSV that maintains itself. Paste a link and the app re-reads the sheet on a schedule, so whoever owns the mapping can keep working in the tool they already use. Setup Format the sheet like the CSV Same six columns, same rules — see CSV upload for the exact grammar. Row one must be the header. Share it Either \"Anyone with the link → Viewer\", or share it with the service account address shown on the Sources screen if your workspace forbids link sharing. Paste the URL Fitment data → Sources → Add Google Sheet. Any normal sheet URL works; you don't need to publish to the web or build an export link. Pick the tab If the spreadsheet has several tabs, choose which one holds fitment. Polling The app re-reads the sheet on a schedule and re-resolves anything that changed. The cadence follows your plan's index cadence — six-hourly on Starter, and on the daily safety-net run for realtime plans, with a manual Sync now button on every plan. Sheets are polled, not pushed: Google does not tell us when a cell changes. If you've just made an urgent correction, press Sync now rather than waiting. Why teams pick this over CSV No re-upload ritual. The person who knows the fitment edits a row and it lands. Version history and comments are Google's problem, not ours. Unlimited sheet sources on every plan, including Starter. Why teams move off it Sheets get slow past roughly 50,000"},{"t":"Metafields & specs","g":"Fitment data","u":"/docs/data/metafields","d":"Per-product specs for facets and spec matching.","h":["Mapping your metafields","Examples across categories","The well-known wheel and tire keys","Units and formatting","Filters hide themselves"],"b":"Metafields do two jobs in WySync. They power filters on the collection page for every category, and — for wheels and tires with the Fitment Data add-on — they are what spec matching judges. Mapping your metafields Every store spells its metafields differently, so the app asks you once. Under Search & filters → Filters, each mapping declares: Namespace and key e.g. custom.wheeldiameter Display name what the shopper sees Type decimal, integer, single-value text, multi-value text, or boolean Role filter only, or filter plus spec matching Types matter because they decide the index field and the filter control: Type Index prefix Filter control Example Decimal specnum Range slider specnumwheeldiameter Integer specint Range slider specintoffset Text, single value specstr Dropdown or radio specstrfinish Text, multi value specstrs Checkboxes specstrsboltpattern Boolean specbool Toggle specboolrunflat Examples across categories Types matter more than names. A few real mappings: Category Metafield Type Becomes Suspension custom.liftheight Decimal specnumliftheight, range slider Brakes custom.rotordiameter Decimal specnumrotordiameter, range Brakes custom.padcompound Text, single specstrpadcompound, dropdown Lighting custom.beampattern Text, multi specstrsbeampattern, checkboxes Towing custom.hitchclass Text, single specstrhitchclass, dropdown Wipers custom.bladelength Integer specintblade"},{"t":"Vendor integrations","g":"Fitment data","u":"/docs/data/vendor-integrations","d":"Supplier feeds and what each adapter needs.","h":["How it works","Plan limits","What an adapter can and cannot do","Reading the sync report"],"b":"Vendor integrations pull fitment straight from a supplier, so the mapping arrives with the catalog rather than as a file someone remembers to export. How it works Sixteen suppliers are in the adapter registry. An integration is connected with your credentials — you already have an account with the supplier; we do not resell their data and we never see it for any shop but yours. Ask us to enable the supplier Fitment data → Sources → Vendors lists the registry. Adapters ship per merchant signup, so tell us which of your suppliers you want and we'll turn it on for your shop. Enter your credentials Usually an API key or an FTP account issued by the supplier. Stored encrypted, used only for your shop's sync. Match on SKU or MPN Most suppliers key on their own part number; the adapter maps it to your SKU, or to an MPN metafield if your SKUs are internal. Sync The first sync is full; later ones are incremental on the supplier's own cadence. Plan limits Plan Vendor integrations Starter 2 Growth 5 Pro All 16 standard adapters Enterprise Unlimited — including adapters we build for suppliers not in the registry That last row is the real Enterprise feature. If your best supplier has no API and mails you a fixed-width file — or an ACES XML export nobody else will touch — we will write the adapter for it as part of the plan. What an adapter can and cannot do It can bring product-to-vehicle m"},{"t":"WySync Fitment Data add-on","g":"Fitment data","u":"/docs/data/wysync-fitment-data","d":"Curated wheel and tire data, matched at query time.","h":["What you get","How a wheel is judged","Honest negatives","Turning it on","Where it stops"],"b":"The add-on switches the engine from look up a mapping to judge the specs. It costs $150/month on top of any plan, including Starter. This add-on covers wheels and tires. That is the curated data we own, and we are not going to imply otherwise. Brakes, suspension, lighting, exhaust, towing and everything else run entirely on the sources you connect — which is how most stores use the app, and why the add-on is optional on every plan. What you get 65,000 vehicles the same YMMS taxonomy every shop gets, now with dimensions attached. Wheel spec envelopes for each vehicle: bolt pattern, hub bore, and acceptable diameter, width and offset ranges. 1.2 million tire sizes with the data's own factory, guaranteed and aggressive tiers. Query-time matching evaluated per request across search, collections, the product verdict, the fits endpoint and the fitment table. How a wheel is judged For the shopper's vehicle and one product's specs, in order: Bolt pattern Canonicalised on both sides, then compared exactly. A mismatch is a definite does not fit — this is the one property with no tolerance. Hub bore The wheel's bore must be greater than or equal to the vehicle's hub. Larger is fine with a centring ring; smaller cannot physically seat. Diameter and width Must sit inside the vehicle's envelope. Offset Inside the envelope is a stock fit. Outside it but within tolerance is an aggressive fit —"},{"t":"Fitment editor","g":"Fitment data","u":"/docs/data/editor","d":"Per-SKU additions, exclusions, notes and universal flags.","h":["What you can do","Overlays survive everything","Working through the queue","Bulk edits","When to use the editor versus a source"],"b":"Supplier data is never perfect and tags go stale. The fitment editor is the overlay that sits on top of every source: it is applied after the union, which is what lets a single exclusion beat a feed that is confidently wrong. What you can do Add a vehicle a fit a source missed. Behaves exactly like a mapping from any other source. Exclude a vehicle remove a fit a source wrongly claims. Wins over every source, always. Flag universal cleaner, tools, hardware, anything that fits everything. Never filtered out by a vehicle, never marked as no-fit. Attach a note per SKU or per SKU-and-vehicle. Shown on the product page and in the fitment table: \"Requires trimming\", \"Not with factory tow package\", \"Front axle only\", \"Rubbing at full lock\". Overlays survive everything Edits are stored separately from source data and re-applied on every index run. Re-upload a CSV, resync a vendor, change plans — your corrections persist. This is the property that makes the editor safe to use as a daily tool rather than a last resort. Working through the queue The editor lists products by fitment status, so the useful workflow is: Filter to no fitment and sort by revenue. Fixing your top sellers first is worth more than fixing everything alphabetically. Filter to recently changed after a vendor sync to see what a supplier added or removed. Search a SKU directly when support forwards you a complaint. Eve"},{"t":"Normalization & synonyms","g":"Fitment data","u":"/docs/data/normalization","d":"Making “5x114.3” and “5x4.5” the same thing.","h":["Two kinds of rules","What's canonicalised automatically","Synonyms you control","Finding what needs a rule","Ranking is separate"],"b":"Real catalogs spell the same value five ways. Normalization is how \"5x114.3\", \"5×114.3mm\" and \"5x4.5″\" become one thing — and how \"Chevy\" finds \"Chevrolet\". Two kinds of rules Physics ships in code. Unit equivalences are not opinions: 5×114.3mm is 5×4.5″, 1 inch is 25.4mm, and no shop should have to configure that. Unit conversion, decimal tolerance and measurement parsing are baked in and identical for every shop. Vocabulary is yours. Make and model aliases, brand spellings, finish and compound names, and product-type synonyms are per-shop, stored as a list you can read and edit. Nothing about your catalog is decided by a black box you cannot inspect. The make and model rules are the ones that matter to every store, whatever you sell — they are what turn \"chevy silverado\" into a vehicle. What's canonicalised automatically Makes and models case, spacing, hyphens and punctuation, on both sides of every comparison. F150, F 150 and f-150 reach the same vehicle. Bolt pattern (wheels) separators (x, ×, -, /), units, and imperial/metric equivalence. Output looks like 5x114.3. Lengths inches as decimals; 20\", 20, 20.00 collapse to one value, whether that's a rim diameter, a lift height or a blade length. Offset (wheels) millimetres as signed integers; +35, 35mm, ET35 collapse to 35. Hub bore (wheels) millimetres as decimals. Tire size parsed into width, aspect and rim so 275/55R20 and"},{"t":"Vehicle taxonomy","g":"Fitment data","u":"/docs/data/vehicles","d":"The 65,000-vehicle YMMS table every shop gets free.","h":["What's in it","Why four levels","Submodel semantics","Vehicle IDs","Missing vehicles"],"b":"Every shop gets the vehicle taxonomy free, on every plan, including during the trial. It is the cascade behind every Year → Make → Model → Submodel dropdown in the app. What's in it About 65,000 vehicles , each a unique year-make-model-submodel combination with a stable numeric ID. Four levels only YMMS. Not engine, not bed length, not drivetrain. Shared and read-only one taxonomy for all shops, refreshed on a schedule. You do not maintain a vehicle list. Why four levels YMMS is the shape of the data WySync owns, and for most categories it is the right granularity — the submodel level is where trim-specific fitment usually lives. Some categories genuinely need more dimensions: bed length for bed liners and tonneau covers, drivetrain for driveshafts, engine code for intakes and headers, cab configuration for running boards. Those are modelled inside the vendor adapter that carries them rather than by widening the core schema for everyone — and in the meantime the honest answer is a per-SKU editor note (\"6.5ft bed only\"). If a dimension is structural to your catalog, it is an Enterprise conversation, not a setting. Submodel semantics The rule that catches people out: A mapping with a blank submodel applies to every submodel of that year, make and model. So 2019 Ford F-150 with no submodel covers XL, XLT, Lariat, King Ranch, Platinum, Limited and Raptor. That is usually what you w"},{"t":"Widgets overview","g":"Storefront widgets","u":"/docs/widgets/overview","d":"The suite, the placement model, and the shared vehicle state.","h":["The suite","One vehicle, shared","Where routing happens, and where it doesn't","Structure variants","Themes"],"b":"Nine widgets ship on every plan, whatever categories you sell. They are theme app extension blocks — Liquid plus vanilla JavaScript, no framework — that you place in Shopify's theme editor and remove the same way. The suite Widget Lives on What it does YMMS hero Homepage Picks the vehicle and routes into a filtered catalog Persistent bar Every page Shows and changes the active vehicle Garage Header or sticky Multiple saved vehicles per shopper Collection page Collections Replaces the native grid with a fitment-aware one Collection list Post-search The mapped collections for the chosen vehicle Search takeover Search Keyword search, autocomplete, SKU redirect, vehicle detection Product fits check Product page The verdict, in your words Fitment table Product page Everything this SKU fits Cart re-verification Cart Re-checks every line, optionally gates checkout Vehicle landing pages are the tenth surface — generated pages rather than a block you place. One vehicle, shared Every widget reads the same state, held in the browser and synced to the customer account when they're logged in. Change the vehicle in the bar and the product page verdict, the next collection grid and the cart all answer for the new vehicle — without a reload for anything already on screen. That state is loaded by the app embed, which is why the embed has to be enabled before any block behaves properly. Where ro"},{"t":"YMMS hero","g":"Storefront widgets","u":"/docs/widgets/ymms-hero","d":"The homepage vehicle picker and where it routes.","h":["Behaviour","Placement","Settings","Why it converts"],"b":"The front door. Four dropdowns — Year, Make, Model, Submodel — that cascade, and a button that sends the shopper into a catalog already filtered to their vehicle. Behaviour Each dropdown loads only values that exist below the one above it, so a shopper can never build a vehicle that doesn't exist. Options come from the taxonomy through the app proxy and are cached, so the second visitor of the day gets them instantly. Submodel is optional by default: a shopper who stops at model gets fitment for every submodel of that model. Make it required in the block settings if your catalog's fitment genuinely varies by trim. On submit the vehicle becomes the active vehicle and the shopper is routed to the block's redirect URL. Leave it blank and they go to /collections, which is where the collection list belongs. Placement Homepage, above the fold. It is a section block: theme editor → Add section → Apps → WySync YMMS hero. It also works on a landing page template if you run vehicle-specific campaigns. Horizon constrains section content to a centre column. The hero includes the override that lets it run edge-to-edge inside any section width, so you don't need a custom section wrapper. Settings Heading and helper copy \"Find parts for your vehicle\" is the default; use your own voice. Button label \"Shop my vehicle\", \"Find parts that fit\", \"Shop my F-150\" — whatever your customers say. Layout"},{"t":"Persistent vehicle bar","g":"Storefront widgets","u":"/docs/widgets/persistent-bar","d":"Carrying the vehicle across the whole store.","h":["Behaviour","Placement","Settings","Interaction with the other widgets"],"b":"Once a vehicle is chosen, the bar keeps it visible everywhere. It is the widget that makes the rest of the store feel like it remembers the shopper. Behaviour The bar appears only when a vehicle is active, showing the full YMMS with two actions: Change opens the shared vehicle selector in place. No navigation; the current page re-answers for the new vehicle. Clear deselects the active vehicle. The garage is untouched. Below 768px it collapses to a compact pill so it never eats the viewport on a phone. It can sit under the header or fixed to the bottom of the screen — bottom tends to win on mobile, where it sits near the thumb. Clearing removes the active selection only. Deleting saved vehicles is a separate, explicit action inside the garage. Nothing on the storefront wipes a customer's saved vehicles in one click, by design. Placement An app embed, not a section block — enable it under Theme editor → App embeds. That is what lets it render on every template, including ones you didn't think about, without adding a block to each. Settings Position: below header, or fixed bottom Background and text colour, with automatic contrast correction Whether to show the fitment count for the current page (\"248 products fit\") Copy for both actions Interaction with the other widgets The bar is the primary way a shopper corrects a mistake. When they change vehicle from the bar: The active veh"},{"t":"Garage","g":"Storefront widgets","u":"/docs/widgets/garage","d":"Multiple saved vehicles per shopper.","h":["Behaviour","Placement","Settings","The empty state matters"],"b":"Households have more than one vehicle. The garage lets a shopper save several and switch between them, so the truck's lift kit and the daily driver's brake pads are two clicks apart instead of two searches. Behaviour Save multiple vehicles added from the hero, the bar, or the garage itself. One active the one every other widget answers for. Switch sets the active vehicle and routes to the block's switch redirect (blank → /collections) so the new fitment applies immediately. Remove an explicit per-vehicle action, never a side effect of Clear. For a logged-out shopper the garage lives in the browser. For a logged-in customer it syncs to a customer metafield, so it follows them from the phone on the driveway to the laptop that evening. Placement Either a header icon with a badge, or a sticky button in a bottom corner. Both are block settings. On a theme whose header can't take an app block, the sticky variant is the fallback that always works. Settings Position: header, sticky bottom-left, sticky bottom-right Icon style and badge behaviour Panel heading and empty-state copy Switch redirect URL Maximum saved vehicles (default 5) The empty state matters A shopper who opens an empty garage should get an invitation, not a shrug. The default copy prompts them to add a vehicle and opens the selector inline. If your customers use language like \"my rig\" or \"the shop truck\", change it — th"},{"t":"Collection page","g":"Storefront widgets","u":"/docs/widgets/collection-page","d":"The Typesense-backed replacement for the native grid.","h":["What changes for the shopper","It renders on every collection","Placement","Settings","Filters","Mobile"],"b":"This is the widget that does the heavy lifting: it replaces your theme's native product grid with a Typesense-backed one that knows the shopper's vehicle. What changes for the shopper Fitment filtering on by default when a vehicle is active. A toggle lets them see everything. Real filters price, stock and your own metafield facets, applied server-side. Four sorts Best match (the ranking score), price ascending, price descending, alphabetical. Fast paging results come from the search index with a cache in front, not from Liquid looping over products. It renders on every collection The grid serves any collection, mapped or not. Unmapped handles get a humanized display name and the normal collection filter; Shopify's reserved all route gets no collection clause and searches your whole catalog. There is no 404 for an unmapped handle — mapping only decides what appears on the post-search list page. Placement On your collection template: remove or hide the theme's product grid section, then add the WySync collection block in its place. Keep the theme's own banner, description and breadcrumbs — the block replaces the grid, not the page. Removing the theme's grid section is reversible from the theme editor. Editing your theme's Liquid to delete it is not, and it makes rolling back harder than it needs to be. Settings Layout variant: standard grid, or grid with a left filter rail Produc"},{"t":"Collection list","g":"Storefront widgets","u":"/docs/widgets/collection-list","d":"The post-search landing surface.","h":["Why it exists","Mapped collections","Placement","Settings","When no vehicle is selected"],"b":"Where a shopper lands after picking a vehicle: the collections you sell for that vehicle, in your order, with your imagery. Why it exists Sending a shopper straight from \"2019 F-150\" into a grid of 4,000 parts is a worse experience than asking one more question. The list page is that question — wheels, brakes, suspension, lighting, protection — and it is also where you get to merchandise. Mapped collections Under Storefront → Collections you choose which collections appear here — typically your top-level categories: Add by handle or numeric ID Reorder by drag — the order shoppers see Image upload one or fall back to Shopify's collection image Toggle active hide seasonal collections without deleting the mapping Mapping affects this page only. The fitment-aware grid still renders on every collection in your store, mapped or not. Placement Add the block to the /collections (collection list) template. That is where the hero's blank redirect sends shoppers, so the two work together out of the box. Settings Heading, which can include the vehicle: \"Shop for your {vehicle}\" Layout variant: cards or compact tiles Columns per breakpoint Whether to show a per-collection count of fitting products \"312 parts fit your F-150\" converts better than a bare \"Suspension\". It costs one extra query per tile, which is cheap — but on a list of twenty collections it adds up. Map the collections that ma"},{"t":"Search takeover","g":"Storefront widgets","u":"/docs/widgets/search","d":"Keyword search, autocomplete, SKU redirect, vehicle detection.","h":["Four behaviours","Placement","Settings","Zero results","What gets measured"],"b":"The search takeover replaces Shopify's native search with the same index that powers collections — and teaches it to read vehicles out of ordinary language. Four behaviours Keyword search typo-tolerant relevance across title, vendor, SKU, product type and your spec fields. Autocomplete suggestions as the shopper types, with product thumbnails, prices and fitment chips. SKU redirect a query that exactly matches one SKU goes straight to that product page instead of a one-result list. Vehicle detection \"f150 6 inch lift kit\" resolves the F-150, sets it as the active vehicle, and searches the rest. That last one is the difference people notice. Shoppers type their vehicle into search boxes whether or not the box was designed for it; detecting it turns a zero-result query into the right result. Placement Two parts, and you usually want both: The results template — add the WySync search block to your /search template in place of the theme's results section. The autocomplete embed — the app embed that attaches to your theme's existing search inputs, including the one inside a header drawer or dialog. Several modern themes render search inside a <dialog element. The embed handles that case — but if autocomplete works on the search page and not in the header, that is the first thing to check with us. Settings Placeholder copy Number of suggestions, and whether to show collections and pa"},{"t":"Product fits check","g":"Storefront widgets","u":"/docs/widgets/product-fitment","d":"Fits / does not fit / unconfirmed on the product page.","h":["The three states","Copy templates","What \"unconfirmed\" should say","Notes","Add to cart"],"b":"The product page verdict. One sentence, in your words, that answers the question the shopper came to ask. The three states Fits \"This kit fits your 2024 Ford F-150 Lariat.\" Does not fit \"This kit does not fit your 2024 Ford F-150 Lariat.\" with a link to what does. Unconfirmed \"Fitment unconfirmed for your vehicle — call us and we'll check.\" Shown when nothing claims it and nothing can judge it. With no vehicle selected, the widget shows an inline selector instead: choosing a vehicle here answers immediately without leaving the page. Copy templates Every string is yours, with placeholders: The templates live in the app admin rather than the theme editor, because the same wording should appear in the cart and the fitment table. What the theme editor controls is how the block looks. What \"unconfirmed\" should say This is the highest-leverage sentence in the app. Default copy hedges; yours should route. Most shops turn unconfirmed into a lead: Not sure this fits your {vehicle}? Call us on 555-0142 — we fit these every day. There is a global no-fitment-data behaviour setting for shops still building coverage: show the unconfirmed message, hide the widget entirely, or show a generic prompt. Notes Notes attached in the editor render under the verdict for the matching vehicle — \"Requires trimming\", \"Not with factory tow package\", \"Rubbing at full lock with 35s\". These prevent more retur"},{"t":"Fitment table","g":"Storefront widgets","u":"/docs/widgets/fitment-table","d":"The full compatibility list for a SKU.","h":["What it shows","Year grouping","Placement","Settings","SEO"],"b":"The compatibility list for one SKU: every vehicle it fits, grouped and year-ranged, on the product page. What it shows Rows of years, make, model and submodel, collapsed into ranges — 2015–2026 Ford F-150 rather than twelve rows. Notes appear against the vehicles they apply to. The list is the union of two things: Mappings — everything your sources claim for this SKU. This is the whole list for most categories. Spec inverse matching — for wheels and tires with the Fitment Data add-on, every vehicle whose envelope this product's specs satisfy, even where no mapping exists. The second is why a wheel nobody ever mapped can still list hundreds of vehicles. Year grouping Ranges break where the fitment reason changes, not merely where years are contiguous. If a platform changed mid-generation — a new bolt pattern, a different caliper, a facelift that moved the bumper — you get two rows rather than one misleading range, which is exactly the case a shopper needs to see. Placement A section block on the product template, usually below the description or inside a tab. It is heavy content, so it belongs below the fold; the block ships collapsed by default with a \"Show all\" control. Settings Collapsed or expanded initially, and how many rows to show before \"Show all\" Whether to filter to the active vehicle's make first (useful for very wide-fitment SKUs) Column set: with or without submode"},{"t":"Cart re-verification","g":"Storefront widgets","u":"/docs/widgets/cart-fitment","d":"Re-checking the cart and gating checkout.","h":["Why a second check exists","What it does","The gate is a business decision","Placement","Matching lines to rows","Settings"],"b":"The last check before money changes hands. The cart widget re-verifies every line against the active vehicle and, if you want, refuses to open checkout until a problem is resolved. Why a second check exists The product page verdict was correct when the item went in. Then the shopper switched vehicles in the garage, or opened a saved cart from three weeks ago, or added from a link a friend sent. Fitment that only runs on the product page lets all of those reach checkout. What it does Per-line verdict each cart line shows the vehicle it was added for and its current status. Re-verification every line is re-checked against the active vehicle on cart load and after any vehicle change. Per-line vehicle change a shopper buying for two cars can correct one line without emptying the cart. Checkout gate optional. Blocks the checkout button while a line does not fit, with copy you write. The gate is a business decision Off by default. Turning it on prevents returns and prevents sales, and which matters more depends on your customer: Retail-heavy stores usually turn it on. A blocked checkout costs one conversation; a wrong lift kit or a wrong set of four wheels costs heavy freight, twice, plus a restock. Builder-heavy stores usually leave it off, because their customers deliberately buy things that don't \"fit\" by any envelope. A warning with an acknowledgement is the middle ground. Placem"},{"t":"Vehicle landing pages","g":"Storefront widgets","u":"/docs/widgets/vehicle-pages","d":"Indexable pages for every vehicle you carry.","h":["What gets generated","Manual or automatic","SEO templates","Year grouping","Deletion"],"b":"Indexable landing pages for the vehicles you carry parts for — \"2019 Ford F-150 Parts & Accessories\" — generated from your real collections rather than spun out of a template. What gets generated One page per vehicle you choose, each containing: An H1 and intro built from your SEO template The products that fit that vehicle, from real published collections A vehicle selector for shoppers who landed on the wrong page Internal links to the fitting collections Pages are created as real Shopify pages and published to your Online Store channel — which is why the app asks for the publications scope. Manual or automatic Starter create pages manually, one at a time, for the vehicles that matter most. Growth and above opt in to daily auto-generation. New vehicles that gain coverage get pages; vehicles that lose all coverage are cleanly deleted rather than left as thin content. Auto-generation is opt-in on every plan that has it. It is off until you turn it on, because publishing a thousand pages to someone's storefront without asking would be rude. SEO templates Title, meta description, H1 and intro copy are templates with variables: Available variables include {year}, {make}, {model}, {submodel}, {shop} and {productcount}, plus {boltpattern} and {hubbore} for wheel-focused pages. Year grouping Pages group years by platform, not by calendar. Consecutive years are combined only while the"},{"t":"Search overview","g":"Search & filters","u":"/docs/search/overview","d":"What replaces native search and how queries resolve.","h":["How a query resolves","Vehicle detection","What's searchable","Caching"],"b":"The search takeover replaces Shopify's native search with queries against your own index. Same engine as the collection grid, same fitment awareness, same speed. How a query resolves Normalize The raw query is lowercased, trimmed, and run through your synonym rules — so \"chevy\" finds Chevrolet and \"cat back\" finds cat-back. Look for a SKU An exact SKU match short-circuits everything and redirects straight to that product page. Staff and repeat buyers type SKUs; making them read a one-result page is a small insult. Look for a vehicle Tokens are tested against the taxonomy. \"f150 6 inch lift kit\" yields the F-150 plus the remaining terms. Search The leftover terms run against title, vendor, SKU, product type and your spec fields, typo-tolerant, ranked by the ranking tuner. Filter If a vehicle is active — whether pre-existing or detected in step 3 — fitment filtering applies unless the shopper turns it off. Vehicle detection Detection is conservative. It requires enough tokens to identify one vehicle unambiguously; \"ford\" alone sets nothing, because narrowing a search to every Ford ever made is not helpful. When a vehicle is detected you can either set it as active automatically, or show a confirm chip (\"Searching for your 2019 F-150 — not your vehicle?\"). The chip is slightly slower and considerably less annoying; it is the default. What's searchable Field Weight Notes Title High"},{"t":"Filters","g":"Search & filters","u":"/docs/search/filters","d":"Built-in filters plus your own metafield facets.","h":["Built-in","Merchant-defined","Smart show and hide","Ordering that works","Mobile"],"b":"Filters come in two kinds: the built-ins you always have, and the ones you define from your own metafields. Built-in Price a range slider bounded by the actual min and max of the current result set. Stock in stock, low stock, out of stock. The low-stock threshold is yours to set. Which options are preselected is configurable, and defaulting to \"in stock\" is usually right. Vendor dropdown or checkboxes depending on how many brands you carry. Fitment the \"fits my vehicle\" toggle, present whenever a vehicle is active. Merchant-defined Every mapped metafield can become a filter — lift height, rotor diameter, pad compound, beam pattern, hitch class, blade length, finish, whatever your catalog carries. For each one you set: Display name — what the shopper reads, not what the metafield is called Control type — checkbox, range, radio or dropdown Display order — drag to reorder Type drives what is possible: a decimal field can be a range, a multi-value text field wants checkboxes. Smart show and hide If no product in the current result set has a value for a field, that filter is not rendered. Browsing lighting does not show a Rotor Diameter filter with zero options, and a collection of universal accessories shows almost no filters at all. This is automatic and cannot be turned off, because a filter with no options is a dead end that makes a store look broken. Ordering that works The rul"},{"t":"Ranking tuner","g":"Search & filters","u":"/docs/search/ranking","d":"Weighting stock, price, popularity and fitment.","h":["The inputs","Sensible starting points","How to tune it without guessing","Sorts the shopper controls"],"b":"\"Best match\" is a score, and the score is yours to tune. The tuner is under Search & filters → Ranking. The inputs Text relevance how well the product matches the query terms. Dominant for keyword searches, irrelevant on a collection page with no query. Fitment confidence a mapped exact fit ranks above a spec-judged aggressive fit, which ranks above unconfirmed. Stock in-stock products above low-stock above out-of-stock. Usually the second-heaviest weight, because the fastest way to lose a sale is to rank something you cannot ship. Price off by default. Nudge it up to favour entry-price products, or down to favour margin. Popularity a rolling signal from views and add-to-carts in your own store. Manual boost a per-product override for the things you need to move. Sensible starting points Store type What to weight up High-turn retail Stock heavily, then popularity Brand-led boutique Manual boost on your house lines, then relevance Wide-catalog distributor Fitment confidence, then stock Clearing old inventory Manual boost on the specific SKUs — not a price weight How to tune it without guessing Pick five queries that matter — your top vehicle, your top brand, and a generic category term like \"lift kit\" or \"brake pads\". Note the top eight results for each before you touch anything. Change one weight. Re-run the same five queries. Changes apply immediately; there is no reindex. Tha"},{"t":"Zero-result rescue","g":"Search & filters","u":"/docs/search/zero-results","d":"What a shopper sees when nothing matches.","h":["The rescue ladder","How zero results are recorded","Reading the report"],"b":"Zero results is the most expensive page in a storefront: the shopper told you exactly what they wanted and you said no. WySync never renders an empty grid. The rescue ladder Tried in order, stopping at the first step that returns products: Relax fitment Show matching products that don't fit the active vehicle, clearly labelled. \"These match your search but not your 2019 F-150.\". Relax filters Drop the narrowest filter and retry, then the next. Relax the query Retry with the most restrictive term removed — useful when someone typed four words and three of them were adjectives. Popular for this vehicle Fall back to top products for the active vehicle. Not what they asked for, but buyable and relevant. Every rescue tells the shopper what happened. Silently returning different results than the ones requested is worse than an empty page, because it looks like the store cannot count. How zero results are recorded A search counts as zero-result when the underlying query returned nothing or the rescue ladder had to substitute popular products. Recording only the raw total would report near-zero forever, because the ladder almost always finds something to show. That distinction is why the analytics number is trustworthy — and it's the number to work from. Reading the report The zero-result list in analytics sorts by frequency. Entries fall into four buckets: Pattern What it means Fix A "},{"t":"How indexing works","g":"Indexing","u":"/docs/indexing/overview","d":"Bulk operations, webhooks, schedules and jobs.","h":["Full reindex","Realtime updates","Schedules by plan","Jobs","When to press Reindex"],"b":"Indexing is how your Shopify catalog becomes searchable, fitment-aware documents. Everything the storefront shows comes from the index; nothing shopper-facing queries Shopify directly. Full reindex A full run uses a Shopify bulk operation: the app asks for the entire catalog, Shopify assembles a file, and the app streams it into the index. Products, variants, prices, compare-at prices, inventory, vendor, type, collection memberships and metafields all come in one pass. Full runs happen on install, when you press Reindex, on your plan's schedule, and after changes that invalidate everything — a new metafield mapping, a new fitment source. Rough timing: a 40,000-SKU catalog in under ten minutes, scaling roughly linearly. Your storefront keeps serving the previous index throughout; the swap is atomic. Realtime updates From Growth up, the app subscribes to: Each webhook updates only the affected documents, so a price change is live in seconds. A daily full reindex runs behind it as a safety net for anything a dropped webhook missed. Starter subscribes to no webhooks at all — deliberately. Queueing webhooks a plan cannot act on adds complexity for no benefit; the six-hourly schedule is the whole mechanism. Schedules by plan Plan Webhooks Scheduled full reindex Manual Starter None Every 6 hours Yes Growth Yes Daily safety net Yes Pro Yes Daily safety net Yes Enterprise Yes Daily safe"},{"t":"Indexing troubleshooting","g":"Indexing","u":"/docs/indexing/troubleshooting","d":"Products missing, stale prices, failed jobs.","h":["A product isn't in search results","Prices or stock are stale","Fitment is missing on products that should have it","Products failed with a spec error","When to just reindex"],"b":"The four problems that account for nearly every indexing support ticket, in the order they occur. A product isn't in search results Is it active and published to the Online Store channel? Draft and unpublished products are not indexed. This is the answer roughly half the time. Did the last index run finish? Check Indexing for a completed job whose count is close to Shopify's product count. Is it in the failed list? Failures are listed with a reason — usually a spec metafield the indexer could not parse. Search for its exact SKU. If the SKU finds it but the title doesn't, that is a relevance problem, not an indexing one — see ranking. Prices or stock are stale On Starter, the index is up to six hours old by design; press Reindex or consider Growth if this matters commercially. On Growth and above, staleness means webhooks aren't arriving. Check the webhook status on the Indexing screen: it shows the last received event per topic. If a topic has gone quiet, reinstalling the app re-subscribes it — and tell us, because a silent webhook is our bug, not yours. Fitment is missing on products that should have it In order: Was there a reindex after the source was connected? Mapping sources resolve at index time. Did the source's import report skip those rows? Unknown SKUs and unresolved vehicles are listed individually. Does the vehicle resolve? Check that the make and model spellings i"},{"t":"Analytics","g":"Analytics","u":"/docs/analytics/overview","d":"Searches, vehicles, zero-result queries and coverage.","h":["What's recorded","The reports","Windows","Reading it honestly"],"b":"The dashboard answers three questions: what are shoppers searching for, which vehicles are they driving, and where is your fitment data letting them down. What's recorded Searches the query, whether a vehicle was detected, result count, and whether the rescue ladder fired. Suggestions autocomplete, counted separately so per-keystroke volume never swamps real searches. Vehicles which YMMS combinations were selected, and from which widget. Fitment coverage the share of indexed products with at least one vehicle mapped or judgeable. Zero results queries that returned nothing, or that only returned rescued results. Nothing customer-identifying is ever stored: no customer ID, no IP, no session token. Queries are scrubbed of email and phone shapes before they are written. That is why the GDPR customer redact webhook has no analytics work to do — there is nothing keyed to a person. The reports Overview — searches, vehicle selections and coverage over the window, with sparklines. The number to watch in week one is coverage. Searches — top queries, zero-result queries, and the share of searches where a vehicle was involved. A store where under a fifth of searches involve a vehicle usually has its hero below the fold. Vehicles — the vehicles your shoppers actually drive, ranked. This is the most commercially useful screen in the app: it is a stocking brief, a landing-page priority list a"},{"t":"Placing widgets in your theme","g":"Theme integration","u":"/docs/theme/placement","d":"App embeds, section blocks and the theme editor.","h":["Enable the app embed first","Where each block goes","The CLI cannot do this","Themes that need a nudge","After you save"],"b":"Widgets are added in Shopify's theme editor. There are two kinds — app embeds that load globally, and section blocks you place on specific templates. Enable the app embed first Theme editor → App embeds → enable WySync app bootstrap. It loads the shared vehicle state that every other widget reads. Nothing works properly without it, and half of \"the widget isn't doing anything\" tickets are this. Two other embeds are optional: the persistent bar and the search autocomplete attachment. Where each block goes Widget Template Notes YMMS hero Homepage (or a landing page) Above the fold Collection list Collection list (/collections) Where the hero's blank redirect lands Collection page Collection template Replace the theme's product grid Product fits check Product template Near the buy button Fitment table Product template Below the fold, or in a tab Cart re-verification Cart template Plus the embed if you use a cart drawer Garage App embed or header block Header if your theme allows app blocks there The CLI cannot do this Widget placement is theme-editor-only. Pushing config/settingsdata.json or templates/.json with the Shopify CLI silently strips shopify://apps/... block and embed references — the push succeeds and your widgets vanish. Reading theme JSON is fine; only writes are stripped. The Storefront → Widgets screen in the app exists for exactly this: it reads your published them"},{"t":"Styling & theme settings","g":"Theme integration","u":"/docs/theme/styling","d":"Colours, copy, layout variants and CSS hooks.","h":["What lives where","Inheritance","CSS hooks","Dark themes","Copy","RTL and translations"],"b":"Widgets are meant to look like your store, not like an app. Two layers of control: theme settings for anything visual, and CSS hooks when a setting isn't enough. What lives where Theme editor colours, labels, copy, layout variant, spacing, position. Per block, per theme, changeable by anyone who edits the theme. App admin logic that must be consistent everywhere: fitment copy templates, no-fitment-data behaviour, checkout gating. The split exists so that the \"does not fit\" sentence reads identically on the product page, in the cart and in the fitment table, no matter who edited the theme. Inheritance Widgets inherit your theme's font stack and heading styles by default, and respect its container widths. What they do not inherit is button styling — themes vary too much — so each block exposes its own button colour, radius and text colour, defaulting to your theme's accent. A contrast helper corrects foreground colours automatically when a chosen background would leave text unreadable. It is not a substitute for taste, but it stops the most common accessibility failure. CSS hooks Every block exposes stable class names prefixed wf-, plus custom properties you can override from your theme's stylesheet: Class names are treated as public API and don't change without a version note in the changelog. Overriding --wf- properties and top-level classes is supported. Reaching into nested e"},{"t":"Performance","g":"Theme integration","u":"/docs/theme/performance","d":"What we load, when, and what it costs you.","h":["What ships to the browser","Where the work happens","Core Web Vitals","Things that genuinely cost you","Measuring it properly"],"b":"A fitment app that slows a storefront down costs more than it earns. Here is exactly what WySync loads and what it costs. What ships to the browser No framework. Vanilla JavaScript, per widget. There is no React, no jQuery dependency, and no shared runtime bundle to download before anything renders. Per-widget assets. A product page loads the product fitment and table assets, not the collection grid's. Shopify's CDN. Theme app extension assets are served by Shopify, from the same edge as the rest of your theme. No blocking requests. Scripts are deferred; the vehicle state hydrates after first paint. Where the work happens Fitment filtering is an index intersection, executed server-side in the search engine, with Redis in front of the hot paths. Nothing is filtered in the browser and nothing loops over products in Liquid — which is the mechanism that makes tag-based fitment slow as a catalog grows. Typical fitment query time is well under 50 ms at the app, with cached queries considerably faster. Your storefront's total time is dominated by your theme and images, as it should be. Core Web Vitals LCP — the YMMS hero renders from Liquid on the server, so it counts toward LCP as content rather than arriving late as a layout shift. CLS — every widget reserves its space before hydration. The persistent bar is the one to watch: place it below the header rather than above it if your he"},{"t":"Migrating from Convermax","g":"Migrating","u":"/docs/migrate/from-convermax","d":"The switcher captures your resolved fitment first.","h":["What the switcher captures","The order to do it in","What does not transfer","Cost"],"b":"You can evaluate WySync without dismantling what you have. The migration switcher runs on your live storefront while your current fitment app is still installed, and captures the fitment it has already resolved. What the switcher captures Resolved fitment per SKU what your current app actually decided a product fits, across every category, including corrections your team made inside their editor. This is the valuable part: their resolved output, not their raw input. Native tags any fits…-shaped tags already on your products. Metafields spec fields already in your catalog. Vehicle vocabulary the make and model spellings in use, so synonyms can be seeded. Captured fitment becomes a normal WySync source and merges into the union like any other. Nothing is overwritten, and your existing app keeps working the whole time. The order to do it in Install WySync alongside No theme changes yet. It indexes your catalog in the background and starts your trial. Turn on the switcher In Fitment data → Sources. It reads what the incumbent resolves as your storefront is browsed, and from the fitment they expose per product. Let it run A few days of normal traffic covers the products that matter. You can also drive it deliberately across your top collections. Reconcile The admin shows three buckets: mappings both apps agree on, mappings only they have, and mappings only WySync found. The third bu"},{"t":"Migration checklist","g":"Migrating","u":"/docs/migrate/checklist","d":"The order to do it in, with rollback points.","h":["Before you start","Week one — run in parallel","Week two — build the storefront on the duplicate theme","Week two — verify","Cutover day","One week later"],"b":"The whole switch, in order, with the rollback point marked at every step. Before you start [ ] Duplicate your published theme. All widget work happens on the copy. [ ] Note your five most-searched vehicles and ten best-selling SKUs — this is your test set. [ ] Export your current app's analytics if you want to keep the history. [ ] Confirm who can edit the theme and who can install apps. Week one — run in parallel [ ] Install WySync. Confirm the first index finished and the count matches Shopify. [ ] Turn on the migration switcher. [ ] Connect any sources you already own — tags, a supplier CSV, a sheet. [ ] Map your metafields for filters. [ ] Check fitment coverage on the dashboard. Under 60% means keep going. Rollback: uninstall WySync. Nothing on your storefront has changed. Week two — build the storefront on the duplicate theme [ ] Enable the WySync app bootstrap embed. [ ] Add the YMMS hero to the homepage. [ ] Add the collection list block to /collections, and map your collections. [ ] Replace the product grid with the WySync collection block. [ ] Add the product fits check and fitment table. [ ] Add cart re-verification and decide on the checkout gate. [ ] Style everything to match the theme. Rollback: the duplicate is never published. Your live store is untouched. Week two — verify [ ] For each of your five test vehicles: hero → collection list → grid → product → cart. "},{"t":"Billing & plans","g":"Account","u":"/docs/account/billing","d":"Trials, upgrades, downgrades and what's enforced.","h":["The trial","Changing plans","What is actually enforced","Invoices and taxes","Cancelling"],"b":"Billing runs through Shopify. Charges appear on your Shopify invoice alongside your other apps; we never see or store a card. The trial Thirty days from install, on any plan. Nothing is charged during it, and uninstalling before it ends charges nothing at all. One deliberate detail: realtime indexing stays off while a trial is pending. A trial that hasn't converted is treated as the scheduled tier for indexing purposes. Paid capabilities start when the charge is accepted — which is also why your first realtime webhook arrives moments after you approve the subscription rather than on install day. Changing plans Upgrades apply immediately. Shopify prorates the difference, and the new limits take effect at once — including creating webhook subscriptions if you're moving into a realtime tier. Downgrades apply at the next renewal, so you never lose a connected source mid-month. If you're over the new plan's source limit at renewal, the admin asks you to choose which sources to keep rather than silently disconnecting one. What is actually enforced Promise Enforced by Price, trial length, plan name The Shopify subscription Indexing mode (scheduled vs realtime) Your shop's tier, reconciled on every subscription change Vendor and CSV source limits Checked when a source is added Fitment Data add-on An entitlement flag on your shop Catalog size guidance Not enforced — sales sizing only De"},{"t":"Fitment Data add-on","g":"Account","u":"/docs/account/data-addon","d":"Turning the curated data entitlement on.","h":["What switching it on does","Turning it on","Turning it off","Is it worth it for you?"],"b":"The Fitment Data add-on is $150 per month on top of any plan, including Starter. It covers wheels and tires only — every other category runs on the sources you connect, and most stores never need this. What switching it on does It sets an entitlement on your shop. From that moment, spec matching is evaluated at query time across search, collections, the product verdict, the fits endpoint and the fitment table. There is nothing to sync and no reindex needed — matching happens per request, so the change is visible immediately. Turning it on Ask us. It is granted per shop rather than purchased self-serve today; the Sources screen shows a contact link where a purchase flow will eventually be. When self-serve billing for add-on line items ships, it becomes a second subscription line on your Shopify invoice. We would rather say that plainly than build a fake button. Turning it off Also immediate. Products revert to the fitment your own sources provide, which usually means more unconfirmed verdicts and fewer honest negatives. Nothing you own is lost — your mappings, editor overlays and sources are untouched, because the add-on never wrote to them. Is it worth it for you? Yes, if: You sell wheels or tires, and have clean spec metafields (bolt pattern, diameter, width, offset, bore) but no product-to-vehicle mappings. Your suppliers give you good catalogs and poor fitment files. You wan"},{"t":"Support","g":"Account","u":"/docs/account/support","d":"Response times by plan and what to send us.","h":["By plan","What to send","Things you can check first","Custom development","Reporting a documentation bug"],"b":"Support is answered by the engineering team. The person who replies can open the file that caused your problem. By plan Plan Channel Target first response Starter Email 1 business day Growth Priority email Same business day Pro Priority email + phone Same business day, phone during business hours Enterprise Dedicated account manager Named contact, agreed in your onboarding Storefront-down issues jump the queue on every plan, including Starter. A broken store is not a tiering question. What to send The more of this you include, the faster the answer: Your store URL and whether the issue is on the live theme or a duplicate. A URL where it reproduces the exact collection, product or search page. The vehicle you selected, in full YMMS. What you expected and what happened. \"The verdict says unconfirmed but this lift kit definitely fits a 2019 F-150.\" A screenshot if it's visual, or the SKU if it's data. Things you can check first Most tickets resolve to one of these, and checking takes a minute: Is the app bootstrap embed enabled? Half of \"the widget does nothing\" is this. Did an index run finish since the change you made? Was the change made on the published theme or a duplicate? Has it been two minutes since an extension update? Deploys propagate with a short lag. Custom development Growth includes two hours a month, Pro five, Enterprise unlimited. Hours cover work specific to you"},{"t":"Privacy & GDPR","g":"Account","u":"/docs/account/privacy","d":"What we store, what we never store, and the webhooks.","h":["What we store","What we never store","Analytics and personal data","The GDPR webhooks","Where data lives","Isolation"],"b":"What the app stores, what it deliberately doesn't, and how the GDPR webhooks are handled. What we store Shop record your domain, plan, entitlements, install state and access token. Configuration mapped collections, filter mappings, normalization rules, ranking weights, copy templates. Fitment data you supply CSV rows, sheet contents, tag-derived mappings, editor overlays. Derived search documents the indexed representation of your catalog, in your own search collection. Aggregate analytics query strings, vehicle selections and counts, with no identifiers attached. What we never store Customer names, emails, phone numbers, addresses or payment details Order contents, totals or fulfilment data — only the line item properties the app itself wrote Payment information of any kind IP addresses or session tokens in analytics Your product data in any shared table — your index is yours alone The app requests readcustomers and writecustomers, but they reach exactly one field — the wysync.garage customer metafield that stores a logged-in shopper's saved vehicles. No other customer field is read or written, and no feature in the app uses one. readorders likewise reads only the line item properties the app itself wrote. Shopify classifies all three as Protected Customer Data; the app privacy policy sets out the scope-by-scope detail. Analytics and personal data Search analytics record the q"},{"t":"Uninstalling","g":"Account","u":"/docs/account/uninstall","d":"What is deleted, when, and what survives.","h":["Immediately","Within 48 hours","What is never touched","Before you go","Removing the blocks from your theme"],"b":"Uninstalling is one click in Shopify and needs no notice. Here is exactly what happens. Immediately The subscription is cancelled. No further charges, no cancellation fee. Our access token is revoked — the app can no longer read anything from your store. Webhook subscriptions are removed. The storefront widgets stop rendering. Their blocks remain in your theme as inert references until you remove them. Within 48 hours Shopify sends the shop/redact webhook. On receipt we delete: Your search index Your cached data Your configuration — mapped collections, filters, normalization rules, ranking weights, copy templates Your fitment data — uploaded CSV rows, sheet contents, editor overlays Your analytics history What is never touched Everything that was always yours: Products, variants, prices, inventory never modified. Tags including fits… tags. We read them; we never write them. Metafields read for specs, never written. Collections mapping is a WySync-side record; your collections are untouched. Orders line item properties written at checkout stay on the orders that carry them. Vehicle landing pages generated as real Shopify pages. They remain yours after uninstall; delete them yourself if you don't want them. Before you go If there's any chance you'll come back, or you want your work elsewhere: Export your fitment data. The editor exports every mapping and overlay as CSV — includin"},{"t":"Data formats","g":"Reference","u":"/docs/reference/formats","d":"Tag grammar, CSV columns, metafield keys, year ranges.","h":["Product tags","CSV and Google Sheets","Year ranges","Spec metafields","Canonical value formats"],"b":"Every grammar the app parses, in one place. Product tags Part Rules Examples Prefix fits, lowercase, required fits Years One year, or fromto inclusive 2018, 20102015 Make Lowercase, hyphens for spaces ford, land-rover Model Lowercase, hyphens for spaces and slashes f-150, civic Submodel Optional. Omit to match all submodels gt, trd-off-road The grammar is the same whatever the product is. Shopify caps products at 250 tags, so use CSV for wide-fitment SKUs. CSV and Google Sheets Column Required Format SKU Yes Matched to variant SKU, case-insensitive, trimmed Years Yes 2019, 2010-2023 (inclusive), or 2015 2017 2019 Make Yes Free text, normalized before lookup Model Yes Free text, normalized before lookup Submodel No Blank means every submodel Note No Shown to shoppers for that vehicle Header matching is case-insensitive; extra columns are ignored. Year ranges Input Expands to 2019 2019 2010-2023 2010 … 2023 inclusive 20102023 Same (tag form) 2015|2017|2019 2015, 2017, 2019 Spec metafields Any metafield becomes a typed spec field once mapped — see the per-category examples. These wheel and tire keys are recognised without a mapping step, because the Fitment Data add-on needs to read them: Any other metafield works after a mapping step. Index field prefixes by type: Type Prefix Filter control Decimal specnum Range Integer specint Range Text, single specstr Dropdown / radio Text, mu"},{"t":"Storefront API","g":"Reference","u":"/docs/reference/storefront-api","d":"The app proxy endpoints your theme can call.","h":["Vehicle cascade","Products in a collection","Search and suggestions","Fitment for one product","Vehicle specs","Rate limiting and caching"],"b":"The storefront widgets talk to the app through Shopify's app proxy. Requests leave from your own domain and arrive HMAC-signed, so these endpoints are available to your theme's own JavaScript too. Base path on your store: The proxy is signed by Shopify. There is no API key to manage and no way to authenticate as a specific customer — these endpoints serve catalog and fitment data only, never customer data. Vehicle cascade Products in a collection Returns products, the total, facet counts for the current result set, and whether the fitment filter was applied. sort accepts bestmatch, priceasc, pricedesc, titleasc. Search and suggestions Search responses include a detectedvehicle when one was found in the query, and a rescue object when the zero-result ladder substituted results. Fitment for one product verdict is one of fits, doesnotfit, unconfirmed. tier is present only when spec matching produced the answer. Vehicle specs Returns the vehicle's wheel specs — bolt pattern, hub bore and envelopes. Requires the Fitment Data add-on — without it, this endpoint returns 404, because those specs are the paid entitlement. Rate limiting and caching Endpoints are rate-limited per shop and cached in Redis. If you build something custom on top, cache client-side too and avoid firing a request per keystroke without debouncing — suggest is already debounced by our own widget. They exist so you"},{"t":"Order properties","g":"Reference","u":"/docs/reference/order-properties","d":"Vehicle and verdict on every line item.","h":["The properties","Where they show up","Putting them on a packing slip","Why it matters after the sale","Third-party apps"],"b":"When a shopper adds to cart with a vehicle selected, the vehicle and the verdict ride along as line item properties and survive into the order. The properties The leading underscore is Shopify's convention for hidden properties: they do not display to the customer during checkout, and they do not appear on the customer-facing order confirmation as line item options. Where they show up Cart page surfaced deliberately by the cart widget, in readable form. Shopify admin order view under each line item's details. Order confirmation email if your template renders line item properties. Packing slips if you add the property to your template. Order exports and the Admin API as normal line item properties. Putting them on a packing slip In Shopify's packing slip template: This is the single highest-value integration in the app for a warehouse. A picker who can see \"2024 Ford F-150 Lariat\" on the slip catches the mistakes nobody else will. Why it matters after the sale Returns — you can tell whether a customer was shown a fits verdict, or overrode a warning. Support — \"what did they buy it for\" is answered without a conversation. Analytics — vehicle-level revenue, exported from your own order data. Third-party apps Because these are standard line item properties, anything that reads them works: ShipStation, packing-slip apps, ERP connectors, order printers. Nothing WySync-specific needs "},{"t":"Plan limits","g":"Reference","u":"/docs/reference/plan-limits","d":"Exactly what each plan gates, and where it's enforced.","h":["The matrix","Where each limit lives","Not limited on any plan","When you exceed a limit"],"b":"Precisely what each plan gates, and where each limit is actually enforced. The matrix Starter Growth Pro Enterprise Price $99/mo $299/mo $549/mo $999/mo Vendor integrations 2 5 All 16 standard Unlimited, incl. custom-built CSV file sources 1 5 Unlimited Unlimited Sheets sources Unlimited Unlimited Unlimited Unlimited Metafield mappings Unlimited Unlimited Unlimited Unlimited Indexing Every 6h + manual Realtime + daily net Realtime Realtime Vehicle landing pages Manual Auto-generate + SEO templates Auto + templates Auto + templates Analytics window 30 days 90 days 90 days 90 days Catalog guidance 100k products 500k 1M Unlimited Custom development — 2 hrs/mo 5 hrs/mo Unlimited Support Email Priority email Priority email + phone Dedicated AM Where each limit lives Promise Enforced by Price, trial length, plan names The Shopify subscription Indexing mode Your shop's tier, reconciled whenever the subscription changes. A pending trial is treated as the scheduled tier — paid capability starts when the charge is accepted. Vendor and CSV source counts Checked when a source is added, keyed to your plan Fitment Data add-on (wheels & tires) An entitlement flag on your shop, off by default Analytics retention The rollup job's pruning window Catalog size Not enforced. Sizing guidance for support, not a meter. Dev hours, support tiers, free setup Service promises, not code Not limited on any "},{"t":"FAQ","g":"Reference","u":"/docs/reference/faq","d":"The questions merchants ask before they install.","h":["Product","Fitment data","Commercial","Operations"],"b":"The questions merchants ask before they install, answered the way we'd answer them on a call. Product Is this only for wheels and tires? No. It works for any product whose fitment depends on the vehicle — suspension, brakes, lighting, exhaust and intake, exterior and protection, towing, service parts. Spec fields in the index are typed rather than hard-coded, so your attributes behave the way wheel measurements do. The only wheel-and-tire-specific thing in the product is the optional data add-on. Does it work with my theme? Any Online Store 2.0 theme. Vintage themes can run the app embeds — persistent bar, garage, autocomplete — but not the section blocks. Will it slow my store down? It shouldn't, and on large collections it usually helps: fitment filtering happens in a search index, not in Liquid. See performance for what actually loads. Do I have to use all nine widgets? No. Three get a working funnel — the app embed, the hero and the collection page. Add the rest when you want them. Can I keep my theme's collection page? The WySync grid replaces the product grid only. Your banner, description, breadcrumbs and everything else stay as they are. Does it support VIN lookup? Not today. If VIN decoding is a requirement, say so — it's on the roadmap and your use case would shape it. What about non-Shopify platforms? The app is Shopify-only. Our separate data subscriptions are platf"}]