@shopify/hydrogen 2026.4.4 → 2026.10.0-preview.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +73 -13
- package/bin/hydrogen.mjs +7 -0
- package/dist/cli/index.mjs +330 -0
- package/dist/client/client.d.mts +34 -0
- package/dist/client/client.mjs +193 -0
- package/dist/client/client.mjs.map +1 -0
- package/dist/client/errors.d.mts +48 -0
- package/dist/client/errors.mjs +52 -0
- package/dist/client/errors.mjs.map +1 -0
- package/dist/client/index.d.mts +4 -0
- package/dist/client/types.d.mts +147 -0
- package/dist/core/analytics/cart-tracker.d.mts +8 -0
- package/dist/core/analytics/cart-tracker.mjs +144 -0
- package/dist/core/analytics/cart-tracker.mjs.map +1 -0
- package/dist/core/analytics/events.d.mts +15 -0
- package/dist/core/analytics/events.mjs +15 -0
- package/dist/core/analytics/events.mjs.map +1 -0
- package/dist/core/analytics/index.d.mts +3 -0
- package/dist/core/analytics/types.d.mts +143 -0
- package/dist/core/analytics/utils/flatten-connection.d.mts +19 -0
- package/dist/core/analytics/utils/flatten-connection.mjs +25 -0
- package/dist/core/analytics/utils/flatten-connection.mjs.map +1 -0
- package/dist/core/cache/cache-status.mjs +17 -0
- package/dist/core/cache/cache-status.mjs.map +1 -0
- package/dist/core/cache/fetch-with-cache.d.mts +43 -0
- package/dist/core/cache/fetch-with-cache.mjs +188 -0
- package/dist/core/cache/fetch-with-cache.mjs.map +1 -0
- package/dist/core/cache/key.d.mts +6 -0
- package/dist/core/cache/key.mjs +27 -0
- package/dist/core/cache/key.mjs.map +1 -0
- package/dist/core/cache/run-with-cache.d.mts +36 -0
- package/dist/core/cache/run-with-cache.mjs +114 -0
- package/dist/core/cache/run-with-cache.mjs.map +1 -0
- package/dist/core/cache/store.d.mts +19 -0
- package/dist/core/cache/store.mjs +62 -0
- package/dist/core/cache/store.mjs.map +1 -0
- package/dist/core/cache/strategies.d.mts +39 -0
- package/dist/core/cache/strategies.mjs +70 -0
- package/dist/core/cache/strategies.mjs.map +1 -0
- package/dist/core/cart/actions.d.mts +50 -0
- package/dist/core/cart/actions.mjs +240 -0
- package/dist/core/cart/actions.mjs.map +1 -0
- package/dist/core/cart/attach-quantity-input.d.mts +5 -0
- package/dist/core/cart/attach-quantity-input.mjs +17 -0
- package/dist/core/cart/attach-quantity-input.mjs.map +1 -0
- package/dist/core/cart/buyer-identity-sync.d.mts +23 -0
- package/dist/core/cart/buyer-identity-sync.mjs +9 -0
- package/dist/core/cart/buyer-identity-sync.mjs.map +1 -0
- package/dist/core/cart/cart.d.mts +32 -0
- package/dist/core/cart/cart.mjs +1687 -0
- package/dist/core/cart/cart.mjs.map +1 -0
- package/dist/core/cart/cookie.d.mts +5 -0
- package/dist/core/cart/cookie.mjs +28 -0
- package/dist/core/cart/cookie.mjs.map +1 -0
- package/dist/core/cart/form.d.mts +130 -0
- package/dist/core/cart/form.mjs +75 -0
- package/dist/core/cart/form.mjs.map +1 -0
- package/dist/core/cart/get-cart.d.mts +25 -0
- package/dist/core/cart/get-cart.mjs +32 -0
- package/dist/core/cart/get-cart.mjs.map +1 -0
- package/dist/core/cart/index.d.mts +10 -0
- package/dist/core/cart/quantity.d.mts +10 -0
- package/dist/core/cart/quantity.mjs +14 -0
- package/dist/core/cart/quantity.mjs.map +1 -0
- package/dist/core/cart/queries.d.mts +4296 -0
- package/dist/core/cart/queries.mjs +70 -0
- package/dist/core/cart/queries.mjs.map +1 -0
- package/dist/core/cart/server-handlers.d.mts +82 -0
- package/dist/core/cart/server-handlers.mjs +322 -0
- package/dist/core/cart/server-handlers.mjs.map +1 -0
- package/dist/core/cart/state.d.mts +137 -0
- package/dist/core/cart/state.mjs +76 -0
- package/dist/core/cart/state.mjs.map +1 -0
- package/dist/core/cart/sync-quantity-inputs.mjs +16 -0
- package/dist/core/cart/sync-quantity-inputs.mjs.map +1 -0
- package/dist/core/collection/collection.d.mts +134 -0
- package/dist/core/collection/collection.mjs +170 -0
- package/dist/core/collection/collection.mjs.map +1 -0
- package/dist/core/collection/index.d.mts +6 -0
- package/dist/core/collection/reconciler.d.mts +32 -0
- package/dist/core/collection/reconciler.mjs +89 -0
- package/dist/core/collection/reconciler.mjs.map +1 -0
- package/dist/core/collection/state.d.mts +66 -0
- package/dist/core/collection/state.mjs +20 -0
- package/dist/core/collection/state.mjs.map +1 -0
- package/dist/core/collection/url.d.mts +70 -0
- package/dist/core/collection/url.mjs +367 -0
- package/dist/core/collection/url.mjs.map +1 -0
- package/dist/core/constants.d.mts +5 -0
- package/dist/core/constants.mjs +8 -0
- package/dist/core/constants.mjs.map +1 -0
- package/dist/core/headers.mjs +44 -0
- package/dist/core/headers.mjs.map +1 -0
- package/dist/core/index.d.mts +55 -0
- package/dist/core/index.mjs +44 -0
- package/dist/core/logging/logging.d.mts +21 -0
- package/dist/core/logging/logging.mjs +99 -0
- package/dist/core/logging/logging.mjs.map +1 -0
- package/dist/core/logging/types.d.mts +40 -0
- package/dist/core/logging/types.mjs +18 -0
- package/dist/core/logging/types.mjs.map +1 -0
- package/dist/core/money/cache.mjs +25 -0
- package/dist/core/money/cache.mjs.map +1 -0
- package/dist/core/money/format.d.mts +15 -0
- package/dist/core/money/format.mjs +243 -0
- package/dist/core/money/format.mjs.map +1 -0
- package/dist/core/money/types.d.mts +47 -0
- package/dist/core/observable.mjs +46 -0
- package/dist/core/observable.mjs.map +1 -0
- package/dist/core/predictive-search/constants.d.mts +5 -0
- package/dist/core/predictive-search/constants.mjs +6 -0
- package/dist/core/predictive-search/constants.mjs.map +1 -0
- package/dist/core/predictive-search/form.d.mts +31 -0
- package/dist/core/predictive-search/form.mjs +31 -0
- package/dist/core/predictive-search/form.mjs.map +1 -0
- package/dist/core/predictive-search/index.d.mts +6 -0
- package/dist/core/predictive-search/queries.d.mts +118 -0
- package/dist/core/predictive-search/queries.mjs +81 -0
- package/dist/core/predictive-search/queries.mjs.map +1 -0
- package/dist/core/predictive-search/search.d.mts +32 -0
- package/dist/core/predictive-search/search.mjs +74 -0
- package/dist/core/predictive-search/search.mjs.map +1 -0
- package/dist/core/predictive-search/server-handlers.d.mts +36 -0
- package/dist/core/predictive-search/server-handlers.mjs +113 -0
- package/dist/core/predictive-search/server-handlers.mjs.map +1 -0
- package/dist/core/predictive-search/store.d.mts +44 -0
- package/dist/core/predictive-search/store.mjs +224 -0
- package/dist/core/predictive-search/store.mjs.map +1 -0
- package/dist/core/predictive-search/url.d.mts +41 -0
- package/dist/core/predictive-search/url.mjs +71 -0
- package/dist/core/predictive-search/url.mjs.map +1 -0
- package/dist/core/product/form.d.mts +63 -0
- package/dist/core/product/form.mjs +44 -0
- package/dist/core/product/form.mjs.map +1 -0
- package/dist/core/product/index.d.mts +4 -0
- package/dist/core/product/options.d.mts +40 -0
- package/dist/core/product/options.mjs +291 -0
- package/dist/core/product/options.mjs.map +1 -0
- package/dist/core/product/product-form.d.mts +72 -0
- package/dist/core/product/product-form.mjs +158 -0
- package/dist/core/product/product-form.mjs.map +1 -0
- package/dist/core/product/state.d.mts +68 -0
- package/dist/core/request-context.d.mts +70 -0
- package/dist/core/request-context.mjs +120 -0
- package/dist/core/request-context.mjs.map +1 -0
- package/dist/core/request-routing/handle-shopify-redirects.d.mts +17 -0
- package/dist/core/request-routing/handle-shopify-redirects.mjs +31 -0
- package/dist/core/request-routing/handle-shopify-redirects.mjs.map +1 -0
- package/dist/core/request-routing/handle-shopify-routes.d.mts +14 -0
- package/dist/core/request-routing/handle-shopify-routes.mjs +42 -0
- package/dist/core/request-routing/handle-shopify-routes.mjs.map +1 -0
- package/dist/core/request-routing/interceptors/admin-redirect.mjs +12 -0
- package/dist/core/request-routing/interceptors/admin-redirect.mjs.map +1 -0
- package/dist/core/request-routing/interceptors/agent-proxy.mjs +19 -0
- package/dist/core/request-routing/interceptors/agent-proxy.mjs.map +1 -0
- package/dist/core/request-routing/interceptors/ajax-api.mjs +16 -0
- package/dist/core/request-routing/interceptors/ajax-api.mjs.map +1 -0
- package/dist/core/request-routing/interceptors/api-proxy.mjs +20 -0
- package/dist/core/request-routing/interceptors/api-proxy.mjs.map +1 -0
- package/dist/core/request-routing/interceptors/checkout.mjs +58 -0
- package/dist/core/request-routing/interceptors/checkout.mjs.map +1 -0
- package/dist/core/request-routing/interceptors/mcp-proxy.mjs +23 -0
- package/dist/core/request-routing/interceptors/mcp-proxy.mjs.map +1 -0
- package/dist/core/request-routing/interceptors/proxy.mjs +68 -0
- package/dist/core/request-routing/interceptors/proxy.mjs.map +1 -0
- package/dist/core/request-routing/interceptors/query-param-redirect.mjs +22 -0
- package/dist/core/request-routing/interceptors/query-param-redirect.mjs.map +1 -0
- package/dist/core/request-routing/interceptors/sfapi-proxy.mjs +27 -0
- package/dist/core/request-routing/interceptors/sfapi-proxy.mjs.map +1 -0
- package/dist/core/request-routing/interceptors/standard-routes.mjs +19 -0
- package/dist/core/request-routing/interceptors/standard-routes.mjs.map +1 -0
- package/dist/core/request-routing/interceptors/url-redirects.mjs +27 -0
- package/dist/core/request-routing/interceptors/url-redirects.mjs.map +1 -0
- package/dist/core/request-routing/interceptors/well-known.mjs +19 -0
- package/dist/core/request-routing/interceptors/well-known.mjs.map +1 -0
- package/dist/core/request-routing/registered-routes.d.mts +7 -0
- package/dist/core/request-routing/registered-routes.mjs +59 -0
- package/dist/core/request-routing/registered-routes.mjs.map +1 -0
- package/dist/core/request-routing/route-types.d.mts +51 -0
- package/dist/core/request-routing/safe-apply-response-headers.mjs +16 -0
- package/dist/core/request-routing/safe-apply-response-headers.mjs.map +1 -0
- package/dist/core/shop-pay/shop-pay.d.mts +102 -0
- package/dist/core/shop-pay/shop-pay.mjs +289 -0
- package/dist/core/shop-pay/shop-pay.mjs.map +1 -0
- package/dist/core/shopify-scripts/analytics.mjs +26 -0
- package/dist/core/shopify-scripts/analytics.mjs.map +1 -0
- package/dist/core/shopify-scripts/consent.mjs +17 -0
- package/dist/core/shopify-scripts/consent.mjs.map +1 -0
- package/dist/core/shopify-scripts/constants.mjs +19 -0
- package/dist/core/shopify-scripts/constants.mjs.map +1 -0
- package/dist/core/shopify-scripts/deprecated-cookies.mjs +97 -0
- package/dist/core/shopify-scripts/deprecated-cookies.mjs.map +1 -0
- package/dist/core/shopify-scripts/global.d.mts +1 -0
- package/dist/core/shopify-scripts/global.mjs +86 -0
- package/dist/core/shopify-scripts/global.mjs.map +1 -0
- package/dist/core/shopify-scripts/index.d.mts +27 -0
- package/dist/core/shopify-scripts/index.mjs +135 -0
- package/dist/core/shopify-scripts/index.mjs.map +1 -0
- package/dist/core/shopify-scripts/initialize.d.mts +18 -0
- package/dist/core/shopify-scripts/initialize.mjs +27 -0
- package/dist/core/shopify-scripts/initialize.mjs.map +1 -0
- package/dist/core/shopify-scripts/page-view.mjs +49 -0
- package/dist/core/shopify-scripts/page-view.mjs.map +1 -0
- package/dist/core/shopify-scripts/perfkit.mjs +33 -0
- package/dist/core/shopify-scripts/perfkit.mjs.map +1 -0
- package/dist/core/shopify-scripts/render.d.mts +1 -0
- package/dist/core/shopify-scripts/render.mjs +23 -0
- package/dist/core/shopify-scripts/render.mjs.map +1 -0
- package/dist/core/shopify-scripts/types.d.mts +76 -0
- package/dist/core/shopify-scripts/utils/cookie-domain.mjs +43 -0
- package/dist/core/shopify-scripts/utils/cookie-domain.mjs.map +1 -0
- package/dist/core/shopify-scripts/utils/inline-script.mjs +8 -0
- package/dist/core/shopify-scripts/utils/inline-script.mjs.map +1 -0
- package/dist/core/shopify-scripts/utils/navigation.mjs +46 -0
- package/dist/core/shopify-scripts/utils/navigation.mjs.map +1 -0
- package/dist/core/shopify-scripts/utils/tracking-values.mjs +65 -0
- package/dist/core/shopify-scripts/utils/tracking-values.mjs.map +1 -0
- package/dist/core/shopify-scripts/utils/uuid.mjs +17 -0
- package/dist/core/shopify-scripts/utils/uuid.mjs.map +1 -0
- package/dist/core/shopify-scripts/webmcp.mjs +22 -0
- package/dist/core/shopify-scripts/webmcp.mjs.map +1 -0
- package/dist/core/standard-routes/build.d.mts +34 -0
- package/dist/core/standard-routes/build.mjs +54 -0
- package/dist/core/standard-routes/build.mjs.map +1 -0
- package/dist/core/standard-routes/defaults.mjs +31 -0
- package/dist/core/standard-routes/defaults.mjs.map +1 -0
- package/dist/core/standard-routes/match.mjs +108 -0
- package/dist/core/standard-routes/match.mjs.map +1 -0
- package/dist/core/standard-routes/path.mjs +58 -0
- package/dist/core/standard-routes/path.mjs.map +1 -0
- package/dist/core/standard-routes/redirects.mjs +51 -0
- package/dist/core/standard-routes/redirects.mjs.map +1 -0
- package/dist/core/standard-routes/types.d.mts +95 -0
- package/dist/core/url.mjs +35 -0
- package/dist/core/url.mjs.map +1 -0
- package/dist/core/utils/load-script.mjs +34 -0
- package/dist/core/utils/load-script.mjs.map +1 -0
- package/dist/core/utils/parse-gid.mjs +33 -0
- package/dist/core/utils/parse-gid.mjs.map +1 -0
- package/dist/core/utils/record.mjs +8 -0
- package/dist/core/utils/record.mjs.map +1 -0
- package/dist/customer-account/client.d.mts +50 -0
- package/dist/customer-account/client.mjs +239 -0
- package/dist/customer-account/client.mjs.map +1 -0
- package/dist/customer-account/errors.d.mts +28 -0
- package/dist/customer-account/errors.mjs +39 -0
- package/dist/customer-account/errors.mjs.map +1 -0
- package/dist/customer-account/graphql.d.mts +29 -0
- package/dist/customer-account/graphql.mjs +39 -0
- package/dist/customer-account/graphql.mjs.map +1 -0
- package/dist/customer-account/index.d.mts +7 -0
- package/dist/customer-account/index.mjs +7 -0
- package/dist/customer-account/session.d.mts +117 -0
- package/dist/customer-account/session.mjs +733 -0
- package/dist/customer-account/session.mjs.map +1 -0
- package/dist/customer-account/type-resolver.d.mts +11 -0
- package/dist/customer-account-api-types.d.ts +3269 -3270
- package/dist/customer-account.schema.json +50753 -1
- package/dist/development/_virtual/_@oxc-project_runtime@0.127.0/helpers/taggedTemplateLiteral.mjs +7 -0
- package/dist/development/client/client.d.mts +34 -0
- package/dist/development/client/client.mjs +193 -0
- package/dist/development/client/client.mjs.map +1 -0
- package/dist/development/client/errors.d.mts +48 -0
- package/dist/development/client/errors.mjs +57 -0
- package/dist/development/client/errors.mjs.map +1 -0
- package/dist/development/client/index.d.mts +4 -0
- package/dist/development/client/types.d.mts +147 -0
- package/dist/development/core/analytics/cart-tracker.d.mts +8 -0
- package/dist/development/core/analytics/cart-tracker.mjs +144 -0
- package/dist/development/core/analytics/cart-tracker.mjs.map +1 -0
- package/dist/development/core/analytics/events.d.mts +15 -0
- package/dist/development/core/analytics/events.mjs +15 -0
- package/dist/development/core/analytics/events.mjs.map +1 -0
- package/dist/development/core/analytics/index.d.mts +3 -0
- package/dist/development/core/analytics/types.d.mts +143 -0
- package/dist/development/core/analytics/utils/flatten-connection.d.mts +19 -0
- package/dist/development/core/analytics/utils/flatten-connection.mjs +25 -0
- package/dist/development/core/analytics/utils/flatten-connection.mjs.map +1 -0
- package/dist/development/core/cache/cache-status.mjs +17 -0
- package/dist/development/core/cache/cache-status.mjs.map +1 -0
- package/dist/development/core/cache/fetch-with-cache.d.mts +43 -0
- package/dist/development/core/cache/fetch-with-cache.mjs +188 -0
- package/dist/development/core/cache/fetch-with-cache.mjs.map +1 -0
- package/dist/development/core/cache/key.d.mts +6 -0
- package/dist/development/core/cache/key.mjs +27 -0
- package/dist/development/core/cache/key.mjs.map +1 -0
- package/dist/development/core/cache/run-with-cache.d.mts +36 -0
- package/dist/development/core/cache/run-with-cache.mjs +114 -0
- package/dist/development/core/cache/run-with-cache.mjs.map +1 -0
- package/dist/development/core/cache/store.d.mts +19 -0
- package/dist/development/core/cache/store.mjs +62 -0
- package/dist/development/core/cache/store.mjs.map +1 -0
- package/dist/development/core/cache/strategies.d.mts +39 -0
- package/dist/development/core/cache/strategies.mjs +70 -0
- package/dist/development/core/cache/strategies.mjs.map +1 -0
- package/dist/development/core/cart/actions.d.mts +50 -0
- package/dist/development/core/cart/actions.mjs +240 -0
- package/dist/development/core/cart/actions.mjs.map +1 -0
- package/dist/development/core/cart/attach-quantity-input.d.mts +5 -0
- package/dist/development/core/cart/attach-quantity-input.mjs +17 -0
- package/dist/development/core/cart/attach-quantity-input.mjs.map +1 -0
- package/dist/development/core/cart/buyer-identity-sync.d.mts +19 -0
- package/dist/development/core/cart/buyer-identity-sync.mjs +6 -0
- package/dist/development/core/cart/buyer-identity-sync.mjs.map +1 -0
- package/dist/development/core/cart/cart.d.mts +32 -0
- package/dist/development/core/cart/cart.mjs +1687 -0
- package/dist/development/core/cart/cart.mjs.map +1 -0
- package/dist/development/core/cart/cookie.d.mts +5 -0
- package/dist/development/core/cart/cookie.mjs +28 -0
- package/dist/development/core/cart/cookie.mjs.map +1 -0
- package/dist/development/core/cart/form.d.mts +130 -0
- package/dist/development/core/cart/form.mjs +75 -0
- package/dist/development/core/cart/form.mjs.map +1 -0
- package/dist/development/core/cart/get-cart.d.mts +25 -0
- package/dist/development/core/cart/get-cart.mjs +32 -0
- package/dist/development/core/cart/get-cart.mjs.map +1 -0
- package/dist/development/core/cart/index.d.mts +10 -0
- package/dist/development/core/cart/quantity.d.mts +10 -0
- package/dist/development/core/cart/quantity.mjs +14 -0
- package/dist/development/core/cart/quantity.mjs.map +1 -0
- package/dist/development/core/cart/queries.d.mts +4296 -0
- package/dist/development/core/cart/queries.mjs +70 -0
- package/dist/development/core/cart/queries.mjs.map +1 -0
- package/dist/development/core/cart/server-handlers.d.mts +82 -0
- package/dist/development/core/cart/server-handlers.mjs +322 -0
- package/dist/development/core/cart/server-handlers.mjs.map +1 -0
- package/dist/development/core/cart/state.d.mts +137 -0
- package/dist/development/core/cart/state.mjs +76 -0
- package/dist/development/core/cart/state.mjs.map +1 -0
- package/dist/development/core/cart/sync-quantity-inputs.mjs +16 -0
- package/dist/development/core/cart/sync-quantity-inputs.mjs.map +1 -0
- package/dist/development/core/collection/collection.d.mts +134 -0
- package/dist/development/core/collection/collection.mjs +170 -0
- package/dist/development/core/collection/collection.mjs.map +1 -0
- package/dist/development/core/collection/index.d.mts +6 -0
- package/dist/development/core/collection/reconciler.d.mts +32 -0
- package/dist/development/core/collection/reconciler.mjs +89 -0
- package/dist/development/core/collection/reconciler.mjs.map +1 -0
- package/dist/development/core/collection/state.d.mts +66 -0
- package/dist/development/core/collection/state.mjs +20 -0
- package/dist/development/core/collection/state.mjs.map +1 -0
- package/dist/development/core/collection/url.d.mts +70 -0
- package/dist/development/core/collection/url.mjs +367 -0
- package/dist/development/core/collection/url.mjs.map +1 -0
- package/dist/development/core/constants.mjs +7 -0
- package/dist/development/core/constants.mjs.map +1 -0
- package/dist/development/core/development.d.mts +55 -0
- package/dist/development/core/development.mjs +44 -0
- package/dist/development/core/headers.mjs +44 -0
- package/dist/development/core/headers.mjs.map +1 -0
- package/dist/development/core/index.d.mts +53 -0
- package/dist/development/core/logging/logging.d.mts +21 -0
- package/dist/development/core/logging/logging.mjs +99 -0
- package/dist/development/core/logging/logging.mjs.map +1 -0
- package/dist/development/core/logging/types.d.mts +40 -0
- package/dist/development/core/logging/types.mjs +18 -0
- package/dist/development/core/logging/types.mjs.map +1 -0
- package/dist/development/core/money/cache.mjs +25 -0
- package/dist/development/core/money/cache.mjs.map +1 -0
- package/dist/development/core/money/format.d.mts +15 -0
- package/dist/development/core/money/format.mjs +243 -0
- package/dist/development/core/money/format.mjs.map +1 -0
- package/dist/development/core/money/types.d.mts +47 -0
- package/dist/development/core/observable.mjs +46 -0
- package/dist/development/core/observable.mjs.map +1 -0
- package/dist/development/core/predictive-search/constants.d.mts +5 -0
- package/dist/development/core/predictive-search/constants.mjs +6 -0
- package/dist/development/core/predictive-search/constants.mjs.map +1 -0
- package/dist/development/core/predictive-search/form.d.mts +31 -0
- package/dist/development/core/predictive-search/form.mjs +31 -0
- package/dist/development/core/predictive-search/form.mjs.map +1 -0
- package/dist/development/core/predictive-search/index.d.mts +6 -0
- package/dist/development/core/predictive-search/queries.d.mts +118 -0
- package/dist/development/core/predictive-search/queries.mjs +81 -0
- package/dist/development/core/predictive-search/queries.mjs.map +1 -0
- package/dist/development/core/predictive-search/search.d.mts +32 -0
- package/dist/development/core/predictive-search/search.mjs +74 -0
- package/dist/development/core/predictive-search/search.mjs.map +1 -0
- package/dist/development/core/predictive-search/server-handlers.d.mts +36 -0
- package/dist/development/core/predictive-search/server-handlers.mjs +113 -0
- package/dist/development/core/predictive-search/server-handlers.mjs.map +1 -0
- package/dist/development/core/predictive-search/store.d.mts +44 -0
- package/dist/development/core/predictive-search/store.mjs +224 -0
- package/dist/development/core/predictive-search/store.mjs.map +1 -0
- package/dist/development/core/predictive-search/url.d.mts +41 -0
- package/dist/development/core/predictive-search/url.mjs +71 -0
- package/dist/development/core/predictive-search/url.mjs.map +1 -0
- package/dist/development/core/product/form.d.mts +63 -0
- package/dist/development/core/product/form.mjs +44 -0
- package/dist/development/core/product/form.mjs.map +1 -0
- package/dist/development/core/product/index.d.mts +4 -0
- package/dist/development/core/product/options.d.mts +40 -0
- package/dist/development/core/product/options.mjs +291 -0
- package/dist/development/core/product/options.mjs.map +1 -0
- package/dist/development/core/product/product-form.d.mts +72 -0
- package/dist/development/core/product/product-form.mjs +158 -0
- package/dist/development/core/product/product-form.mjs.map +1 -0
- package/dist/development/core/product/state.d.mts +68 -0
- package/dist/development/core/request-context.d.mts +70 -0
- package/dist/development/core/request-context.mjs +120 -0
- package/dist/development/core/request-context.mjs.map +1 -0
- package/dist/development/core/request-routing/handle-shopify-redirects.d.mts +17 -0
- package/dist/development/core/request-routing/handle-shopify-redirects.mjs +31 -0
- package/dist/development/core/request-routing/handle-shopify-redirects.mjs.map +1 -0
- package/dist/development/core/request-routing/handle-shopify-routes.d.mts +1 -0
- package/dist/development/core/request-routing/handle-shopify-routes.development.d.mts +11 -0
- package/dist/development/core/request-routing/handle-shopify-routes.development.mjs +16 -0
- package/dist/development/core/request-routing/handle-shopify-routes.development.mjs.map +1 -0
- package/dist/development/core/request-routing/handle-shopify-routes.mjs +42 -0
- package/dist/development/core/request-routing/handle-shopify-routes.mjs.map +1 -0
- package/dist/development/core/request-routing/interceptors/admin-redirect.mjs +12 -0
- package/dist/development/core/request-routing/interceptors/admin-redirect.mjs.map +1 -0
- package/dist/development/core/request-routing/interceptors/agent-proxy.mjs +19 -0
- package/dist/development/core/request-routing/interceptors/agent-proxy.mjs.map +1 -0
- package/dist/development/core/request-routing/interceptors/ajax-api.mjs +16 -0
- package/dist/development/core/request-routing/interceptors/ajax-api.mjs.map +1 -0
- package/dist/development/core/request-routing/interceptors/api-proxy.mjs +20 -0
- package/dist/development/core/request-routing/interceptors/api-proxy.mjs.map +1 -0
- package/dist/development/core/request-routing/interceptors/checkout.mjs +58 -0
- package/dist/development/core/request-routing/interceptors/checkout.mjs.map +1 -0
- package/dist/development/core/request-routing/interceptors/graphiql.mjs +46 -0
- package/dist/development/core/request-routing/interceptors/graphiql.mjs.map +1 -0
- package/dist/development/core/request-routing/interceptors/mcp-proxy.mjs +23 -0
- package/dist/development/core/request-routing/interceptors/mcp-proxy.mjs.map +1 -0
- package/dist/development/core/request-routing/interceptors/proxy.mjs +68 -0
- package/dist/development/core/request-routing/interceptors/proxy.mjs.map +1 -0
- package/dist/development/core/request-routing/interceptors/query-param-redirect.mjs +22 -0
- package/dist/development/core/request-routing/interceptors/query-param-redirect.mjs.map +1 -0
- package/dist/development/core/request-routing/interceptors/sfapi-proxy.mjs +27 -0
- package/dist/development/core/request-routing/interceptors/sfapi-proxy.mjs.map +1 -0
- package/dist/development/core/request-routing/interceptors/standard-routes.mjs +19 -0
- package/dist/development/core/request-routing/interceptors/standard-routes.mjs.map +1 -0
- package/dist/development/core/request-routing/interceptors/url-redirects.mjs +27 -0
- package/dist/development/core/request-routing/interceptors/url-redirects.mjs.map +1 -0
- package/dist/development/core/request-routing/interceptors/well-known.mjs +19 -0
- package/dist/development/core/request-routing/interceptors/well-known.mjs.map +1 -0
- package/dist/development/core/request-routing/registered-routes.d.mts +7 -0
- package/dist/development/core/request-routing/registered-routes.mjs +59 -0
- package/dist/development/core/request-routing/registered-routes.mjs.map +1 -0
- package/dist/development/core/request-routing/route-types.d.mts +51 -0
- package/dist/development/core/request-routing/safe-apply-response-headers.mjs +16 -0
- package/dist/development/core/request-routing/safe-apply-response-headers.mjs.map +1 -0
- package/dist/development/core/shop-pay/shop-pay.d.mts +102 -0
- package/dist/development/core/shop-pay/shop-pay.mjs +289 -0
- package/dist/development/core/shop-pay/shop-pay.mjs.map +1 -0
- package/dist/development/core/shopify-scripts/analytics.mjs +26 -0
- package/dist/development/core/shopify-scripts/analytics.mjs.map +1 -0
- package/dist/development/core/shopify-scripts/consent.mjs +17 -0
- package/dist/development/core/shopify-scripts/consent.mjs.map +1 -0
- package/dist/development/core/shopify-scripts/constants.mjs +19 -0
- package/dist/development/core/shopify-scripts/constants.mjs.map +1 -0
- package/dist/development/core/shopify-scripts/deprecated-cookies.mjs +97 -0
- package/dist/development/core/shopify-scripts/deprecated-cookies.mjs.map +1 -0
- package/dist/development/core/shopify-scripts/global.d.mts +1 -0
- package/dist/development/core/shopify-scripts/global.mjs +86 -0
- package/dist/development/core/shopify-scripts/global.mjs.map +1 -0
- package/dist/development/core/shopify-scripts/index.d.mts +27 -0
- package/dist/development/core/shopify-scripts/index.mjs +145 -0
- package/dist/development/core/shopify-scripts/index.mjs.map +1 -0
- package/dist/development/core/shopify-scripts/initialize.d.mts +18 -0
- package/dist/development/core/shopify-scripts/initialize.mjs +27 -0
- package/dist/development/core/shopify-scripts/initialize.mjs.map +1 -0
- package/dist/development/core/shopify-scripts/page-view.mjs +49 -0
- package/dist/development/core/shopify-scripts/page-view.mjs.map +1 -0
- package/dist/development/core/shopify-scripts/perfkit.mjs +33 -0
- package/dist/development/core/shopify-scripts/perfkit.mjs.map +1 -0
- package/dist/development/core/shopify-scripts/render.d.mts +1 -0
- package/dist/development/core/shopify-scripts/render.mjs +23 -0
- package/dist/development/core/shopify-scripts/render.mjs.map +1 -0
- package/dist/development/core/shopify-scripts/types.d.mts +76 -0
- package/dist/development/core/shopify-scripts/utils/cookie-domain.mjs +43 -0
- package/dist/development/core/shopify-scripts/utils/cookie-domain.mjs.map +1 -0
- package/dist/development/core/shopify-scripts/utils/inline-script.mjs +8 -0
- package/dist/development/core/shopify-scripts/utils/inline-script.mjs.map +1 -0
- package/dist/development/core/shopify-scripts/utils/navigation.mjs +46 -0
- package/dist/development/core/shopify-scripts/utils/navigation.mjs.map +1 -0
- package/dist/development/core/shopify-scripts/utils/tracking-values.mjs +65 -0
- package/dist/development/core/shopify-scripts/utils/tracking-values.mjs.map +1 -0
- package/dist/development/core/shopify-scripts/utils/uuid.mjs +17 -0
- package/dist/development/core/shopify-scripts/utils/uuid.mjs.map +1 -0
- package/dist/development/core/shopify-scripts/webmcp.mjs +22 -0
- package/dist/development/core/shopify-scripts/webmcp.mjs.map +1 -0
- package/dist/development/core/standard-routes/build.d.mts +34 -0
- package/dist/development/core/standard-routes/build.mjs +54 -0
- package/dist/development/core/standard-routes/build.mjs.map +1 -0
- package/dist/development/core/standard-routes/defaults.mjs +31 -0
- package/dist/development/core/standard-routes/defaults.mjs.map +1 -0
- package/dist/development/core/standard-routes/match.mjs +108 -0
- package/dist/development/core/standard-routes/match.mjs.map +1 -0
- package/dist/development/core/standard-routes/path.mjs +58 -0
- package/dist/development/core/standard-routes/path.mjs.map +1 -0
- package/dist/development/core/standard-routes/redirects.mjs +51 -0
- package/dist/development/core/standard-routes/redirects.mjs.map +1 -0
- package/dist/development/core/standard-routes/types.d.mts +95 -0
- package/dist/development/core/types.d.mts +11 -0
- package/dist/development/core/url.mjs +35 -0
- package/dist/development/core/url.mjs.map +1 -0
- package/dist/development/core/utils/load-script.mjs +34 -0
- package/dist/development/core/utils/load-script.mjs.map +1 -0
- package/dist/development/core/utils/parse-gid.mjs +33 -0
- package/dist/development/core/utils/parse-gid.mjs.map +1 -0
- package/dist/development/customer-account/session.d.mts +46 -0
- package/dist/development/customer-account/session.mjs +21 -0
- package/dist/development/customer-account/session.mjs.map +1 -0
- package/dist/development/globals.d.mts +64 -0
- package/dist/development/graphql/generated/customer-account-api-types.d.mts +13 -0
- package/dist/development/graphql/generated/graphql-env.d.mts +19280 -0
- package/dist/development/graphql/generated/storefront-api-types.d.mts +47 -0
- package/dist/development/graphql/graphql.d.mts +40 -0
- package/dist/development/graphql/graphql.mjs +16 -0
- package/dist/development/graphql/graphql.mjs.map +1 -0
- package/dist/development/graphql/index.d.mts +2 -0
- package/dist/development/graphql/scalars.d.mts +15 -0
- package/dist/development/graphql/type-resolver.d.mts +229 -0
- package/dist/development/react/cart.d.mts +40 -0
- package/dist/development/react/cart.mjs +150 -0
- package/dist/development/react/cart.mjs.map +1 -0
- package/dist/development/react/collection.d.mts +91 -0
- package/dist/development/react/collection.mjs +129 -0
- package/dist/development/react/collection.mjs.map +1 -0
- package/dist/development/react/index.d.mts +13 -0
- package/dist/development/react/index.mjs +10 -0
- package/dist/development/react/predictive-search.d.mts +49 -0
- package/dist/development/react/predictive-search.mjs +133 -0
- package/dist/development/react/predictive-search.mjs.map +1 -0
- package/dist/development/react/product.d.mts +72 -0
- package/dist/development/react/product.mjs +127 -0
- package/dist/development/react/product.mjs.map +1 -0
- package/dist/development/react/shop-pay.d.mts +9 -0
- package/dist/development/react/shop-pay.mjs +16 -0
- package/dist/development/react/shop-pay.mjs.map +1 -0
- package/dist/development/react/shopify-scripts.d.mts +20 -0
- package/dist/development/react/shopify-scripts.mjs +39 -0
- package/dist/development/react/shopify-scripts.mjs.map +1 -0
- package/dist/development/vendor/standard-actions.d.mts +134 -0
- package/dist/development/vendor/standard-events.d.mts +1107 -0
- package/dist/development/vue/cart.d.mts +42 -0
- package/dist/development/vue/cart.mjs +118 -0
- package/dist/development/vue/cart.mjs.map +1 -0
- package/dist/development/vue/collection.d.mts +46 -0
- package/dist/development/vue/collection.mjs +108 -0
- package/dist/development/vue/collection.mjs.map +1 -0
- package/dist/development/vue/index.d.mts +11 -0
- package/dist/development/vue/index.mjs +8 -0
- package/dist/development/vue/predictive-search.d.mts +124 -0
- package/dist/development/vue/predictive-search.mjs +171 -0
- package/dist/development/vue/predictive-search.mjs.map +1 -0
- package/dist/development/vue/product.d.mts +57 -0
- package/dist/development/vue/product.mjs +167 -0
- package/dist/development/vue/product.mjs.map +1 -0
- package/dist/development/vue/shop-pay.d.mts +25 -0
- package/dist/development/vue/shop-pay.mjs +35 -0
- package/dist/development/vue/shop-pay.mjs.map +1 -0
- package/dist/development/vue/shopify-scripts.d.mts +127 -0
- package/dist/development/vue/shopify-scripts.mjs +79 -0
- package/dist/development/vue/shopify-scripts.mjs.map +1 -0
- package/dist/globals.d.mts +64 -0
- package/dist/graphql/generated/customer-account-api-types.d.mts +13 -0
- package/dist/graphql/generated/customer-account-graphql-env.d.mts +22170 -0
- package/dist/graphql/generated/graphql-env.d.mts +19280 -0
- package/dist/graphql/generated/storefront-api-types.d.mts +47 -0
- package/dist/graphql/graphql.d.mts +40 -0
- package/dist/graphql/graphql.mjs +16 -0
- package/dist/graphql/graphql.mjs.map +1 -0
- package/dist/graphql/index.d.mts +2 -0
- package/dist/graphql/scalars.d.mts +26 -0
- package/dist/graphql/type-resolver.d.mts +229 -0
- package/dist/react/cart.d.mts +40 -0
- package/dist/react/cart.mjs +150 -0
- package/dist/react/cart.mjs.map +1 -0
- package/dist/react/collection.d.mts +91 -0
- package/dist/react/collection.mjs +129 -0
- package/dist/react/collection.mjs.map +1 -0
- package/dist/react/index.d.mts +13 -0
- package/dist/react/index.mjs +10 -0
- package/dist/react/predictive-search.d.mts +49 -0
- package/dist/react/predictive-search.mjs +133 -0
- package/dist/react/predictive-search.mjs.map +1 -0
- package/dist/react/product.d.mts +72 -0
- package/dist/react/product.mjs +127 -0
- package/dist/react/product.mjs.map +1 -0
- package/dist/react/shop-pay.d.mts +9 -0
- package/dist/react/shop-pay.mjs +16 -0
- package/dist/react/shop-pay.mjs.map +1 -0
- package/dist/react/shopify-scripts.d.mts +20 -0
- package/dist/react/shopify-scripts.mjs +39 -0
- package/dist/react/shopify-scripts.mjs.map +1 -0
- package/dist/storefront-api-types.d.ts +2351 -2390
- package/dist/storefront.schema.json +41534 -1
- package/dist/ts-plugin/index.cjs +68 -0
- package/dist/ts-plugin/index.cjs.map +1 -0
- package/dist/ts-plugin/index.d.cts +4 -0
- package/dist/vendor/standard-actions.d.mts +134 -0
- package/dist/vendor/standard-events.d.mts +1107 -0
- package/dist/vite/index.d.mts +2 -0
- package/dist/vite/index.mjs +3 -0
- package/dist/vite/local-https.d.mts +35 -0
- package/dist/vite/local-https.mjs +202 -0
- package/dist/vite/local-https.mjs.map +1 -0
- package/dist/vue/cart.d.mts +42 -0
- package/dist/vue/cart.mjs +118 -0
- package/dist/vue/cart.mjs.map +1 -0
- package/dist/vue/collection.d.mts +46 -0
- package/dist/vue/collection.mjs +108 -0
- package/dist/vue/collection.mjs.map +1 -0
- package/dist/vue/index.d.mts +11 -0
- package/dist/vue/index.mjs +8 -0
- package/dist/vue/predictive-search.d.mts +124 -0
- package/dist/vue/predictive-search.mjs +171 -0
- package/dist/vue/predictive-search.mjs.map +1 -0
- package/dist/vue/product.d.mts +57 -0
- package/dist/vue/product.mjs +167 -0
- package/dist/vue/product.mjs.map +1 -0
- package/dist/vue/shop-pay.d.mts +25 -0
- package/dist/vue/shop-pay.mjs +35 -0
- package/dist/vue/shop-pay.mjs.map +1 -0
- package/dist/vue/shopify-scripts.d.mts +127 -0
- package/dist/vue/shopify-scripts.mjs +79 -0
- package/dist/vue/shopify-scripts.mjs.map +1 -0
- package/package.json +116 -86
- package/skills/hydrogen-analytics/SKILL.md +80 -0
- package/skills/hydrogen-analytics/references/react.md +160 -0
- package/skills/hydrogen-analytics/references/vue.md +80 -0
- package/skills/hydrogen-cart-drawer/SKILL.md +248 -0
- package/skills/hydrogen-cart-drawer/references/accessibility.md +109 -0
- package/skills/hydrogen-cart-drawer/references/css.md +67 -0
- package/skills/hydrogen-cart-ui/SKILL.md +218 -0
- package/skills/hydrogen-cart-ui/references/nextjs.md +89 -0
- package/skills/hydrogen-cart-ui/references/react.md +263 -0
- package/skills/hydrogen-cart-ui/references/vue.md +204 -0
- package/skills/hydrogen-collection-browser/SKILL.md +80 -0
- package/skills/hydrogen-collection-browser/references/nextjs.md +118 -0
- package/skills/hydrogen-collection-browser/references/nuxt.md +108 -0
- package/skills/hydrogen-collection-browser/references/react.md +237 -0
- package/skills/hydrogen-customer-account/SKILL.md +107 -0
- package/skills/hydrogen-image/SKILL.md +65 -0
- package/skills/hydrogen-local-https/SKILL.md +144 -0
- package/skills/hydrogen-markets/SKILL.md +221 -0
- package/skills/hydrogen-markets/references/nextjs.md +157 -0
- package/skills/hydrogen-money/SKILL.md +67 -0
- package/skills/hydrogen-oxygen/SKILL.md +245 -0
- package/skills/hydrogen-oxygen/references/react-router.md +230 -0
- package/skills/hydrogen-predictive-search/SKILL.md +130 -0
- package/skills/hydrogen-predictive-search/references/react.md +32 -0
- package/skills/hydrogen-predictive-search/references/vue.md +40 -0
- package/skills/hydrogen-request-handlers/SKILL.md +90 -0
- package/skills/hydrogen-request-handlers/references/frameworks.md +174 -0
- package/skills/hydrogen-request-handlers/references/nextjs.md +136 -0
- package/skills/hydrogen-request-handlers/references/nuxt.md +214 -0
- package/skills/hydrogen-routing/SKILL.md +154 -0
- package/skills/hydrogen-setup/SKILL.md +50 -0
- package/skills/hydrogen-setup/references/analytics.md +624 -0
- package/skills/hydrogen-setup/steps/1-inspect-app.md +62 -0
- package/skills/hydrogen-setup/steps/10-analytics.md +10 -0
- package/skills/hydrogen-setup/steps/11-verify.md +31 -0
- package/skills/hydrogen-setup/steps/2-scaffold.md +86 -0
- package/skills/hydrogen-setup/steps/3-build-home-page.md +37 -0
- package/skills/hydrogen-setup/steps/4-collection-and-search.md +13 -0
- package/skills/hydrogen-setup/steps/5-cart.md +10 -0
- package/skills/hydrogen-setup/steps/6-product-detail-page.md +390 -0
- package/skills/hydrogen-setup/steps/7-shopify-runtime-scripts.md +69 -0
- package/skills/hydrogen-setup/steps/8-cart-drawer-and-navbar.md +35 -0
- package/skills/hydrogen-setup/steps/9-account-page.md +54 -0
- package/skills/hydrogen-shop-pay/SKILL.md +79 -0
- package/skills/hydrogen-shop-pay/references/core.md +66 -0
- package/skills/hydrogen-shop-pay/references/react.md +50 -0
- package/skills/hydrogen-shop-pay/references/vue.md +39 -0
- package/skills/hydrogen-smoke-test/SKILL.md +203 -0
- package/skills/hydrogen-storefront-client/SKILL.md +322 -0
- package/skills/hydrogen-storefront-client/references/astro.md +125 -0
- package/skills/hydrogen-storefront-client/references/caching.md +25 -0
- package/skills/hydrogen-storefront-client/references/nextjs.md +121 -0
- package/skills/hydrogen-storefront-client/references/nuxt.md +121 -0
- package/skills/hydrogen-storefront-client/references/query-validation.md +95 -0
- package/skills/hydrogen-storefront-client/references/react-router.md +81 -0
- package/skills/hydrogen-storefront-client/references/solidstart.md +131 -0
- package/skills/hydrogen-storefront-client/references/sveltekit.md +169 -0
- package/skills/hydrogen-variant-form/SKILL.md +250 -0
- package/skills/hydrogen-variant-form/references/nextjs.md +203 -0
- package/skills/hydrogen-variant-form/references/nuxt.md +95 -0
- package/skills/hydrogen-variant-form/references/react.md +71 -0
- package/dist/dev/get-virtual-routes-H72465VB.js +0 -74
- package/dist/dev/hydrogen-routes.d.ts +0 -5
- package/dist/dev/hydrogen-routes.js +0 -25
- package/dist/development/get-virtual-routes-ACFZHU42.js +0 -71
- package/dist/development/get-virtual-routes-ACFZHU42.js.map +0 -1
- package/dist/development/index.cjs +0 -6948
- package/dist/development/index.cjs.map +0 -1
- package/dist/development/index.js +0 -6601
- package/dist/development/index.js.map +0 -1
- package/dist/development/log-seo-tags-IG37ONQ2.js +0 -74
- package/dist/development/log-seo-tags-IG37ONQ2.js.map +0 -1
- package/dist/development/react-router-preset.d.ts +0 -45
- package/dist/development/react-router-preset.js +0 -49
- package/dist/development/react-router-preset.js.map +0 -1
- package/dist/index.cjs +0 -1
- package/dist/oxygen/index.d.ts +0 -197
- package/dist/oxygen/index.js +0 -107
- package/dist/production/get-virtual-routes-ZZEGQQDV.js +0 -3
- package/dist/production/get-virtual-routes-ZZEGQQDV.js.map +0 -1
- package/dist/production/index.cjs +0 -1019
- package/dist/production/index.cjs.map +0 -1
- package/dist/production/index.d.cts +0 -3260
- package/dist/production/index.d.ts +0 -3260
- package/dist/production/index.js +0 -1019
- package/dist/production/index.js.map +0 -1
- package/dist/production/log-seo-tags-TY72EQWZ.js +0 -2
- package/dist/production/log-seo-tags-TY72EQWZ.js.map +0 -1
- package/dist/production/react-router-preset.d.ts +0 -45
- package/dist/production/react-router-preset.js +0 -11
- package/dist/react-router.d.ts +0 -75
- package/dist/vite/chunk-4O5OI3OO.js +0 -127
- package/dist/vite/chunk-FAQ7TVHC.js +0 -9
- package/dist/vite/chunk-QXBQVDMY.js +0 -68
- package/dist/vite/compat-date.d.ts +0 -3
- package/dist/vite/compat-date.js +0 -6
- package/dist/vite/get-virtual-routes.d.ts +0 -21
- package/dist/vite/get-virtual-routes.js +0 -74
- package/dist/vite/hydrogen-middleware.d.ts +0 -9
- package/dist/vite/hydrogen-middleware.js +0 -7
- package/dist/vite/plugin.d.ts +0 -22
- package/dist/vite/plugin.js +0 -171
- package/dist/vite/request-events.d.ts +0 -144
- package/dist/vite/request-events.js +0 -10
- package/dist/vite/types.d.ts +0 -5
- package/dist/vite/types.js +0 -0
- package/dist/vite/virtual-routes/assets/debug-network.css +0 -609
- package/dist/vite/virtual-routes/assets/favicon-dark.svg +0 -20
- package/dist/vite/virtual-routes/assets/favicon.svg +0 -28
- package/dist/vite/virtual-routes/assets/inter-variable-font.woff2 +0 -0
- package/dist/vite/virtual-routes/assets/jetbrainsmono-variable-font.woff2 +0 -0
- package/dist/vite/virtual-routes/assets/styles.css +0 -249
- package/dist/vite/virtual-routes/components/FlameChartWrapper.jsx +0 -123
- package/dist/vite/virtual-routes/components/HydrogenLogoBaseBW.jsx +0 -32
- package/dist/vite/virtual-routes/components/HydrogenLogoBaseColor.jsx +0 -47
- package/dist/vite/virtual-routes/components/IconBanner.jsx +0 -292
- package/dist/vite/virtual-routes/components/IconClose.jsx +0 -38
- package/dist/vite/virtual-routes/components/IconDiscard.jsx +0 -44
- package/dist/vite/virtual-routes/components/IconError.jsx +0 -61
- package/dist/vite/virtual-routes/components/IconGithub.jsx +0 -23
- package/dist/vite/virtual-routes/components/IconTwitter.jsx +0 -21
- package/dist/vite/virtual-routes/components/Layout.jsx +0 -7
- package/dist/vite/virtual-routes/components/RequestDetails.jsx +0 -171
- package/dist/vite/virtual-routes/components/RequestTable.jsx +0 -91
- package/dist/vite/virtual-routes/components/RequestWaterfall.jsx +0 -151
- package/dist/vite/virtual-routes/layout.jsx +0 -33
- package/dist/vite/virtual-routes/lib/useDebugNetworkServer.jsx +0 -178
- package/dist/vite/virtual-routes/routes/[.]well-known.appspecific.com[.]chrome[.]devtools[.]json.jsx +0 -37
- package/dist/vite/virtual-routes/routes/[.]well-known.appspecific.com[.]chrome[.]devtools[.]json.tsx +0 -79
- package/dist/vite/virtual-routes/routes/graphiql.jsx +0 -5
- package/dist/vite/virtual-routes/routes/index.jsx +0 -265
- package/dist/vite/virtual-routes/routes/subrequest-profiler.jsx +0 -243
- package/dist/vite/virtual-routes/virtual-root-with-layout.jsx +0 -63
- package/dist/vite/virtual-routes/virtual-root.jsx +0 -67
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: hydrogen-markets
|
|
3
|
+
description: >
|
|
4
|
+
Guide for implementing Shopify Markets with Hydrogen. Use when adding
|
|
5
|
+
market routing, country/language localization, Shopify Markets, subdomains,
|
|
6
|
+
per-market domains, path-prefixed markets, Next.js App Router market routing,
|
|
7
|
+
or Storefront API @inContext wiring.
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Markets
|
|
11
|
+
|
|
12
|
+
Markets are an application routing concern plus Storefront API context. Hydrogen does not prescribe how a storefront chooses a market. Use domains, subdomains, paths, cookies, buyer preferences, geolocation, or merchant config as needed.
|
|
13
|
+
|
|
14
|
+
The Hydrogen part is request-scoped `i18n` on `createShopifyRequestContext`. Resolve the market first, then create the request context with `i18n`. When a query declares `$country` and `$language` and uses `@inContext(country: $country, language: $language)`, the client injects those values from the resolved `i18n`.
|
|
15
|
+
|
|
16
|
+
If the storefront uses Next.js App Router, read `references/nextjs.md` before writing code. Server Components do not receive a full `Request`, so host-based and path-prefixed markets need Next-specific wiring.
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## Core Rule
|
|
21
|
+
|
|
22
|
+
Add `i18n` where the app already creates its Shopify request context:
|
|
23
|
+
|
|
24
|
+
```diff
|
|
25
|
+
import {
|
|
26
|
+
createStorefrontClient,
|
|
27
|
+
createShopifyRequestContext,
|
|
28
|
+
gql,
|
|
29
|
+
} from "@shopify/hydrogen";
|
|
30
|
+
|
|
31
|
+
const PRODUCTS_PAGE_SIZE = 12;
|
|
32
|
+
|
|
33
|
+
const PRODUCTS_QUERY = gql(`
|
|
34
|
+
- query Products($first: Int!) {
|
|
35
|
+
+ query Products($first: Int!, $country: CountryCode, $language: LanguageCode)
|
|
36
|
+
+ @inContext(country: $country, language: $language) {
|
|
37
|
+
products(first: $first) {
|
|
38
|
+
nodes {
|
|
39
|
+
title
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
`);
|
|
44
|
+
|
|
45
|
+
export async function loadProducts(request: Request) {
|
|
46
|
+
- const requestContext = createShopifyRequestContext({
|
|
47
|
+
- request,
|
|
48
|
+
- i18n: DEFAULT_MARKET,
|
|
49
|
+
- });
|
|
50
|
+
+ const i18n = getMarketFromRequest(request);
|
|
51
|
+
+ const requestContext = createShopifyRequestContext({
|
|
52
|
+
+ request,
|
|
53
|
+
+ i18n,
|
|
54
|
+
+ });
|
|
55
|
+
|
|
56
|
+
const client = createStorefrontClient({
|
|
57
|
+
type: "public",
|
|
58
|
+
requestContext,
|
|
59
|
+
config: {
|
|
60
|
+
storeDomain: process.env.PUBLIC_STORE_DOMAIN!,
|
|
61
|
+
publicStorefrontToken: process.env.PUBLIC_STOREFRONT_API_TOKEN!,
|
|
62
|
+
},
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
return client.graphql(PRODUCTS_QUERY, {
|
|
66
|
+
variables: { first: PRODUCTS_PAGE_SIZE },
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Do not pass `country` or `language` in every query call. Resolve the market once at the request boundary, set `i18n` when creating the request context, and let the client inject the context variables into queries that declare them.
|
|
72
|
+
|
|
73
|
+
The returned Storefront client exposes the resolved locale as `client.i18n`. Use `client.i18n.pathPrefix` when app route helpers need to prepend a market path; Hydrogen normalizes it to `""` or a leading-slash prefix with no trailing slash.
|
|
74
|
+
|
|
75
|
+
---
|
|
76
|
+
|
|
77
|
+
## Market Shape
|
|
78
|
+
|
|
79
|
+
Keep the resolver small and explicit. The Storefront API expects uppercase enum values like `US`, `CA`, `EN`, and `FR`.
|
|
80
|
+
|
|
81
|
+
```ts
|
|
82
|
+
type Market = {
|
|
83
|
+
country: string;
|
|
84
|
+
language: string;
|
|
85
|
+
pathPrefix?: string;
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
const DEFAULT_MARKET = {
|
|
89
|
+
country: "US",
|
|
90
|
+
language: "EN",
|
|
91
|
+
} satisfies Market;
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
If the app needs labels or alternate domains, keep those as application fields. `country` and `language` are required in `i18n`; `pathPrefix` is optional on input and is normalized on the request context to `""` or a leading-slash prefix with no trailing slash.
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
## Subdomains
|
|
99
|
+
|
|
100
|
+
Use this when each market lives under one storefront domain, like `ca.example.com` or `fr.example.com`.
|
|
101
|
+
|
|
102
|
+
```ts
|
|
103
|
+
const MARKET_BY_SUBDOMAIN = {
|
|
104
|
+
ca: { country: "CA", language: "EN" },
|
|
105
|
+
fr: { country: "FR", language: "FR" },
|
|
106
|
+
} satisfies Record<string, Market>;
|
|
107
|
+
|
|
108
|
+
export function getMarketFromRequest(request: Request): Market {
|
|
109
|
+
const { hostname } = new URL(request.url);
|
|
110
|
+
const [subdomain] = hostname.toLowerCase().split(".");
|
|
111
|
+
|
|
112
|
+
return MARKET_BY_SUBDOMAIN[subdomain] ?? DEFAULT_MARKET;
|
|
113
|
+
}
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
---
|
|
117
|
+
|
|
118
|
+
## Per-Market Domains
|
|
119
|
+
|
|
120
|
+
Use this when markets have separate buyer-facing domains, like `example.com`, `example.ca`, and `example.fr`.
|
|
121
|
+
|
|
122
|
+
```ts
|
|
123
|
+
const MARKET_BY_HOST = {
|
|
124
|
+
"example.com": { country: "US", language: "EN" },
|
|
125
|
+
"example.ca": { country: "CA", language: "EN" },
|
|
126
|
+
"example.fr": { country: "FR", language: "FR" },
|
|
127
|
+
} satisfies Record<string, Market>;
|
|
128
|
+
|
|
129
|
+
export function getMarketFromRequest(request: Request): Market {
|
|
130
|
+
const { hostname } = new URL(request.url);
|
|
131
|
+
const host = hostname.toLowerCase();
|
|
132
|
+
|
|
133
|
+
return MARKET_BY_HOST[host] ?? DEFAULT_MARKET;
|
|
134
|
+
}
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
---
|
|
138
|
+
|
|
139
|
+
## Path Prefixes
|
|
140
|
+
|
|
141
|
+
Use this when markets share one domain and the market is encoded in the pathname, like `/en-ca/products/shirt` or `/fr-fr/products/shirt`.
|
|
142
|
+
|
|
143
|
+
```ts
|
|
144
|
+
type PathMarket = Market & {
|
|
145
|
+
pathPrefix: string;
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
const FIRST_PATH_SEGMENT_INDEX = 0;
|
|
149
|
+
|
|
150
|
+
const MARKET_BY_PATH_PREFIX = {
|
|
151
|
+
"en-ca": { country: "CA", language: "EN", pathPrefix: "/en-ca" },
|
|
152
|
+
"fr-fr": { country: "FR", language: "FR", pathPrefix: "/fr-fr" },
|
|
153
|
+
} satisfies Record<string, PathMarket>;
|
|
154
|
+
|
|
155
|
+
function getFirstPathSegment(pathname: string): string | undefined {
|
|
156
|
+
return pathname.split("/").filter(Boolean)[FIRST_PATH_SEGMENT_INDEX];
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
export function getMarketFromRequest(request: Request): PathMarket | Market {
|
|
160
|
+
const { pathname } = new URL(request.url);
|
|
161
|
+
const pathPrefix = getFirstPathSegment(pathname);
|
|
162
|
+
|
|
163
|
+
if (!pathPrefix) return DEFAULT_MARKET;
|
|
164
|
+
|
|
165
|
+
return MARKET_BY_PATH_PREFIX[pathPrefix.toLowerCase()] ?? DEFAULT_MARKET;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
export function localizePath(pathname: string, market: PathMarket | Market): string {
|
|
169
|
+
if (!("pathPrefix" in market)) return pathname;
|
|
170
|
+
|
|
171
|
+
const normalizedPathname = pathname.replace(/^\/+/, "");
|
|
172
|
+
return `${market.pathPrefix}/${normalizedPathname}`;
|
|
173
|
+
}
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
The router should strip or interpret the prefix before matching product and collection routes. Hydrogen's Storefront API variable injection uses `country` and `language`; `pathPrefix` is carried as a leading-slash app route prefix for helpers.
|
|
177
|
+
|
|
178
|
+
When the app uses custom Shopify resource paths, use the local `hydrogen-routing` skill. Keep market prefixes in `i18n.pathPrefix`, not in route template values.
|
|
179
|
+
|
|
180
|
+
---
|
|
181
|
+
|
|
182
|
+
## Framework Exceptions
|
|
183
|
+
|
|
184
|
+
Read the relevant reference before applying the generic `Request` examples in frameworks that do not expose the full incoming request to server code.
|
|
185
|
+
|
|
186
|
+
- **Next.js App Router** — read `references/nextjs.md` first. Server Components can read `headers()` and route `params`, but not the current URL or a standard `Request`; host-based markets, path-prefix markets, and raw URL fallback each need different wiring.
|
|
187
|
+
|
|
188
|
+
---
|
|
189
|
+
|
|
190
|
+
## Rules
|
|
191
|
+
|
|
192
|
+
- **Use whatever market strategy fits the store.** Hydrogen should not force domains, subdomains, pathnames, or detection policy.
|
|
193
|
+
- **Resolve the market on the server from a standard `Request`.** `new URL(request.url)` is enough for host and path strategies.
|
|
194
|
+
- **Use request-context `i18n` as the Storefront API boundary.** Prefer `createShopifyRequestContext({ request, i18n })`. Always provide a default market rather than letting it be undefined.
|
|
195
|
+
- **Use market-contextualized queries.** The Storefront client injects `country` and `language` variable values when the document declares `$country` and `$language`; it does not rewrite query text. Market-sensitive queries still need `@inContext(country: $country, language: $language)` or equivalent Storefront API context in the document.
|
|
196
|
+
- **Do not calculate currency locally.** Render `amount` and `currencyCode` returned by Shopify and format them with the local `hydrogen-money` skill's `formatMoney()` guidance.
|
|
197
|
+
- **Keep ShopifyScripts in the same market.** When the app renders Shopify browser runtime scripts, pass the resolved `country` and `language` into `ShopifyScripts` i18n so Shopify globals match Storefront API context.
|
|
198
|
+
- **Keep route templates prefix-free.** When route templates are configured, pass market prefixes through `i18n.pathPrefix`; do not bake prefixes such as `/en-ca` into template values.
|
|
199
|
+
- **Keep translations separate.** Shopify Markets context localizes Shopify data. Application UI strings still need the app's translation system.
|
|
200
|
+
- **Treat geolocation as a hint, not truth.** Buyers travel, use VPNs, and intentionally choose markets. Persist explicit choices when the app supports switching.
|
|
201
|
+
- **Ask before choosing the strategy.** If the app does not already make market selection clear, ask whether domains, subdomains, path prefixes, cookies, buyer preference, geolocation, or merchant config should own it before writing code.
|
|
202
|
+
|
|
203
|
+
---
|
|
204
|
+
|
|
205
|
+
## Testing
|
|
206
|
+
|
|
207
|
+
Test market resolution with plain `Request` objects. You do not need a framework test harness.
|
|
208
|
+
|
|
209
|
+
```ts
|
|
210
|
+
import { describe, expect, it } from "vitest";
|
|
211
|
+
|
|
212
|
+
describe("getMarketFromRequest", () => {
|
|
213
|
+
it("resolves a subdomain market", () => {
|
|
214
|
+
const request = new Request("https://ca.example.com/products/shirt");
|
|
215
|
+
|
|
216
|
+
expect(getMarketFromRequest(request)).toEqual({ country: "CA", language: "EN" });
|
|
217
|
+
});
|
|
218
|
+
});
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
Also test at least one Storefront API call through a mocked fetch and assert the GraphQL variables include the expected `country` and `language` when the query declares them.
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
# Next.js App Router
|
|
2
|
+
|
|
3
|
+
## Contents
|
|
4
|
+
|
|
5
|
+
- Host-Based Markets
|
|
6
|
+
- Path-Prefix Markets
|
|
7
|
+
- Raw URL Fallback
|
|
8
|
+
|
|
9
|
+
Next.js App Router Server Components do not receive a standard `Request` object or direct access to the current URL. Use the source that matches the market strategy:
|
|
10
|
+
|
|
11
|
+
- Host or subdomain markets: read the URL from Hydrogen's request context when the app proxy forwards it.
|
|
12
|
+
- Path-prefix markets: model the market as a route segment, such as `app/[market]/products/[handle]/page.tsx`, and read it from `params`.
|
|
13
|
+
- Raw URL markets: use a request-context handoff in `proxy.ts`; do not invent a second URL header.
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## Host-Based Markets
|
|
18
|
+
|
|
19
|
+
Use this for domain or subdomain routing, like `example.ca`, `fr.example.com`, or `ca.example.com`.
|
|
20
|
+
|
|
21
|
+
`proxy.ts` creates a request context from the `NextRequest`, forwards `requestContext.getForwardedRequestHeaders()`, and Server Components recreate the request context from `headers()`. That handoff includes the original URL.
|
|
22
|
+
|
|
23
|
+
```ts
|
|
24
|
+
// lib/markets.ts
|
|
25
|
+
type Market = {
|
|
26
|
+
country: string;
|
|
27
|
+
language: string;
|
|
28
|
+
pathPrefix?: string;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
const DEFAULT_MARKET = {
|
|
32
|
+
country: "US",
|
|
33
|
+
language: "EN",
|
|
34
|
+
} satisfies Market;
|
|
35
|
+
|
|
36
|
+
const MARKET_BY_HOST = {
|
|
37
|
+
"example.com": { country: "US", language: "EN" },
|
|
38
|
+
"example.ca": { country: "CA", language: "EN" },
|
|
39
|
+
"fr.example.com": { country: "FR", language: "FR" },
|
|
40
|
+
} satisfies Record<string, Market>;
|
|
41
|
+
|
|
42
|
+
export function getMarketFromHeaders(headers: Pick<Headers, "get">): Market {
|
|
43
|
+
const forwardedUrl = headers.get("x-storefront-url");
|
|
44
|
+
if (!forwardedUrl) return DEFAULT_MARKET;
|
|
45
|
+
|
|
46
|
+
const { hostname } = new URL(forwardedUrl);
|
|
47
|
+
const host = hostname.toLowerCase();
|
|
48
|
+
|
|
49
|
+
return MARKET_BY_HOST[host] ?? DEFAULT_MARKET;
|
|
50
|
+
}
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Use an allowlist like `MARKET_BY_HOST`; do not blindly trust request hosts for anything security-sensitive.
|
|
54
|
+
|
|
55
|
+
```ts
|
|
56
|
+
// lib/storefront.ts
|
|
57
|
+
import "server-only";
|
|
58
|
+
import {
|
|
59
|
+
createStorefrontClient,
|
|
60
|
+
createShopifyRequestContext,
|
|
61
|
+
} from "@shopify/hydrogen";
|
|
62
|
+
import { headers } from "next/headers";
|
|
63
|
+
import { cache } from "react";
|
|
64
|
+
|
|
65
|
+
import { storefrontConfig } from "./config";
|
|
66
|
+
import { getMarketFromHeaders } from "./markets";
|
|
67
|
+
|
|
68
|
+
export const getStorefrontClient = cache(async () => {
|
|
69
|
+
const requestHeaders = await headers();
|
|
70
|
+
const request = { headers: requestHeaders };
|
|
71
|
+
const requestContext = createShopifyRequestContext({
|
|
72
|
+
request,
|
|
73
|
+
i18n: getMarketFromHeaders(requestHeaders),
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
return createStorefrontClient({
|
|
77
|
+
type: "public",
|
|
78
|
+
requestContext,
|
|
79
|
+
config: {
|
|
80
|
+
storeDomain: storefrontConfig.storeDomain,
|
|
81
|
+
publicStorefrontToken: storefrontConfig.publicStorefrontToken,
|
|
82
|
+
},
|
|
83
|
+
});
|
|
84
|
+
});
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
`headers()` is a request-time API, so pages using this helper are dynamically rendered.
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
## Path-Prefix Markets
|
|
92
|
+
|
|
93
|
+
Use this for routes like `/en-ca/products/shirt` or `/fr-fr/products/shirt`. Model the market prefix as a route segment so Server Components can read it from `params` without `headers()`.
|
|
94
|
+
|
|
95
|
+
```ts
|
|
96
|
+
// lib/path-markets.ts
|
|
97
|
+
type Market = {
|
|
98
|
+
country: string;
|
|
99
|
+
language: string;
|
|
100
|
+
pathPrefix?: string;
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
const DEFAULT_MARKET = {
|
|
104
|
+
country: "US",
|
|
105
|
+
language: "EN",
|
|
106
|
+
} satisfies Market;
|
|
107
|
+
|
|
108
|
+
const MARKET_BY_PARAM = {
|
|
109
|
+
"en-ca": { country: "CA", language: "EN", pathPrefix: "/en-ca" },
|
|
110
|
+
"fr-fr": { country: "FR", language: "FR", pathPrefix: "/fr-fr" },
|
|
111
|
+
} satisfies Record<string, Market>;
|
|
112
|
+
|
|
113
|
+
export function getMarketFromParam(marketParam: string): Market {
|
|
114
|
+
return MARKET_BY_PARAM[marketParam.toLowerCase()] ?? DEFAULT_MARKET;
|
|
115
|
+
}
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
For static or ISR-cached pages, use a `private_no_buyer_context` client and pass the market from route params. The page can be prerendered when the route uses `generateStaticParams` and does not call request-time APIs like `headers()` or `cookies()`.
|
|
119
|
+
|
|
120
|
+
```ts
|
|
121
|
+
// lib/static-storefront.ts
|
|
122
|
+
import { createStorefrontClient, createShopifyRequestContext } from "@shopify/hydrogen";
|
|
123
|
+
|
|
124
|
+
import { getMarketFromParam } from "./path-markets";
|
|
125
|
+
|
|
126
|
+
export function createStaticStorefrontClient(marketParam: string) {
|
|
127
|
+
const requestContext = createShopifyRequestContext({
|
|
128
|
+
request: { headers: new Headers() },
|
|
129
|
+
i18n: getMarketFromParam(marketParam),
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
return createStorefrontClient({
|
|
133
|
+
type: "private_no_buyer_context",
|
|
134
|
+
requestContext,
|
|
135
|
+
config: {
|
|
136
|
+
storeDomain: process.env.NEXT_PUBLIC_STORE_DOMAIN!,
|
|
137
|
+
privateStorefrontToken: process.env.PRIVATE_STOREFRONT_API_TOKEN!,
|
|
138
|
+
},
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
Use the query shape from `SKILL.md`: declare `$country` and `$language`, use `@inContext`, and let the client inject the market variables. Use the private client with trusted buyer context instead when the page needs buyer-specific headers, cookies, or personalized data. That path becomes dynamic because it must read request-time data.
|
|
144
|
+
|
|
145
|
+
---
|
|
146
|
+
|
|
147
|
+
## Raw URL Fallback
|
|
148
|
+
|
|
149
|
+
Use raw URLs only when host headers or route params cannot represent the market, usually with rewrites or catch-all route setups.
|
|
150
|
+
|
|
151
|
+
Use this proxy handoff:
|
|
152
|
+
|
|
153
|
+
- In `proxy.ts`, create a request context from the `NextRequest`.
|
|
154
|
+
- Forward `requestContext.getForwardedRequestHeaders()` through `NextResponse.next({ request: { headers } })`.
|
|
155
|
+
- In Server Components, recreate a request-like object with `request: { headers: await headers() }`, resolve the market from the forwarded URL header, then create the client request context with that `i18n`.
|
|
156
|
+
|
|
157
|
+
`createShopifyRequestContext` already persists the URL through `x-storefront-url`, so do not set a parallel URL header unless the app cannot use the proxy handoff.
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: hydrogen-money
|
|
3
|
+
description: >
|
|
4
|
+
Guide for formatting Shopify money values in Hydrogen storefronts. Use when
|
|
5
|
+
rendering product prices, compare-at prices, cart totals, collection price
|
|
6
|
+
ranges, Shop Pay prices, or any MoneyV2 amount/currencyCode values.
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Money Formatting
|
|
10
|
+
|
|
11
|
+
Use Hydrogen's `formatMoney()` for Storefront API `MoneyV2` values. Never build money strings by concatenating currency symbols or computing totals client-side.
|
|
12
|
+
|
|
13
|
+
```ts
|
|
14
|
+
import { formatMoney, type MoneyV2 } from "@shopify/hydrogen";
|
|
15
|
+
|
|
16
|
+
// `locale` should come from the resolved market. Default only in
|
|
17
|
+
// single-market storefronts; market-aware stores must pass the active locale.
|
|
18
|
+
export function formatPrice(money: MoneyV2, locale = "en-US"): string {
|
|
19
|
+
return formatMoney(money, { locale }).toString();
|
|
20
|
+
}
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Rules
|
|
24
|
+
|
|
25
|
+
- Display server-provided money fields: `variant.price`, `variant.compareAtPrice`, `product.priceRange.minVariantPrice`, `line.cost.totalAmount`, `cart.cost.subtotalAmount`, etc.
|
|
26
|
+
- Do not multiply quantity by unit price in the browser. Cart totals are affected by discounts, duties, tax, rounding, and selling plans.
|
|
27
|
+
- Use the active market locale when the app has markets. Do not hardcode `en-US` in market-aware storefronts.
|
|
28
|
+
- Prefer a small app wrapper such as `formatPrice()` so locale and display options are consistent.
|
|
29
|
+
- Use `withoutTrailingZeros` only for presentation choices, never by editing amount strings manually.
|
|
30
|
+
- For price ranges, pass a readonly array of `MoneyV2` values to `formatMoney([...])`.
|
|
31
|
+
|
|
32
|
+
## Structured Output
|
|
33
|
+
|
|
34
|
+
`formatMoney()` returns an object that stringifies to the localized price. Use
|
|
35
|
+
`toString()` or template literals for normal UI. Call `formatMoney()` directly
|
|
36
|
+
or add an object-returning wrapper when the design needs split markup:
|
|
37
|
+
|
|
38
|
+
- `localizedString` - full display string, same as `toString()`.
|
|
39
|
+
- `amount` - localized numeric portion without currency.
|
|
40
|
+
- `numericAmount` - parsed number; do not use for cart totals or currency math.
|
|
41
|
+
- `currencySymbol`, `currencyNarrowSymbol`, `currencyName` - currency display variants.
|
|
42
|
+
- `parts` - `Intl.NumberFormatPart[]` for custom markup.
|
|
43
|
+
- `withoutTrailingZeros`, `withoutTrailingZerosAndCurrency` - presentation-only variants.
|
|
44
|
+
|
|
45
|
+
For ranges, `formatMoney([min, max], options)` returns an object that stringifies
|
|
46
|
+
to the localized range and exposes `min`, `max`, and `currencyCode`. Range
|
|
47
|
+
inputs must share one currency.
|
|
48
|
+
|
|
49
|
+
## Examples
|
|
50
|
+
|
|
51
|
+
```tsx
|
|
52
|
+
<p>{formatPrice(selectedVariant?.price ?? product.priceRange.minVariantPrice, locale)}</p>
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
```ts
|
|
56
|
+
const range = formatMoney(
|
|
57
|
+
[product.priceRange.minVariantPrice, product.priceRange.maxVariantPrice],
|
|
58
|
+
{ locale, withoutTrailingZeros: true },
|
|
59
|
+
).toString();
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Anti-Patterns
|
|
63
|
+
|
|
64
|
+
- `"$" + amount`
|
|
65
|
+
- `Number(amount).toFixed(2)`
|
|
66
|
+
- `line.quantity * Number(line.merchandise.price.amount)`
|
|
67
|
+
- Showing cart totals at full opacity while a related cart mutation is pending.
|
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: hydrogen-oxygen
|
|
3
|
+
description: >
|
|
4
|
+
Audit and adapt an existing Hydrogen storefront for Shopify Oxygen and local MiniOxygen. Use when asked to make a
|
|
5
|
+
server-capable Hydrogen project Oxygen-compatible, add or repair its Worker server entrypoint, configure MiniOxygen,
|
|
6
|
+
remove Node runtime assumptions, wire Worker environment, cache, and waitUntil, or verify dev, preview, and deploy
|
|
7
|
+
behavior.
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Making A Hydrogen App Oxygen-Compatible
|
|
11
|
+
|
|
12
|
+
Treat Oxygen as a Web Worker runtime, not a Node server. Preserve the app's routes and storefront behavior while
|
|
13
|
+
adapting its server runtime, build output, and request lifecycle.
|
|
14
|
+
|
|
15
|
+
Master checklist:
|
|
16
|
+
|
|
17
|
+
```text
|
|
18
|
+
- [ ] Inspect the framework, server entrypoint, and build target
|
|
19
|
+
- [ ] Read the matching framework reference when available
|
|
20
|
+
- [ ] Produce an Oxygen-compatible module Worker at `<root>/server.ts` or configure its custom path
|
|
21
|
+
- [ ] Produce one server bundle and a public assets directory
|
|
22
|
+
- [ ] Run the Worker locally with MiniOxygen
|
|
23
|
+
- [ ] Thread env, cache, and waitUntil through each request
|
|
24
|
+
- [ ] Create request-dependent Shopify resources per request
|
|
25
|
+
- [ ] Remove Node-only runtime assumptions
|
|
26
|
+
- [ ] Typecheck and build
|
|
27
|
+
- [ ] Exercise dynamic routes in dev and preview
|
|
28
|
+
- [ ] Run Hydrogen smoke tests
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Inspect The App
|
|
32
|
+
|
|
33
|
+
Run from the app root. Read `package.json`, framework and bundler configuration, server and client entries, SSR setup,
|
|
34
|
+
request middleware, environment declarations, deployment scripts, and the existing production adapter. If there is no
|
|
35
|
+
`package.json`, stop and tell the user to run the skill from the app root.
|
|
36
|
+
|
|
37
|
+
Identify how the framework:
|
|
38
|
+
|
|
39
|
+
- turns an incoming Web `Request` into the app's request handler
|
|
40
|
+
- renders SSR responses and hydrates the browser
|
|
41
|
+
- passes request-scoped context to loaders, middleware, or server functions
|
|
42
|
+
- builds and selects its server entrypoint
|
|
43
|
+
- serves static assets alongside dynamic Worker responses
|
|
44
|
+
|
|
45
|
+
Read [references/react-router.md](references/react-router.md) for a React Router framework-mode app. For another
|
|
46
|
+
framework, apply the generic Oxygen contract below through its Worker adapter and existing conventions. Do not copy
|
|
47
|
+
React Router filenames or APIs into another framework. If no Worker adapter or build target exists, identify that gap
|
|
48
|
+
explicitly before changing application code.
|
|
49
|
+
|
|
50
|
+
## Preserve App Behavior
|
|
51
|
+
|
|
52
|
+
Keep existing routes, middleware, cart, customer accounts, analytics, search, redirects, cookies, and response headers
|
|
53
|
+
unless the user explicitly asks to remove them. Reuse the app's context and middleware architecture where possible. Do
|
|
54
|
+
not replace the app with a starter or rewrite framework-owned routing merely to change runtimes.
|
|
55
|
+
|
|
56
|
+
Keep route-template wiring used by `handleShopifyRedirects`, Shopify scripts, and predictive search. Oxygen compatibility
|
|
57
|
+
does not make those routes optional.
|
|
58
|
+
|
|
59
|
+
## Implement The Oxygen Worker Contract
|
|
60
|
+
|
|
61
|
+
Use `<root>/server.ts` as the default Worker entrypoint. Oxygen and MiniOxygen discover that path without extra
|
|
62
|
+
configuration. If the entrypoint lives elsewhere, configure the same project-relative path everywhere it is consumed:
|
|
63
|
+
|
|
64
|
+
- pass `entry` to MiniOxygen, for example `oxygen({ entry: "./src/worker.ts" })`
|
|
65
|
+
- pass `--entry ./src/worker.ts` to Shopify Hydrogen CLI commands that run or deploy the Worker
|
|
66
|
+
|
|
67
|
+
Do not rely on a framework's server-file convention to make a custom entrypoint discoverable by Oxygen.
|
|
68
|
+
|
|
69
|
+
Produce a module Worker whose default export handles requests with the platform values Oxygen provides:
|
|
70
|
+
|
|
71
|
+
```ts
|
|
72
|
+
export default {
|
|
73
|
+
async fetch(request: Request, env: Env, executionContext: ExecutionContext) {
|
|
74
|
+
const waitUntil = executionContext.waitUntil.bind(executionContext);
|
|
75
|
+
const cache = await caches.open("hydrogen");
|
|
76
|
+
|
|
77
|
+
return handleRequest(request, { env, waitUntil, cache });
|
|
78
|
+
},
|
|
79
|
+
};
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Adapt `handleRequest` and the context shape to the framework. The server build must bundle this entry as a Web-compatible
|
|
83
|
+
module Worker and return a standard `Response`. Use Web APIs such as `Request`, `Response`, `Headers`, `URL`, `fetch`,
|
|
84
|
+
Web Crypto, and Web streams throughout runtime code.
|
|
85
|
+
|
|
86
|
+
Keep server rendering Web-compatible. Use the framework's Worker renderer or Web-stream renderer instead of a Node
|
|
87
|
+
stream renderer. Add or change a browser hydration entry only when the framework requires it; see the matching reference
|
|
88
|
+
for exact entry files.
|
|
89
|
+
|
|
90
|
+
## Configure MiniOxygen And Deployment
|
|
91
|
+
|
|
92
|
+
Use MiniOxygen to run the same Worker contract locally. For a Vite app:
|
|
93
|
+
|
|
94
|
+
- preserve an existing compatible `@shopify/mini-oxygen` version; otherwise install the latest available version
|
|
95
|
+
- add `@shopify/oxygen-workers-types`
|
|
96
|
+
- add `oxygen()` from `@shopify/mini-oxygen/vite` to the Vite plugins
|
|
97
|
+
- make both development and built preview modes execute the Worker entrypoint
|
|
98
|
+
|
|
99
|
+
Require MiniOxygen 4.2.0 or newer for the behavior described here. Do not replace a compatible existing version merely
|
|
100
|
+
to change its version range.
|
|
101
|
+
|
|
102
|
+
Use plain `oxygen()` when the app uses `<root>/server.ts` and does not need explicit binding configuration; MiniOxygen
|
|
103
|
+
uses Vite's environment loading when no `env` option is provided. Values can come from the active mode's `.env` files
|
|
104
|
+
and from variables already exported into `process.env`; Vite merges both sources. Worker runtime code receives the
|
|
105
|
+
result through its `env` argument rather than reading `process.env`. Otherwise pass the custom `entry` or bindings
|
|
106
|
+
explicitly. For a non-Vite build, use the framework's Worker adapter or MiniOxygen integration instead of introducing
|
|
107
|
+
Vite only to copy another framework's setup.
|
|
108
|
+
|
|
109
|
+
Add `@shopify/cli` and a `shopify hydrogen deploy` script when the project does not already have a supported Oxygen
|
|
110
|
+
deployment path. Use the latest available `@shopify/cli`. Preserve the installed `@shopify/hydrogen` version unless the
|
|
111
|
+
user separately asks to upgrade it.
|
|
112
|
+
|
|
113
|
+
## Produce Deployable Build Output
|
|
114
|
+
|
|
115
|
+
Build two deployable outputs:
|
|
116
|
+
|
|
117
|
+
- one bundled Worker server module
|
|
118
|
+
- one directory containing public client assets
|
|
119
|
+
|
|
120
|
+
Configure the server build to avoid code splitting. Oxygen expects a single executable Worker bundle rather than a
|
|
121
|
+
server entry that depends on additional server chunks.
|
|
122
|
+
|
|
123
|
+
### Default Vite Layout
|
|
124
|
+
|
|
125
|
+
For the common Vite setup with `<root>/server.ts`, let the Oxygen plugin detect output locations from Vite
|
|
126
|
+
configuration. `vite preview` and `shopify hydrogen deploy` generally need no `previewEntry`, `--assets-dir`, or
|
|
127
|
+
`--worker-dir` overrides. When Vite does not expose custom locations, Oxygen prefers this fallback layout:
|
|
128
|
+
|
|
129
|
+
```text
|
|
130
|
+
dist/
|
|
131
|
+
├── client/
|
|
132
|
+
└── server/
|
|
133
|
+
└── index.js
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
The Worker file may use `.js` or `.mjs`. A build may also emit `oxygen.json` beside the Worker as a compatibility-date
|
|
137
|
+
artifact; preserve and deploy it with the server output.
|
|
138
|
+
|
|
139
|
+
### Custom Or Non-Default Layout
|
|
140
|
+
|
|
141
|
+
Only add explicit output configuration when the framework emits a layout that Oxygen or MiniOxygen does not discover:
|
|
142
|
+
|
|
143
|
+
- pass the built Worker file to MiniOxygen as `previewEntry` so `vite preview` executes it
|
|
144
|
+
- pass the asset directory to deployment with `--assets-dir <path>`
|
|
145
|
+
- pass the Worker directory to deployment with `--worker-dir <path>`
|
|
146
|
+
|
|
147
|
+
For example:
|
|
148
|
+
|
|
149
|
+
```ts
|
|
150
|
+
oxygen({
|
|
151
|
+
entry: "./src/worker.ts",
|
|
152
|
+
previewEntry: "./build/server/index.mjs",
|
|
153
|
+
});
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
```sh
|
|
157
|
+
shopify hydrogen deploy --assets-dir ./build/client --worker-dir ./build/server
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
Treat `entry` and `previewEntry` as different stages: `entry` points to the source Worker used during development;
|
|
161
|
+
`previewEntry` points to the built Worker module. The directory passed to `--worker-dir` must contain `index.js` or
|
|
162
|
+
`index.mjs` at its root. Pass directories, not individual files, to `--assets-dir` and `--worker-dir`.
|
|
163
|
+
|
|
164
|
+
## Keep Request State Request-Scoped
|
|
165
|
+
|
|
166
|
+
Pass the incoming `env`, bound `waitUntil`, and an Oxygen cache through the framework's request context. Pass `cache`
|
|
167
|
+
and `waitUntil` together in the Hydrogen client config:
|
|
168
|
+
|
|
169
|
+
```ts
|
|
170
|
+
createStorefrontClient({
|
|
171
|
+
// Existing client options...
|
|
172
|
+
config: {
|
|
173
|
+
// Existing config options...
|
|
174
|
+
cache,
|
|
175
|
+
waitUntil,
|
|
176
|
+
},
|
|
177
|
+
});
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
The `Cache` returned by `caches.open("hydrogen")` is accepted directly by Hydrogen clients. Remove custom cache
|
|
181
|
+
adapters and process-local cache dependencies such as `lru-cache`; do not wrap the Workers cache in an adapter.
|
|
182
|
+
`waitUntil` lets background cache revalidation continue after the response has been returned, so pass the bound
|
|
183
|
+
function whenever the platform provides it.
|
|
184
|
+
|
|
185
|
+
Create values that depend on the request, environment, headers, locale, session, or response headers inside the request
|
|
186
|
+
lifecycle, including:
|
|
187
|
+
|
|
188
|
+
- `createShopifyRequestContext(...)`
|
|
189
|
+
- `createStorefrontClient(...)`
|
|
190
|
+
- `createCustomerAccountClient(...)`
|
|
191
|
+
- cart and customer session managers
|
|
192
|
+
- request-specific response header collections
|
|
193
|
+
|
|
194
|
+
Keep only pure constants and stateless factories at module scope. Use `caches.open("hydrogen")` instead of a process-local
|
|
195
|
+
LRU cache for Hydrogen request caching, and use `executionContext.waitUntil` for background cache work.
|
|
196
|
+
|
|
197
|
+
## Configure Environment And Types
|
|
198
|
+
|
|
199
|
+
Declare the Worker's actual `Env` bindings and include `@shopify/oxygen-workers-types` in app runtime types. Keep
|
|
200
|
+
`.env.example` committed with placeholders and `.env` ignored. Let Oxygen provide deployed secrets as environment
|
|
201
|
+
bindings and MiniOxygen provide local bindings.
|
|
202
|
+
|
|
203
|
+
Read server secrets from the request's `env`, never from `process.env` or browser-importable modules. Keep public browser
|
|
204
|
+
configuration separate from private Worker bindings. Start from the existing TypeScript config rather than replacing it;
|
|
205
|
+
retain Node types where build tooling genuinely needs them. Node and Worker types can usually coexist when one TypeScript
|
|
206
|
+
program includes both Worker runtime code and Vite or build files. If their globals conflict, use separate runtime and
|
|
207
|
+
build-tool tsconfigs instead of masking the conflict with `skipLibCheck`.
|
|
208
|
+
|
|
209
|
+
## Remove Incompatible Runtime Assumptions
|
|
210
|
+
|
|
211
|
+
Inspect server runtime code for:
|
|
212
|
+
|
|
213
|
+
- `process`, `Buffer`, `node:*`, filesystem, and Node crypto APIs
|
|
214
|
+
- Node streams and Node-specific SSR renderers
|
|
215
|
+
- framework Node server adapters and start commands
|
|
216
|
+
- CommonJS globals or dependencies that require `module` or `require` at runtime
|
|
217
|
+
- in-memory caches used in place of the Workers Cache API
|
|
218
|
+
- classic Hydrogen runtime or Vite integrations
|
|
219
|
+
|
|
220
|
+
Replace each runtime dependency with a Web API or the framework's Worker adapter. Do not mechanically remove packages
|
|
221
|
+
used only by build configuration, tests, or transitive dependencies.
|
|
222
|
+
|
|
223
|
+
## Verify The Result
|
|
224
|
+
|
|
225
|
+
Run the applicable formatter, lint, typecheck, GraphQL validation, tests, and production build. Run both development and
|
|
226
|
+
built preview modes under MiniOxygen, then request routes that exercise server rendering and Hydrogen data rather than
|
|
227
|
+
only static assets.
|
|
228
|
+
|
|
229
|
+
At minimum, check `/`, one product, one collection, `/search`, `/cart`, and `/account` when those routes exist. Confirm
|
|
230
|
+
environment bindings load, dynamic responses come from the Worker, mutations preserve cookies and headers, cache work
|
|
231
|
+
uses `waitUntil`, and no Node or CommonJS runtime error appears. A server starting is not sufficient evidence that the
|
|
232
|
+
Worker request path works.
|
|
233
|
+
|
|
234
|
+
Use the local `hydrogen-smoke-test` skill for broader Hydrogen request-handler, cart, analytics, markets, and production
|
|
235
|
+
checks. Exercise mutations through the real cart UI or the framework's cart action rather than hand-crafting an internal
|
|
236
|
+
Hydrogen payload; follow that skill for the concrete cookie and header checks. Fix failures and rerun the affected checks.
|
|
237
|
+
Report every validation step that could not be completed and why.
|
|
238
|
+
|
|
239
|
+
## Stop Conditions
|
|
240
|
+
|
|
241
|
+
- No `package.json` exists at the current app root.
|
|
242
|
+
- The app is static-only and has no server request lifecycle to deploy.
|
|
243
|
+
- The framework cannot produce a module Worker and no suitable adapter or server-build hook is available.
|
|
244
|
+
- Required production secrets are unavailable for live route verification; complete static/build verification and
|
|
245
|
+
report runtime checks as blocked instead of inventing values.
|