Initial commit

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01F22Ms5Cxam5UHyxaCrtZzu
This commit is contained in:
Rami Bitar
2026-07-29 11:02:40 -04:00
co-authored by Claude Fable 5
commit f23332e42c
88 changed files with 7947 additions and 0 deletions
+61
View File
@@ -0,0 +1,61 @@
/**
* Shopify CDN image sizing helper (`hydrogen-image` skill).
*
* Hydrogen ships no Image component. Size Shopify CDN image URLs with this tiny
* helper and render plain `<img>`. Append CDN sizing params with
* `URL.searchParams` (never string-concat) so an existing query string is
* preserved. Only rewrite Shopify CDN hosts; pass third-party images (e.g. an
* Unsplash hero) through unchanged.
*
* CDN params: https://shopify.dev/docs/api/storefront/latest/input-objects/ImageTransformInput
*/
type ShopifyImageOptions = {
width?: number;
height?: number;
crop?: "center" | "top" | "bottom" | "left" | "right";
};
/** Shopify CDN hosts (and their subdomains) that may be rewritten. */
const SHOPIFY_CDN_HOSTS = ["cdn.shopify.com", "mock.shop"];
function isShopifyImageHost(hostname: string): boolean {
return SHOPIFY_CDN_HOSTS.some((host) => hostname === host || hostname.endsWith(`.${host}`));
}
/**
* Append Shopify CDN sizing params to `url`. Non-Shopify hosts and unparseable
* URLs are returned unchanged. Existing query params are preserved.
*/
export function shopifyImageUrl(url: string, options: ShopifyImageOptions = {}): string {
let parsed: URL;
try {
parsed = new URL(url);
} catch {
return url;
}
if (!isShopifyImageHost(parsed.hostname)) return url;
if (options.width) parsed.searchParams.set("width", String(options.width));
if (options.height) parsed.searchParams.set("height", String(options.height));
if (options.crop) parsed.searchParams.set("crop", options.crop);
return parsed.toString();
}
/**
* Build a 1x/2x DPR `srcset` for a Shopify CDN image. Each descriptor is sized
* via `shopifyImageUrl`. For width-descriptor srcsets (e.g. the home hero), use
* a custom srcset string instead — `sizes` is a no-op for DPR descriptors.
*/
export function srcSetFor(url: string, options: ShopifyImageOptions): string {
const oneX = shopifyImageUrl(url, options);
const twoX = shopifyImageUrl(url, {
...options,
width: options.width ? options.width * 2 : undefined,
height: options.height ? options.height * 2 : undefined,
});
return `${oneX} 1x, ${twoX} 2x`;
}