Releases: Shopify/hydrogen
[email protected]
Patch Changes
- Bump to get new cli package version by @wizardlyhel
@shopify/[email protected]
Patch Changes
- Bump to get new cli package version by @wizardlyhel
@shopify/[email protected]
[email protected]
Patch Changes
-
Stabilize
getSitemap
,getSitemapIndex
and implement on skeleton (#2589) by @juanpprieto- Update the
getSitemapIndex
at/app/routes/[sitemap.xml].tsx
- import {unstable__getSitemapIndex as getSitemapIndex} from '@shopify/hydrogen'; + import {getSitemapIndex} from '@shopify/hydrogen';
- Update the
getSitemap
at/app/routes/sitemap.$type.$page[.xml].tsx
- import {unstable__getSitemap as getSitemap} from '@shopify/hydrogen'; + import {getSitemap} from '@shopify/hydrogen';
For a reference implementation please see the skeleton template sitemap routes
- Update the
-
Breaking change by @wizardlyhel
Set up Customer Privacy without the Shopify's cookie banner by default.
If you are using Shopify's cookie banner to handle user consent in your app, you need to set
withPrivacyBanner: true
to the consent config. Without this update, the Shopify cookie banner will not appear.return defer({ ... consent: { checkoutDomain: env.PUBLIC_CHECKOUT_DOMAIN, storefrontAccessToken: env.PUBLIC_STOREFRONT_API_TOKEN, + withPrivacyBanner: true, // localize the privacy banner country: args.context.storefront.i18n.country, language: args.context.storefront.i18n.language, }, });
-
Update to 2024-10 SFAPI (#2570) by @wizardlyhel
-
Breaking change by @frandiox
Update
createWithCache
to make it harder to accidentally cache undesired results.request
is now mandatory prop when initializingcreateWithCache
.// server.ts export default { async fetch( request: Request, env: Env, executionContext: ExecutionContext, ): Promise<Response> { try { // ... - const withCache = createWithCache({cache, waitUntil}); + const withCache = createWithCache({cache, waitUntil, request});
createWithCache
now returns an object with two utility functions:withCache.run
andwithCache.fetch
. Both have a new propshouldCacheResult
that must be defined.The original
withCache
callback function is nowwithCache.run
. This is useful to run multiple fetch calls and merge their responses, or run any arbitrary code. It caches anything you return, but you can throw if you don't want to cache anything.const withCache = createWithCache({cache, waitUntil, request}); const fetchMyCMS = (query) => { - return withCache(['my-cms', query], CacheLong(), async (params) => { + return withCache.run({ + cacheKey: ['my-cms', query], + cacheStrategy: CacheLong(), + // Cache if there are no data errors or a specific data that make this result not suited for caching + shouldCacheResult: (result) => !result?.errors, + }, async(params) => { const response = await fetch('my-cms.com/api', { method: 'POST', body: query, }); if (!response.ok) throw new Error(response.statusText); const {data, error} = await response.json(); if (error || !data) throw new Error(error ?? 'Missing data'); params.addDebugData({displayName: 'My CMS query', response}); return data; }); };
New
withCache.fetch
is for caching simple fetch requests. This method caches the responses if they are OK responses, and you can passshouldCacheResponse
,cacheKey
, etc. to modify behavior.data
is the consumed body of the response (we need to consume to cache it).const withCache = createWithCache({cache, waitUntil, request}); const {data, response} = await withCache.fetch<{data: T; error: string}>( 'my-cms.com/api', { method: 'POST', headers: {'Content-type': 'application/json'}, body, }, { cacheStrategy: CacheLong(), // Cache if there are no data errors or a specific data that make this result not suited for caching shouldCacheResponse: (result) => !result?.error, cacheKey: ['my-cms', body], displayName: 'My CMS query', }, );
-
Breaking change by @wizardlyhel
Deprecate usages of
product.options.values
and useproduct.options.optionValues
instead.- Update your product graphql query to use the new
optionValues
field.
const PRODUCT_FRAGMENT = `#graphql fragment Product on Product { id title options { name - values + optionValues { + name + } }
- Update your
<VariantSelector>
to use the newoptionValues
field.
<VariantSelector handle={product.handle} - options={product.options.filter((option) => option.values.length > 1)} + options={product.options.filter((option) => option.optionValues.length > 1)} variants={variants} >
- Update your product graphql query to use the new
-
Updated dependencies [
d97cd56e
,809c9f3d
,8c89f298
,a253ef97
,84a66b1e
,227035e7
,ac12293c
,c7c9f2eb
,76cd4f9b
,8337e534
]:- @Shopify/hydrogen@2024.10.0
- @shopify/[email protected]
@shopify/[email protected]
Patch Changes
- Bump package versions by @wizardlyhel
@shopify/[email protected]
Minor Changes
-
[Breaking change] by @wizardlyhel
Support worker compatibility date that aligns with SFAPI release.
Starting from this major version, on each deploy to Oxygen, Hydrogen will be on Cloudflare worker compatibility date
2024-10-01
. Onwards, Hydrogen will update worker compatibility date on every SFAPI release.There is no specific project update that needs to be done in order to get this feature. However, please ensure your project is working properly in an Oxygen deployment when updating to this Hydrogen version. (#2380)
@shopify/[email protected]
Patch Changes
-
Add optional headers param for logout redirect (#2602) by @coryagami
-
Stabilize
getSitemap
,getSitemapIndex
and implement on skeleton (#2589) by @juanpprieto- Update the
getSitemapIndex
at/app/routes/[sitemap.xml].tsx
- import {unstable__getSitemapIndex as getSitemapIndex} from '@shopify/hydrogen'; + import {getSitemapIndex} from '@shopify/hydrogen';
- Update the
getSitemap
at/app/routes/sitemap.$type.$page[.xml].tsx
- import {unstable__getSitemap as getSitemap} from '@shopify/hydrogen'; + import {getSitemap} from '@shopify/hydrogen';
For a reference implementation please see the skeleton template sitemap routes
- Update the
-
Update
<ProductPrice>
to remove deprecated code usage forpriceV2
andcompareAtPriceV2
. Remove export forgetCustomerPrivacy
. (#2601) by @wizardlyhel -
Breaking change by @wizardlyhel
Set up Customer Privacy without the Shopify's cookie banner by default.
If you are using Shopify's cookie banner to handle user consent in your app, you need to set
withPrivacyBanner: true
to the consent config. Without this update, the Shopify cookie banner will not appear.return defer({ ... consent: { checkoutDomain: env.PUBLIC_CHECKOUT_DOMAIN, storefrontAccessToken: env.PUBLIC_STOREFRONT_API_TOKEN, + withPrivacyBanner: true, // localize the privacy banner country: args.context.storefront.i18n.country, language: args.context.storefront.i18n.language, }, });
-
Update to 2024-10 SFAPI (#2570) by @wizardlyhel
-
Breaking change by @frandiox
Update
createWithCache
to make it harder to accidentally cache undesired results.request
is now mandatory prop when initializingcreateWithCache
.// server.ts export default { async fetch( request: Request, env: Env, executionContext: ExecutionContext, ): Promise<Response> { try { // ... - const withCache = createWithCache({cache, waitUntil}); + const withCache = createWithCache({cache, waitUntil, request});
createWithCache
now returns an object with two utility functions:withCache.run
andwithCache.fetch
. Both have a new propshouldCacheResult
that must be defined.The original
withCache
callback function is nowwithCache.run
. This is useful to run multiple fetch calls and merge their responses, or run any arbitrary code. It caches anything you return, but you can throw if you don't want to cache anything.const withCache = createWithCache({cache, waitUntil, request}); const fetchMyCMS = (query) => { - return withCache(['my-cms', query], CacheLong(), async (params) => { + return withCache.run({ + cacheKey: ['my-cms', query], + cacheStrategy: CacheLong(), + // Cache if there are no data errors or a specific data that make this result not suited for caching + shouldCacheResult: (result) => !result?.errors, + }, async(params) => { const response = await fetch('my-cms.com/api', { method: 'POST', body: query, }); if (!response.ok) throw new Error(response.statusText); const {data, error} = await response.json(); if (error || !data) throw new Error(error ?? 'Missing data'); params.addDebugData({displayName: 'My CMS query', response}); return data; }); };
New
withCache.fetch
is for caching simple fetch requests. This method caches the responses if they are OK responses, and you can passshouldCacheResponse
,cacheKey
, etc. to modify behavior.data
is the consumed body of the response (we need to consume to cache it).const withCache = createWithCache({cache, waitUntil, request}); const {data, response} = await withCache.fetch<{data: T; error: string}>( 'my-cms.com/api', { method: 'POST', headers: {'Content-type': 'application/json'}, body, }, { cacheStrategy: CacheLong(), // Cache if there are no data errors or a specific data that make this result not suited for caching shouldCacheResponse: (result) => !result?.error, cacheKey: ['my-cms', body], displayName: 'My CMS query', }, );
-
Breaking change by @wizardlyhel
Deprecate usages of
product.options.values
and useproduct.options.optionValues
instead.- Update your product graphql query to use the new
optionValues
field.
const PRODUCT_FRAGMENT = `#graphql fragment Product on Product { id title options { name - values + optionValues { + name + } }
- Update your
<VariantSelector>
to use the newoptionValues
field.
<VariantSelector handle={product.handle} - options={product.options.filter((option) => option.values.length > 1)} + options={product.options.filter((option) => option.optionValues.length > 1)} variants={variants} >
- Update your product graphql query to use the new
-
Add utility functions
decodeEncodedVariant
andisOptionValueCombinationInEncodedVariant
for parsingproduct.encodedVariantExistence
andproduct.encodedVariantAvailability
fields. (#2425) by @lhoffbeck -
Breaking change by @wizardlyhel
Update all cart mutation methods from
createCartHandler
to return cart warnings.As of API version 2024-10, inventory errors about stock levels will no longer be included in the
userErrors
of cart mutations. Inventory errors will now be available in a new return fieldwarnings
and will contain explicit code values ofMERCHANDISE_NOT_ENOUGH_STOCK
orMERCHANDISE_OUT_OF_STOCK
. Reference: https://shopify.dev/changelog/cart-warnings-in-storefront-api-cart -
Updated dependencies [
8c89f298
,84a66b1e
,76cd4f9b
]:- @shopify/[email protected]
@shopify/[email protected]
Patch Changes
-
Update
<ProductPrice>
to remove deprecated code usage forpriceV2
andcompareAtPriceV2
. Remove export forgetCustomerPrivacy
. (#2601) by @wizardlyhel -
Update to 2024-10 SFAPI (#2570) by @wizardlyhel
-
Add utility functions
decodeEncodedVariant
andisOptionValueCombinationInEncodedVariant
for parsingproduct.encodedVariantExistence
andproduct.encodedVariantAvailability
fields. (#2425) by @lhoffbeck
@shopify/[email protected]
@shopify/[email protected]
Patch Changes
- Bump package versions by @wizardlyhel