Blog
Practical notes on JavaScript tooling, module systems and the platform decisions behind the work we do
-
Hydrogen i18n: Put the Locale in the URL Path
Hydrogen i18n works best as a URL prefix: read the locale in context.ts, pass it as i18n, rename routes to ($locale) and let @inContext fill every query.
-
bfcache Not Working? Find the Blocker, Then Remove It
Your bfcache is not working because of one of a short list of blockers: how to read notRestoredReasons, test in DevTools and fix each one.
-
Shopify Checkout Upsell Extension: applyCartLinesChange
Build a Shopify checkout upsell extension that adds a product with applyCartLinesChange, checks canAddCartLine first and handles the error result.
-
Shopify Flow Trigger Extension: Fire It From Your App
Declare a Flow trigger in shopify.extension.toml, fire it with flowTriggerReceive, and add the lifecycle callback so you only send it where it is used.
-
Import JSON in ES Modules: with { type: 'json' }
Import JSON in ES modules with the with { type: 'json' } attribute: why Node and browsers require it, why named imports fail, and when require is better.
-
Shopify Returns API: returnCreate, Then returnProcess
The Shopify Returns API in Admin GraphQL 2026-10: open a return with returnCreate, then restock and refund it in one returnProcess call, not returnRefund.
-
Migrate Subscriptions to Shopify: Keep the Cards
Migrate subscriptions to Shopify without new card details: import Stripe, Braintree or Authorize.net cards by reference, then create the contracts.
-
React useEffectEvent: Latest Props Without Re-Running
useEffectEvent, stable since React 19.2, lets an Effect read the latest props and state without re-running; here is how it works and when not to use it.
-
Shopify Storefront API Product Filters: Pass input Back
Shopify Storefront API product filters come from collection.products: query filters, pass each value's input JSON back, and plan for the 25-filter cap.
-
Shopify Carrier Service API: Rates From Your Endpoint
Register a Shopify carrier service with carrierServiceCreate, answer the rate callback in subunits inside the timeout, and know when backup rates kick in.
-
Cloudflare Workflows: Steps, Sleep and waitForEvent
Cloudflare Workflows runs multi-step jobs as checkpointed, retried steps that can sleep for a year or wait for a webhook; here is how to write one safely.
-
Shopify Line Item Properties: From Form to Order
Shopify line item properties are name and value pairs sent with a cart line from the product form; here is how to collect, hide and read them.