Releases: Shopify/hydrogen
skeleton@2025.1.2
Patch Changes
-
Updated dependencies [
128dfcd6
]:- @Shopify/hydrogen@2025.1.2
@shopify/hydrogen@2025.1.2
Patch Changes
-
Update cli dependencies (#2766) by @juanpprieto
-
Updated dependencies [
128dfcd6
]:- @shopify/hydrogen-react@2025.1.2
@shopify/hydrogen-react@2025.1.2
Patch Changes
- Update cli dependencies (#2766) by @juanpprieto
@shopify/create-hydrogen@5.0.17
Patch Changes
- Update cli-hydrogen & create-hydrogen for latest cli (#2766) by @juanpprieto
@shopify/cli-hydrogen@9.0.8
Patch Changes
-
Update plugin-cloudflare by @juanpprieto
-
Update cli-hydrogen & create-hydrogen for latest cli (#2766) by @juanpprieto
@shopify/cli-hydrogen@9.0.7
Patch Changes
- Fixed a regression in
hydrogen build
where the environment variableHYDROGEN_ASSET_BASE_URL
was ignored when used as build command when deploying. (#2758) by @vincentezw
skeleton@2025.1.1
Patch Changes
-
Upgrade eslint to version 9 and unify eslint config across all packages (with the exception of the skeleton, which still keeps its own config) (#2716) by @liady
-
Bump remix version (#2740) by @wizardlyhel
-
Turn on Remix
v3_singleFetch
future flag (#2708) by @wizardlyhelRemix single fetch migration quick guide: https://remix.run/docs/en/main/start/future-flags#v3_singlefetch
Remix single fetch migration guide: https://remix.run/docs/en/main/guides/single-fetchNote: If you have any routes that appends (or looks for) a search param named
_data
, make sure to rename it to something else.-
In your
vite.config.ts
, add the single fetch future flag.+ declare module "@remix-run/server-runtime" { + interface Future { + v3_singleFetch: true; + } + } export default defineConfig({ plugins: [ hydrogen(), oxygen(), remix({ presets: [hydrogen.preset()], future: { v3_fetcherPersist: true, v3_relativeSplatPath: true, v3_throwAbortReason: true, v3_lazyRouteDiscovery: true, + v3_singleFetch: true, }, }), tsconfigPaths(), ],
-
In your
entry.server.tsx
, addnonce
to the<RemixServer>
.const body = await renderToReadableStream( <NonceProvider> <RemixServer context={remixContext} url={request.url} + nonce={nonce} /> </NonceProvider>,
-
Update the
shouldRevalidate
function inroot.tsx
.Defaulting to no revalidation for root loader data to improve performance. When using this feature, you risk your UI getting out of sync with your server. Use with caution. If you are uncomfortable with this optimization, update the
return false;
toreturn defaultShouldRevalidate;
instead.For more details see: https://remix.run/docs/en/main/route/should-revalidate
export const shouldRevalidate: ShouldRevalidateFunction = ({ formMethod, currentUrl, nextUrl, - defaultShouldRevalidate, }) => { // revalidate when a mutation is performed e.g add to cart, login... if (formMethod && formMethod !== 'GET') return true; // revalidate when manually revalidating via useRevalidator if (currentUrl.toString() === nextUrl.toString()) return true; - return defaultShouldRevalidate; + return false; };
-
Update
cart.tsx
to add a headers export and update todata
import usage.import { - json, + data, type LoaderFunctionArgs, type ActionFunctionArgs, type HeadersFunction } from '@shopify/remix-oxygen'; + export const headers: HeadersFunction = ({actionHeaders}) => actionHeaders; export async function action({request, context}: ActionFunctionArgs) { ... - return json( + return data( { cart: cartResult, errors, warnings, analytics: { cartId, }, }, {status, headers}, ); } export async function loader({context}: LoaderFunctionArgs) { const {cart} = context; - return json(await cart.get()); + return await cart.get(); }
-
Deprecate
json
anddefer
import usage from@shopify/remix-oxygen
.Remove
json()
/defer()
in favor of raw objects.Single Fetch supports JSON objects and Promises out of the box, so you can return the raw data from your loader/action functions:
- import {json} from "@shopify/remix-oxygen"; export async function loader({}: LoaderFunctionArgs) { let tasks = await fetchTasks(); - return json(tasks); + return tasks; }
- import {defer} from "@shopify/remix-oxygen"; export async function loader({}: LoaderFunctionArgs) { let lazyStuff = fetchLazyStuff(); let tasks = await fetchTasks(); - return defer({ tasks, lazyStuff }); + return { tasks, lazyStuff }; }
If you were using the second parameter of json/defer to set a custom status or headers on your response, you can continue doing so via the new data API:
- import {json} from "@shopify/remix-oxygen"; + import {data, type HeadersFunction} from "@shopify/remix-oxygen"; + /** + * If your loader or action is returning a response with headers, + * make sure to export a headers function that merges your headers + * on your route. Otherwise, your headers may be lost. + * Remix doc: https://remix.run/docs/en/main/route/headers + **/ + export const headers: HeadersFunction = ({loaderHeaders}) => loaderHeaders; export async function loader({}: LoaderFunctionArgs) { let tasks = await fetchTasks(); - return json(tasks, { + return data(tasks, { headers: { "Cache-Control": "public, max-age=604800" } }); }
-
If you are using legacy customer account flow or multipass, there are a couple more files that requires updating:
In
root.tsx
androutes/account.tsx
, add aheaders
export forloaderHeaders
.+ export const headers: HeadersFunction = ({loaderHeaders}) => loaderHeaders;
In
routes/account_.register.tsx
, add aheaders
export foractionHeaders
.+ export const headers: HeadersFunction = ({actionHeaders}) => actionHeaders;
-
If you are using multipass, in
routes/account_.login.multipass.tsx
a. export a
headers
export+ export const headers: HeadersFunction = ({actionHeaders}) => actionHeaders;
b. Update all
json
response wrapper toremixData
import { - json, + data as remixData, } from '@shopify/remix-oxygen'; - return json( + return remixData( ... );
-
-
Updated dependencies [
3af2e453
,6bff6b62
,cd65685c
,8c717570
,4e81bd1b
,3ea25820
]:- @Shopify/hydrogen@2025.1.1
- @shopify/remix-oxygen@2.0.11
@shopify/remix-oxygen@2.0.11
Patch Changes
-
Bump remix version (#2740) by @wizardlyhel
-
Turn on Remix
v3_singleFetch
future flag (#2708) by @wizardlyhel
@shopify/hydrogen@2025.1.1
Patch Changes
-
Update
getProductOptions
to handle divergent product options. (#2747) by @wizardlyhel -
Added the ability to optionally provide
language
data tocreateCustomerAccountClient
, and automatically pass it down to it fromcreateHydrogenContext
. (#2746) by @ruggishopIf present, the provided
language
will be used to set theuilocales
property in the Customer Account API request.// Optional: provide language data to the constructor const customerAccount = createCustomerAccountClient({ // ... language, });
Calls to
login()
will use the providedlanguage
without having to pass it explicitly viauiLocales
; however, if thelogin()
method is
already using itsuilocales
property, thelanguage
parameter coming from the context/constructor will be ignored. If nothing is explicitly passed,login()
will default tocontext.i18n.language
.export async function loader({request, context}: LoaderFunctionArgs) { return context.customerAccount.login({ uiLocales: 'FR', // will be used instead of the one coming from the context }); }
-
Upgrade eslint to version 9 and unify eslint config across all packages (with the exception of the skeleton, which still keeps its own config) (#2716) by @liady
-
Bump remix version (#2740) by @wizardlyhel
-
Turn on Remix
v3_singleFetch
future flag (#2708) by @wizardlyhel -
B2B methods and props are now stable. Warnings are in place for unstable usages and will be removed completely in the next major version. (#2736) by @dustinfirman
-
Search for anywhere using
UNSTABLE_getBuyer
andUNSTABLE_setBuyer
is update accordingly.- customerAccount.UNSTABLE_getBuyer(); + customerAccount.getBuyer() - customerAccount.UNSTABLE_setBuyer({ + customerAccount.setBuyer({ companyLocationId, });
-
Update
createHydrogenContext
to remove theunstableB2b
optionconst hydrogenContext = createHydrogenContext({ env, request, cache, waitUntil, session, i18n: {language: 'EN', country: 'US'}, - customerAccount: { - unstableB2b: true, - }, cart: { queryFragment: CART_QUERY_FRAGMENT, }, });
-
-
Updated dependencies [
3af2e453
,cd65685c
]:- @shopify/hydrogen-react@2025.1.1
@shopify/hydrogen-react@2025.1.1
Patch Changes
-
Update
getProductOptions
to handle divergent product options. (#2747) by @wizardlyhel -
Upgrade eslint to version 9 and unify eslint config across all packages (with the exception of the skeleton, which still keeps its own config) (#2716) by @liady