Designing an Algolia index is not the same as exporting your WooCommerce database. An index should contain the smallest useful search document for the experiences your store needs to support: product discovery, filtering, sorting, merchandising, autocomplete, or a combination of these.
For an agency, the right schema usually begins with the storefront search requirements rather than with the fields available in WordPress.
Start with the Search Experience
Before selecting fields, document what shoppers must be able to do. A typical WooCommerce catalog may require shoppers to:
- Search product names, SKUs, brands, categories, and selected specifications.
- Filter by price, stock status, brand, category, size, color, or other attributes.
- Sort by relevance, price, newest products, popularity, or rating.
- See product cards with the correct image, price, sale price, badges, and availability.
- Open the appropriate product or variation URL from the result.
Every field in the index should support one of these requirements. If a value is not searched, displayed, filtered, sorted, used for ranking, or required by the frontend, it probably does not belong in the record.
Include a Stable Object Identifier
Every Algolia record needs a stable objectID. For WooCommerce products, this is commonly the product ID, provided that the same identifier is used consistently during full imports and incremental updates.
{
"objectID": "product-4821",
"post_type": "product",
"product_id": 4821
}
Do not generate a random identifier every time a product is synchronized. Changing the identifier makes Algolia treat the item as a new record and can leave stale records behind. If products and variations are indexed separately, use an unambiguous convention such as product-4821 and variation-9174.
Store the Searchable Product Content
Include the product information that customers genuinely search for. Common fields include:
namefor the product title.skuand, where appropriate, manufacturer or supplier part numbers.brandor manufacturer.categoriesand selected category names.descriptionor a carefully prepared plain-text excerpt.short_descriptionwhen it contains useful product terminology.- Relevant product attributes such as material, compatibility, capacity, or model.
Searchable text should be clean and intentional. Do not send raw post content containing shortcodes, HTML markup, page-builder metadata, or internal notes. A normalized field can be useful when content is assembled from several WooCommerce sources.
{
"name": "Stainless Steel Pour-Over Kettle",
"brand": "Northstar",
"sku": "NS-KETTLE-900",
"categories": ["Coffee Equipment", "Kettles"],
"searchable_attributes": "Stainless Steel Pour-Over Kettle Northstar NS-KETTLE-900 Coffee Equipment Kettles"
}
The combined field is optional. In many implementations, Algolia searches individual attributes directly through searchableAttributes. Avoid duplicating large amounts of text simply because it is available in WordPress.
Separate Display Data from Search Data
The frontend usually needs more than the fields used to match a query. Include the minimum presentation data required to render a result without another request:
permalinkor a canonical product URL.thumbnailor an image URL suitable for the result card.priceand, when needed,regular_priceandsale_price.price_displayif currency formatting must be controlled by the backend.currencywhen the index serves more than one currency.availability_labelor another presentation value for stock messaging.- Small badges such as
on_sale,new_product, orfeatured.
Keep raw and formatted values distinct. A numeric price can support sorting and range filters, while a formatted value such as £129.00 is intended only for display.
{
"price": 129.0,
"regular_price": 149.0,
"currency": "GBP",
"price_display": "£129.00",
"on_sale": true,
"in_stock": true,
"thumbnail": "https://cdn.example.com/products/ns-kettle-900.jpg",
"permalink": "https://example.com/product/stainless-steel-pour-over-kettle/"
}
Model Facets as Consistent Values
Filtering depends on predictable data types and value formats. Fields used as facets should normally contain short strings, booleans, or arrays of values. Typical WooCommerce facet fields include:
categoriesbrandscolorssizesmaterialsin_stockon_saleproduct_type
Configure the corresponding fields in Algolia’s attributesForFaceting. For example, filterOnly(in_stock) is appropriate when a field is needed for filtering but should not be shown as a facet value. Use searchable facets only when shoppers need to search within a large facet list.
Normalize values before indexing. Decide whether colors are stored as navy, Navy, or localized labels, and apply that decision to every record. Do not use a human-readable label as the only value when the label may change; a stable taxonomy or attribute identifier can be stored alongside it.
Choose a Product and Variation Strategy
Variable products need an explicit indexing decision. There are three common approaches:
- Index the parent product only. Use this when shoppers select options on the product page and search results should not expose individual variations.
- Index every variation. Use this when each variation has its own SKU, price, stock status, image, or searchable identity.
- Index a parent record with aggregated variation data. Store values such as available sizes, colors, minimum price, and maximum price on the parent record.
Indexing both the parent and every variation without a clear frontend strategy often produces duplicate results. If variations are indexed, include enough context for the result to make sense and link directly to the correct selection when possible.
{
"objectID": "product-4821",
"parent_product_id": 4821,
"name": "Trail Running Jacket",
"available_colors": ["Black", "Blue"],
"available_sizes": ["S", "M", "L"],
"min_price": 89.0,
"max_price": 109.0,
"variation_count": 6
}
Include Ranking Signals Carefully
Algolia’s ranking configuration should handle textual relevance, but business signals can be useful as numeric attributes. Examples include:
popularity_scorebased on completed orders or product engagement.sales_count_30dfor a recent sales signal.rating_averageandrating_count.inventory_levelwhen stock quantity should influence merchandising.published_timestampfor a newest-first sort.
Only add these values when the business has agreed how they are calculated and updated. A ranking field that is stale, poorly normalized, or based on inconsistent product data can make results less trustworthy. Configure numeric attributes as ranking or sorting inputs deliberately rather than expecting Algolia to infer their purpose.
Support Multi-Store and Multi-Language Requirements
If the agency operates multiple storefronts, languages, currencies, or catalogs, decide whether these should use separate indices or shared records with filters. Separate indices are often simpler when product visibility, language, ranking, or currency differs substantially. A shared index may work when records can be reliably filtered by fields such as store_id, locale, and currency.
{
"store_id": "uk-main",
"locale": "en_GB",
"currency": "GBP",
"visible_in_store": true
}
Never rely on the frontend alone to hide records belonging to another store or customer group. Visibility constraints should be represented in the indexing strategy and enforced through secured search parameters or separate indices where appropriate.
Keep Sensitive and Volatile Data Out
An Algolia record may be returned to a browser, so do not include customer information, private supplier details, internal cost prices, unpublished editorial notes, or credentials. Be cautious with stock quantities, especially when exact inventory is commercially sensitive. A boolean availability field is often sufficient.
Also avoid putting rapidly changing fields into the index unless the business requires them in search results. Frequent updates increase synchronization work and can create visible inconsistencies between the index and WooCommerce. Product title, URL, price, stock status, taxonomy, images, and ranking signals usually deserve defined update rules; internal metadata usually does not.
Use a Practical Record Contract
A useful product record might look like this:
{
"objectID": "product-4821",
"product_id": 4821,
"name": "Stainless Steel Pour-Over Kettle",
"sku": "NS-KETTLE-900",
"brand": "Northstar",
"categories": ["Coffee Equipment", "Kettles"],
"description": "A gooseneck kettle with temperature control for precise pour-over brewing.",
"price": 129.0,
"regular_price": 149.0,
"currency": "GBP",
"in_stock": true,
"on_sale": true,
"rating_average": 4.7,
"rating_count": 86,
"thumbnail": "https://cdn.example.com/products/ns-kettle-900.jpg",
"permalink": "https://example.com/product/stainless-steel-pour-over-kettle/",
"published_timestamp": 1714521600
}
This is a starting point, not a universal schema. Test it against actual search queries, facet interactions, sort orders, result-card requirements, synchronization events, and index-size constraints. A well-designed index is focused, consistently typed, safe to expose, and directly aligned with the WooCommerce search experience.