When srcset maxes at 1000w on retina PDP
Sander Korf4 min read
PDP packshots looked soft on phones while cards stayed sharp. sizes asked for retina pixels but srcset stopped at 1000w. I matched candidates and one builder.
Read more
Writing
Notes on commerce engineering, AI integrations, and storefront patterns from production work. Next.js, Centra, Algolia, Convex, and what actually ships.
Sander Korf4 min read
PDP packshots looked soft on phones while cards stayed sharp. sizes asked for retina pixels but srcset stopped at 1000w. I matched candidates and one builder.
Read more
Sander Korf3 min read
A paid Centra order with a blank city blocked our warehouse export queue for eighty minutes. Classify bad address data as permanent and ack the event.
Read more
Sander Korf4 min read
Guided session app granted mic access then showed could not start listening. A stale Listen start called stop and bumped the generation counter past the winner.
Read more
Sander Korf4 min read
Creator marketplace cards reused a Stripe Tax preview total as payout. Creators read fee plus tax as cash in hand. Split payoutCents from the estimate.
Read more
Sander Korf3 min read
Fast models re-showed three resistance memories after move-on. Ended-step instructions must leave the system prompt, not fight a movedOn flag.
Read more
Sander Korf4 min read
On a Centra PDP, nested Embla carousels for card media and edge-bleed rails hit two traps. Use watchDrag on the parent; safe-area inset on the viewport.
Read more
Sander Korf3 min read
Fashion liveshow soft nav painted an empty shell. Instant Nav locks static HTML; next/dynamic with ssr false and cookie awaits blocked landmarks e2e needed.
Read more
Sander Korf3 min read
Liveshow detail refreshed after Sanity edits but the overview stayed stale for hours. Type-based GROQ lists never matched reference-only revalidation.
Read more
Sander Korf3 min read
BamHub liveshow webhooks sync into Sanity for a public listing. Sparse payloads left shows unpublished until I hydrated from the API or returned 503 for retry.
Read more
Sander Korf4 min read
Purge deleted transcript overlays while vendor STT still ran. Completion handlers recreated erased text. Missing overlay row means return, not upsert.
Read more
Sander Korf4 min read
STT under per-thread and global Convex buckets spent the thread token when global was empty. Check both before limit and throw so the mutation rolls back.
Read more
Sander Korf3 min read
Shopify PLPs showed wrong Size facets when variant overrides keyed a Map by null shopifyProductId on consolidated locales. Use the store Product GID.
Read more
Sander Korf4 min read
Fashion full-catalog rebuilds false-fail when replaceAllObjects hits fifty waitForTask polls. Large indexes need a custom copy, batch, and move path.
Read more
Sander Korf3 min read
Accept buttons in my Expo app worked everywhere except RN Modal dialogs. GestureDetector taps died silently because Modal renders outside the gesture root.
Read more
Sander Korf4 min read
On a fashion storefront mega menu, the dim layer snapped off when Base UI cleared the menu value at the start of the exit animation, not the end.
Read more
Sander Korf4 min read
Homepage prerender on a Centra Next.js build failed with 'Filling a cache during prerender timed out'. Nested use cache remote boundaries caused the hang.
Read more
Sander Korf4 min read
Soft-nav to a Convex movement catalog hit React error 441 when a redirect streamed in Suspense. I render the index and pick the default group client-side.
Read more
Sander Korf3 min read
PLP cards with optional Sanity video stay silent or flash wrong when autoPlay lives in SSR. I start muted loops in a client effect and respect reduced motion.
Read more
Sander Korf4 min read
Clinicians read Identify as a spreadsheet. Engineers cannot prove it ends. I seed Convex, write a pure reducer, and replay the sheet paths in Vitest first.
Read more
Sander Korf4 min read
When two movements stay yes after Compare, looping the same chips teaches nothing. I pause for a pick, hatch the losers, and end the run as a hypothesis.
Read more
Sander Korf4 min read
Identify is a clinician movement engine on Convex. Spreadsheet authors invent words weekly; lock metrics and actions to validators so the reducer stays boring.
Read more
Sander Korf4 min read
Gmail and Outlook strip video in campaigns. Ship a poster image with an optional play overlay and an outbound link baked at send time from the CMS.
Read more
Sander Korf3 min read
On a Centra fashion storefront, product cards broke when commerce API types leaked into JSX. Map to storefront DTOs and ban vendor imports in shop components.
Read more
Sander Korf3 min read
Collection pages stuck on loading after Instant Nav. Own PLP slugs per locale, 308 the rest, and skip waiting on empty query strings for the shell.
Read more
Sander Korf3 min read
Checkout country dropdowns rebuilt after hydration and emptied a test fill. Precompute localized names on the server before the form paints.
Read more
Sander Korf4 min read
A fashion PDP that greys out add to cart until size is picked looks broken. Validate on submit, show the hint after a miss, then focus the chips.
Read more
Sander Korf3 min read
A research product records session audio apart from chat. Deleting a thread must not wipe the rolls. Admin purge is terminal-only and deletes chunks first.
Read more
Sander Korf3 min read
Editors pin Shop the Look dots on the full photo. A tall cover crop on the product page slides those dots off the garment unless you remap them once.
Read more
Sander Korf4 min read
Colour swatches showed Black twice on a fashion PDP. Dedupe siblings on the URL you paint, then hide the picker when only one colour exists.
Read more
Sander Korf3 min read
Fashion size guides store measurements as rows. Shoppers need size rows on the product page. Flip the sheet once so the numbers match the layout.
Read more
Sander Korf4 min read
An out of stock size on a fashion product page should not grey out checkout. Flip the main button to a notify action and reuse one overlay for every sheet.
Read more
Sander Korf4 min read
Below-the-fold blocks on my Next.js site faded in with a client observer. Scroll timelines do the fade now, and older browsers just show the content.
Read more
Sander Korf4 min read
Crawlers never ran my blog JavaScript, so they got a shell with no article. I flattened the static pages and now test the HTML with scripts turned off.
Read more
Sander Korf4 min read
Preview and production disagreed because one push deployed twice. I let Vercel Git own the build, run Convex there, and keep Actions for tests only.
Read more
Sander Korf4 min read
Fashion PLP filter chips felt frozen when an observability hook retried on new object refs each render. Key the effect on queryID, not the results bag.
Read more
Sander Korf3 min read
I awaited a cached translation for a skip link and the Shopify homepage jumped. That one string now renders inside the section that already waits.
Read more
Sander Korf3 min read
Empty loading slots made my CMS blocks jump in late and wrecked layout stability. I now reserve height per section type and watch P95, not P75.
Read more
Sander Korf3 min read
On a fashion storefront PLP, merchandisers pin hero SKUs in Sanity CMS but Algolia ignores them when Groq filters on the desk title instead of the schema id.
Read more
Sander Korf3 min read
A fashion PLP runs Algolia InstantSearch in the browser. Only the search-only key belongs in client code; writes stay on the server with the admin key.
Read more
Sander Korf4 min read
Fashion checkout mail never arrives if you invent the event names. Copy the plugin tags and split the catalog id so receipts and restock emails actually send.
Read more
Sander Korf3 min read
Dutch shoppers got English order emails from Klaviyo. I now pick the storefront language on the server before the event leaves, not in a default template.
Read more
Sander Korf3 min read
A mobile app ships production and staging builds. Reusing production Universal Link hosts sends QA to the store app and makes staging reset links look broken.
Read more
Sander Korf4 min read
My Expo cloud build died hashing the JS bundle. I pinned Worklets Bundle Mode to false in Babel so Metro stopped hashing a graph I never asked for.
Read more
Sander Korf4 min read
An existing email is not always a blank account. I send a password reset when a login already exists, and I only set a password when none is on file.
Read more
Sander Korf8 min read
A live eToro book sat in cash while the allocator returned success. I force a deploy, park leftover in indexes, and name the fee skip when a rotate waits.
Read more
Sander Korf4 min read
A live eToro rebalance returned 200 with zero orders. Search 404ed on a bad fields list. I keep the ticker map and treat an empty 200 as the miss.
Read more
Sander Korf5 min read
A timeout on an eToro open can still fill the book. I treat open as at-most-once, leave closes on v1, and pick settlement from the matching leverage config.
Read more
Sander Korf4 min read
A live eToro book went to cash when the model rejected the prompt. I keep a fully invested core, cap tilts at ten points, and ignore a critic on idle cash.
Read more
Sander Korf4 min read
When a market is closed, I skip that eToro leg instead of retrying the whole Vercel Workflows step. A retry after a partial fill can buy the same names twice.
Read more
Sander Korf2 min read
I ship agentic Convex workflows and production Gen AI from Amsterdam. Posts cover what I build, who I work with, and what usually breaks in production.
Read more
Writing
Notes on commerce engineering, AI integrations, and storefront patterns from production work. Next.js, Centra, Algolia, Convex, and what actually ships.
Sander Korf4 min read
PDP packshots looked soft on phones while cards stayed sharp. sizes asked for retina pixels but srcset stopped at 1000w. I matched candidates and one builder.
Read more
Sander Korf3 min read
A paid Centra order with a blank city blocked our warehouse export queue for eighty minutes. Classify bad address data as permanent and ack the event.
Read more
Sander Korf4 min read
Guided session app granted mic access then showed could not start listening. A stale Listen start called stop and bumped the generation counter past the winner.
Read more
Sander Korf4 min read
Creator marketplace cards reused a Stripe Tax preview total as payout. Creators read fee plus tax as cash in hand. Split payoutCents from the estimate.
Read more
Sander Korf3 min read
Fast models re-showed three resistance memories after move-on. Ended-step instructions must leave the system prompt, not fight a movedOn flag.
Read more
Sander Korf4 min read
On a Centra PDP, nested Embla carousels for card media and edge-bleed rails hit two traps. Use watchDrag on the parent; safe-area inset on the viewport.
Read more
Sander Korf3 min read
Fashion liveshow soft nav painted an empty shell. Instant Nav locks static HTML; next/dynamic with ssr false and cookie awaits blocked landmarks e2e needed.
Read more
Sander Korf3 min read
Liveshow detail refreshed after Sanity edits but the overview stayed stale for hours. Type-based GROQ lists never matched reference-only revalidation.
Read more
Sander Korf3 min read
BamHub liveshow webhooks sync into Sanity for a public listing. Sparse payloads left shows unpublished until I hydrated from the API or returned 503 for retry.
Read more
Sander Korf4 min read
Purge deleted transcript overlays while vendor STT still ran. Completion handlers recreated erased text. Missing overlay row means return, not upsert.
Read more
Sander Korf4 min read
STT under per-thread and global Convex buckets spent the thread token when global was empty. Check both before limit and throw so the mutation rolls back.
Read more
Sander Korf3 min read
Shopify PLPs showed wrong Size facets when variant overrides keyed a Map by null shopifyProductId on consolidated locales. Use the store Product GID.
Read more
Sander Korf4 min read
Fashion full-catalog rebuilds false-fail when replaceAllObjects hits fifty waitForTask polls. Large indexes need a custom copy, batch, and move path.
Read more
Sander Korf3 min read
Accept buttons in my Expo app worked everywhere except RN Modal dialogs. GestureDetector taps died silently because Modal renders outside the gesture root.
Read more
Sander Korf4 min read
On a fashion storefront mega menu, the dim layer snapped off when Base UI cleared the menu value at the start of the exit animation, not the end.
Read more
Sander Korf4 min read
Homepage prerender on a Centra Next.js build failed with 'Filling a cache during prerender timed out'. Nested use cache remote boundaries caused the hang.
Read more
Sander Korf4 min read
Soft-nav to a Convex movement catalog hit React error 441 when a redirect streamed in Suspense. I render the index and pick the default group client-side.
Read more
Sander Korf3 min read
PLP cards with optional Sanity video stay silent or flash wrong when autoPlay lives in SSR. I start muted loops in a client effect and respect reduced motion.
Read more
Sander Korf4 min read
Clinicians read Identify as a spreadsheet. Engineers cannot prove it ends. I seed Convex, write a pure reducer, and replay the sheet paths in Vitest first.
Read more
Sander Korf4 min read
When two movements stay yes after Compare, looping the same chips teaches nothing. I pause for a pick, hatch the losers, and end the run as a hypothesis.
Read more
Sander Korf4 min read
Identify is a clinician movement engine on Convex. Spreadsheet authors invent words weekly; lock metrics and actions to validators so the reducer stays boring.
Read more
Sander Korf4 min read
Gmail and Outlook strip video in campaigns. Ship a poster image with an optional play overlay and an outbound link baked at send time from the CMS.
Read more
Sander Korf3 min read
On a Centra fashion storefront, product cards broke when commerce API types leaked into JSX. Map to storefront DTOs and ban vendor imports in shop components.
Read more
Sander Korf3 min read
Collection pages stuck on loading after Instant Nav. Own PLP slugs per locale, 308 the rest, and skip waiting on empty query strings for the shell.
Read more
Sander Korf3 min read
Checkout country dropdowns rebuilt after hydration and emptied a test fill. Precompute localized names on the server before the form paints.
Read more
Sander Korf4 min read
A fashion PDP that greys out add to cart until size is picked looks broken. Validate on submit, show the hint after a miss, then focus the chips.
Read more
Sander Korf3 min read
A research product records session audio apart from chat. Deleting a thread must not wipe the rolls. Admin purge is terminal-only and deletes chunks first.
Read more
Sander Korf3 min read
Editors pin Shop the Look dots on the full photo. A tall cover crop on the product page slides those dots off the garment unless you remap them once.
Read more
Sander Korf4 min read
Colour swatches showed Black twice on a fashion PDP. Dedupe siblings on the URL you paint, then hide the picker when only one colour exists.
Read more
Sander Korf3 min read
Fashion size guides store measurements as rows. Shoppers need size rows on the product page. Flip the sheet once so the numbers match the layout.
Read more
Sander Korf4 min read
An out of stock size on a fashion product page should not grey out checkout. Flip the main button to a notify action and reuse one overlay for every sheet.
Read more
Sander Korf4 min read
Below-the-fold blocks on my Next.js site faded in with a client observer. Scroll timelines do the fade now, and older browsers just show the content.
Read more
Sander Korf4 min read
Crawlers never ran my blog JavaScript, so they got a shell with no article. I flattened the static pages and now test the HTML with scripts turned off.
Read more
Sander Korf4 min read
Preview and production disagreed because one push deployed twice. I let Vercel Git own the build, run Convex there, and keep Actions for tests only.
Read more
Sander Korf4 min read
Fashion PLP filter chips felt frozen when an observability hook retried on new object refs each render. Key the effect on queryID, not the results bag.
Read more
Sander Korf3 min read
I awaited a cached translation for a skip link and the Shopify homepage jumped. That one string now renders inside the section that already waits.
Read more
Sander Korf3 min read
Empty loading slots made my CMS blocks jump in late and wrecked layout stability. I now reserve height per section type and watch P95, not P75.
Read more
Sander Korf3 min read
On a fashion storefront PLP, merchandisers pin hero SKUs in Sanity CMS but Algolia ignores them when Groq filters on the desk title instead of the schema id.
Read more
Sander Korf3 min read
A fashion PLP runs Algolia InstantSearch in the browser. Only the search-only key belongs in client code; writes stay on the server with the admin key.
Read more
Sander Korf4 min read
Fashion checkout mail never arrives if you invent the event names. Copy the plugin tags and split the catalog id so receipts and restock emails actually send.
Read more
Sander Korf3 min read
Dutch shoppers got English order emails from Klaviyo. I now pick the storefront language on the server before the event leaves, not in a default template.
Read more
Sander Korf3 min read
A mobile app ships production and staging builds. Reusing production Universal Link hosts sends QA to the store app and makes staging reset links look broken.
Read more
Sander Korf4 min read
My Expo cloud build died hashing the JS bundle. I pinned Worklets Bundle Mode to false in Babel so Metro stopped hashing a graph I never asked for.
Read more
Sander Korf4 min read
An existing email is not always a blank account. I send a password reset when a login already exists, and I only set a password when none is on file.
Read more
Sander Korf8 min read
A live eToro book sat in cash while the allocator returned success. I force a deploy, park leftover in indexes, and name the fee skip when a rotate waits.
Read more
Sander Korf4 min read
A live eToro rebalance returned 200 with zero orders. Search 404ed on a bad fields list. I keep the ticker map and treat an empty 200 as the miss.
Read more
Sander Korf5 min read
A timeout on an eToro open can still fill the book. I treat open as at-most-once, leave closes on v1, and pick settlement from the matching leverage config.
Read more
Sander Korf4 min read
A live eToro book went to cash when the model rejected the prompt. I keep a fully invested core, cap tilts at ten points, and ignore a critic on idle cash.
Read more
Sander Korf4 min read
When a market is closed, I skip that eToro leg instead of retrying the whole Vercel Workflows step. A retry after a partial fill can buy the same names twice.
Read more
Sander Korf2 min read
I ship agentic Convex workflows and production Gen AI from Amsterdam. Posts cover what I build, who I work with, and what usually breaks in production.
Read more