Sander Korf
  • Portfolio
  • Resume

Sander Korf

Dutch Full Stack AI Engineer helping businesses cut costs through intelligent automation. 13+ years turning expensive manual processes into systems that work 24/7. Based in Amsterdam, available for freelance projects.

Navigation

  • Portfolio
  • Resume

Legal

  • Cookies
  • Privacy Policy
  • Terms and Conditions

Blog

Algolia

  • Algolia InstantSearch INP and object identity
  • Algolia merch by Sanity _type, not title
  • Algolia InstantSearch search key, not admin

Vercel

  • Next.js empty Suspense fallbacks wreck CLS P95
  • Vercel Workflows: skip closed eToro legs

eToro

  • eToro deploy vs rotate: idle cash not rotate
  • eToro search 404: query fields, not ticker
  • eToro v2 opens at-most-once, settlement
  • eToro LLM overlay ±10pp: critic cannot veto

Next.js

  • next-intl useTranslate skip links above fold
  • next-intl owns Klaviyo nl-NL email copy

Firebase & Expo

  • Staging deep links must not hijack production
  • Turn off Worklets Bundle Mode for EAS SHA-1
  • Reclaim Firebase orphan without password wipe

Centra & Klaviyo

  • Centra to Klaviyo tags need a plugin contract

About

  • Full Stack AI Engineer in Amsterdam

© 2026 Sander Korf. All rights reserved

94719489

  • Applied AI
  1. Home
  2. Blog
  3. Algolia merch by Sanity _type, not title

Algolia merch by Sanity _type, not title

I filtered Sanity by the pretty type label and every merchandising rule vanished. Filter on the schema id instead and pins show up on the PLP again.

Sander KorfPublished August 26, 20262 min read
algoliasanitynextjsshopify

This was a clothing storefront with Sanity merchandising

Next.js. Shopify catalog in Algolia. Sanity CMS documents for pins, hides, boosts. InstantSearch rendered whatever the index had after the merch pass. If the Groq filter looked at the pretty type name, Sanity returned zero documents and Algolia got a no-op.

What they would notice if it failed

A merchandiser pinned a hero SKU in Sanity. The PLP ignored it. They edited the document again. Still ignored. They blamed InstantSearch. InstantSearch was fine. The query never loaded the rule.

The puzzle: the label is not the id

Sanity schema types have an id and a title. title is what the desk shows: "Collection merchandising." id is what Groq sees: collectionMerch, or whatever you registered. I filtered *[(_type == "Collection merchandising") && locale == $locale]. Zero hits. Always. The documents sat right there in the desk.

_type is the schema id. Always. The title can change because someone wanted a nicer label. The id is the contract.

*[_type == "collectionMerch" && locale == $locale]{
	_id,
	collectionHandle,
	pinned[]->{ sku },
	hidden[]->{ sku }
}

Then the server writes those pins onto the Algolia index (or a replica) with the admin client. InstantSearch on the storefront keeps using the search-only key and never talks to Sanity.

If you need to show the label in the UI, read title from the schema, not from _type. If you need to query, you want the id you put in defineType({ name: 'collectionMerch' }). That name is _type. The string in the desk heading is decoration.

I stopped matching English. I matched the schema. Pins showed up. Merchandisers stopped pinging me.


Happy coding!
Sander