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. Centra to Klaviyo tags need a plugin contract

Centra to Klaviyo tags need a plugin contract

I invented a metric name and Klaviyo stayed silent. Match the plugin's event names and catalog product ids or your flows never fire and nobody gets mail.

Sander KorfPublished August 22, 20262 min read
centraklaviyo

This was a fashion storefront wired through Centra

Centra held products and orders. The Klaviyo plugin shipped the catalog and the events. Flows in Klaviyo were supposed to send receipts, shipping updates, back-in-stock. If a tag was one character off, Klaviyo did not error. It just never entered the flow.

What they would notice if it failed

An order in Centra. Nothing in the inbox. A back-in-stock email with a blank product block. A flow that looks "live" and a metric dropdown that does not list the name you invented in Slack.

The puzzle: we named the event ourselves

I wanted order_placed because that is how I name things. The Centra Klaviyo plugin sends Placed Order. Same for Confirmed Order, Shipping Update, Cancelled Order, Refunded Order, Created Account, Reset Password, Ordered Product. Resends are not aliases. They are Placed Order - resend.

The plugin docs are rude about this, in a useful way: when you create a flow, tags need to match the list. Close enough is a different metric. A different metric is a flow that never starts.

Catalog lookup is the second half of the same contract. Top-level catalog product id is the Centra display-item id. That is what Placed Order / Ordered Product put on the line items. Back-in-stock hands you a compound VariantID like 12366_SE_00_23400. If you feed the whole string to {% catalog %}, Klaviyo looks up a product that does not exist. You split on _ and take the first part. That is the contract, not a style choice.

{% with idParts=event.VariantId|split:"_" %}
	{% catalog idParts.0 %}
		<p>The {{ catalog_item.title }} is back.</p>
	{% endcatalog %}
{% endwith %}

Prices and names in the catalog metadata are keyed by currency and language. lookup:"default" is not Dutch. lookup:customer_lang is, if Centra synced Language onto the profile.

I stopped inventing metric names. I copied the plugin list. Flows started firing. The shopper got a product image instead of a hole. Boring. Correct.


Happy coding!
Sander