Summary
The Intelligent Search PLP loader (vtex/inline-loaders/productListingPage.ts) resolves category facets from the URL path only when no selectedFacets are supplied. The two steps that make that resolution correct — getValidPageTypes and the pageTypes → facets mapping — are private to that module, so any site that needs to inject its own facets (e.g. delivery / pickup facets) must re-implement category resolution and can silently get it wrong.
Details
// productListingPage.ts
let facets = cmsSelectedFacets?.length ? [...cmsSelectedFacets] : [];
// ... extract filter.* from URL ...
if (facets.length === 0 && !query && isValidPLPPath(__pagePath)) {
const allPageTypes = await pageTypesFromPath(__pagePath);
pageTypes = getValidPageTypes(allPageTypes); // <-- private; drops NotFound etc.
facets = filtersFromPageTypes(pageTypes);
}
Once a site supplies a non-empty selectedFacets, the loader uses it verbatim and never resolves the page-type categories. So a site that wants to add facets (zip-code / coordinates / shipping / pickupPoint) must pre-resolve the category itself with filtersFromPageTypes(pageTypesFromPath(path)).
The trap: pageTypeToMapParam(type, index) derives the key from the array index (category-${index + 1}). Upstream calls getValidPageTypes (which drops NotFound, etc.) before filtersFromPageTypes. A site that omits that filter leaves a mid-path NotFound in the array, inflating the index of the following SubCategory and producing a non-contiguous sequence:
category-1/escolar/category-3/<leaf> ← skips category-2
VTEX IS matches that to 0 products (verified live). getValidPageTypes / VALID_PAGE_TYPES are not exported, so the site has to hand-mirror the set, which will drift if upstream changes it.
Secondary concern (please confirm)
filtersFromPageTypes returns { key, value: slugify(page.name) } for every page type, including Collection / Cluster whose key is productClusterIds. VTEX IS expects productClusterIds to be the numeric cluster id, not a slug — productClusterIds/<slug> matches 0 results. deco-cx/apps used the cluster id. If this is real, Collection/Cluster PLPs return 0 even without any site facet injection.
Suggested fix
Export a reusable resolver so sites don't re-implement (and drift from) the filtering, e.g.:
export async function resolveSelectedFacetsFromPath(
pagePath: string,
): Promise<{ facets: SelectedFacet[]; pageTypes: PageType[] }>;
that internally runs getValidPageTypes + filtersFromPageTypes. Sites injecting extra facets would call it and merge, instead of re-deriving the category facets. Also fix the Collection/Cluster value to use the cluster id.
Environment
@decocms/apps (apps-start), VTEX integration
- Files:
vtex/loaders/intelligentSearch/productListingPage.ts (getValidPageTypes, VALID_PAGE_TYPES), vtex/client.ts (filtersFromPageTypes, pageTypeToMapParam, toFacetPath)
Summary
The Intelligent Search PLP loader (
vtex/inline-loaders/productListingPage.ts) resolves category facets from the URL path only when noselectedFacetsare supplied. The two steps that make that resolution correct —getValidPageTypesand thepageTypes → facetsmapping — are private to that module, so any site that needs to inject its own facets (e.g. delivery / pickup facets) must re-implement category resolution and can silently get it wrong.Details
Once a site supplies a non-empty
selectedFacets, the loader uses it verbatim and never resolves the page-type categories. So a site that wants to add facets (zip-code / coordinates / shipping / pickupPoint) must pre-resolve the category itself withfiltersFromPageTypes(pageTypesFromPath(path)).The trap:
pageTypeToMapParam(type, index)derives the key from the array index (category-${index + 1}). Upstream callsgetValidPageTypes(which dropsNotFound, etc.) beforefiltersFromPageTypes. A site that omits that filter leaves a mid-pathNotFoundin the array, inflating the index of the followingSubCategoryand producing a non-contiguous sequence:VTEX IS matches that to 0 products (verified live).
getValidPageTypes/VALID_PAGE_TYPESare not exported, so the site has to hand-mirror the set, which will drift if upstream changes it.Secondary concern (please confirm)
filtersFromPageTypesreturns{ key, value: slugify(page.name) }for every page type, includingCollection/Clusterwhose key isproductClusterIds. VTEX IS expectsproductClusterIdsto be the numeric cluster id, not a slug —productClusterIds/<slug>matches 0 results. deco-cx/apps used the cluster id. If this is real, Collection/Cluster PLPs return 0 even without any site facet injection.Suggested fix
Export a reusable resolver so sites don't re-implement (and drift from) the filtering, e.g.:
that internally runs
getValidPageTypes+filtersFromPageTypes. Sites injecting extra facets would call it and merge, instead of re-deriving the category facets. Also fix theCollection/Clustervalue to use the cluster id.Environment
@decocms/apps(apps-start), VTEX integrationvtex/loaders/intelligentSearch/productListingPage.ts(getValidPageTypes,VALID_PAGE_TYPES),vtex/client.ts(filtersFromPageTypes,pageTypeToMapParam,toFacetPath)