@shopify/cli-hydrogen 10.0.2 → 10.1.0
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/dist/assets/hydrogen/starter/CHANGELOG.md +49 -40
- package/dist/assets/hydrogen/starter/app/routes/api.$version.[graphql.json].tsx +14 -0
- package/dist/assets/hydrogen/starter/app/routes/cart.tsx +6 -1
- package/dist/assets/hydrogen/starter/package.json +2 -2
- package/dist/lib/setups/routes/generate.js +2 -1
- package/oclif.manifest.json +3 -2
- package/package.json +1 -1
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
# skeleton
|
|
2
2
|
|
|
3
|
+
## 2025.4.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Add a new tokenless Storefront API route to the starter template. ([#2948](https://github.com/Shopify/hydrogen/pull/2948)) by [@blittle](https://github.com/blittle)
|
|
8
|
+
|
|
9
|
+
- Updated dependencies [[`d44fab3d`](https://github.com/Shopify/hydrogen/commit/d44fab3d07c5e255edcd22745d4d7e2db2c3e60f)]:
|
|
10
|
+
- @shopify/hydrogen@2025.4.1
|
|
11
|
+
|
|
3
12
|
## 2025.4.0
|
|
4
13
|
|
|
5
14
|
### Patch Changes
|
|
@@ -164,13 +173,13 @@
|
|
|
164
173
|
1. Add a routes.ts file. This is your new Remix route configuration file.
|
|
165
174
|
|
|
166
175
|
```ts
|
|
167
|
-
import {flatRoutes} from
|
|
168
|
-
import {layout, type RouteConfig} from
|
|
169
|
-
import {hydrogenRoutes} from
|
|
176
|
+
import { flatRoutes } from "@remix-run/fs-routes";
|
|
177
|
+
import { layout, type RouteConfig } from "@remix-run/route-config";
|
|
178
|
+
import { hydrogenRoutes } from "@shopify/hydrogen";
|
|
170
179
|
|
|
171
180
|
export default hydrogenRoutes([
|
|
172
181
|
// Your entire app reading from routes folder using Layout from layout.tsx
|
|
173
|
-
layout(
|
|
182
|
+
layout("./layout.tsx", await flatRoutes()),
|
|
174
183
|
]) satisfies RouteConfig;
|
|
175
184
|
```
|
|
176
185
|
|
|
@@ -761,25 +770,25 @@
|
|
|
761
770
|
8. Update the `ProductForm` component.
|
|
762
771
|
|
|
763
772
|
```tsx
|
|
764
|
-
import {Link, useNavigate} from
|
|
765
|
-
import {type MappedProductOptions} from
|
|
773
|
+
import { Link, useNavigate } from "@remix-run/react";
|
|
774
|
+
import { type MappedProductOptions } from "@shopify/hydrogen";
|
|
766
775
|
import type {
|
|
767
776
|
Maybe,
|
|
768
777
|
ProductOptionValueSwatch,
|
|
769
|
-
} from
|
|
770
|
-
import {AddToCartButton} from
|
|
771
|
-
import {useAside} from
|
|
772
|
-
import type {ProductFragment} from
|
|
778
|
+
} from "@shopify/hydrogen/storefront-api-types";
|
|
779
|
+
import { AddToCartButton } from "./AddToCartButton";
|
|
780
|
+
import { useAside } from "./Aside";
|
|
781
|
+
import type { ProductFragment } from "storefrontapi.generated";
|
|
773
782
|
|
|
774
783
|
export function ProductForm({
|
|
775
784
|
productOptions,
|
|
776
785
|
selectedVariant,
|
|
777
786
|
}: {
|
|
778
787
|
productOptions: MappedProductOptions[];
|
|
779
|
-
selectedVariant: ProductFragment[
|
|
788
|
+
selectedVariant: ProductFragment["selectedOrFirstAvailableVariant"];
|
|
780
789
|
}) {
|
|
781
790
|
const navigate = useNavigate();
|
|
782
|
-
const {open} = useAside();
|
|
791
|
+
const { open } = useAside();
|
|
783
792
|
return (
|
|
784
793
|
<div className="product-form">
|
|
785
794
|
{productOptions.map((option) => (
|
|
@@ -813,8 +822,8 @@
|
|
|
813
822
|
to={`/products/${handle}?${variantUriQuery}`}
|
|
814
823
|
style={{
|
|
815
824
|
border: selected
|
|
816
|
-
?
|
|
817
|
-
:
|
|
825
|
+
? "1px solid black"
|
|
826
|
+
: "1px solid transparent",
|
|
818
827
|
opacity: available ? 1 : 0.3,
|
|
819
828
|
}}
|
|
820
829
|
>
|
|
@@ -831,13 +840,13 @@
|
|
|
831
840
|
<button
|
|
832
841
|
type="button"
|
|
833
842
|
className={`product-options-item${
|
|
834
|
-
exists && !selected ?
|
|
843
|
+
exists && !selected ? " link" : ""
|
|
835
844
|
}`}
|
|
836
845
|
key={option.name + name}
|
|
837
846
|
style={{
|
|
838
847
|
border: selected
|
|
839
|
-
?
|
|
840
|
-
:
|
|
848
|
+
? "1px solid black"
|
|
849
|
+
: "1px solid transparent",
|
|
841
850
|
opacity: available ? 1 : 0.3,
|
|
842
851
|
}}
|
|
843
852
|
disabled={!exists}
|
|
@@ -861,7 +870,7 @@
|
|
|
861
870
|
<AddToCartButton
|
|
862
871
|
disabled={!selectedVariant || !selectedVariant.availableForSale}
|
|
863
872
|
onClick={() => {
|
|
864
|
-
open(
|
|
873
|
+
open("cart");
|
|
865
874
|
}}
|
|
866
875
|
lines={
|
|
867
876
|
selectedVariant
|
|
@@ -875,7 +884,7 @@
|
|
|
875
884
|
: []
|
|
876
885
|
}
|
|
877
886
|
>
|
|
878
|
-
{selectedVariant?.availableForSale ?
|
|
887
|
+
{selectedVariant?.availableForSale ? "Add to cart" : "Sold out"}
|
|
879
888
|
</AddToCartButton>
|
|
880
889
|
</div>
|
|
881
890
|
);
|
|
@@ -898,7 +907,7 @@
|
|
|
898
907
|
aria-label={name}
|
|
899
908
|
className="product-option-label-swatch"
|
|
900
909
|
style={{
|
|
901
|
-
backgroundColor: color ||
|
|
910
|
+
backgroundColor: color || "transparent",
|
|
902
911
|
}}
|
|
903
912
|
>
|
|
904
913
|
{!!image && <img src={image} alt={name} />}
|
|
@@ -1399,21 +1408,21 @@
|
|
|
1399
1408
|
New `withCache.fetch` is for caching simple fetch requests. This method caches the responses if they are OK responses, and you can pass `shouldCacheResponse`, `cacheKey`, etc. to modify behavior. `data` is the consumed body of the response (we need to consume to cache it).
|
|
1400
1409
|
|
|
1401
1410
|
```ts
|
|
1402
|
-
const withCache = createWithCache({cache, waitUntil, request});
|
|
1411
|
+
const withCache = createWithCache({ cache, waitUntil, request });
|
|
1403
1412
|
|
|
1404
|
-
const {data, response} = await withCache.fetch<{data: T; error: string}>(
|
|
1405
|
-
|
|
1413
|
+
const { data, response } = await withCache.fetch<{ data: T; error: string }>(
|
|
1414
|
+
"my-cms.com/api",
|
|
1406
1415
|
{
|
|
1407
|
-
method:
|
|
1408
|
-
headers: {
|
|
1416
|
+
method: "POST",
|
|
1417
|
+
headers: { "Content-type": "application/json" },
|
|
1409
1418
|
body,
|
|
1410
1419
|
},
|
|
1411
1420
|
{
|
|
1412
1421
|
cacheStrategy: CacheLong(),
|
|
1413
1422
|
// Cache if there are no data errors or a specific data that make this result not suited for caching
|
|
1414
1423
|
shouldCacheResponse: (result) => !result?.error,
|
|
1415
|
-
cacheKey: [
|
|
1416
|
-
displayName:
|
|
1424
|
+
cacheKey: ["my-cms", body],
|
|
1425
|
+
displayName: "My CMS query",
|
|
1417
1426
|
},
|
|
1418
1427
|
);
|
|
1419
1428
|
```
|
|
@@ -1989,9 +1998,9 @@
|
|
|
1989
1998
|
|
|
1990
1999
|
```tsx
|
|
1991
2000
|
// app/lib/root-data.ts
|
|
1992
|
-
import {useMatches} from
|
|
1993
|
-
import type {SerializeFrom} from
|
|
1994
|
-
import type {loader} from
|
|
2001
|
+
import { useMatches } from "@remix-run/react";
|
|
2002
|
+
import type { SerializeFrom } from "@shopify/remix-oxygen";
|
|
2003
|
+
import type { loader } from "~/root";
|
|
1995
2004
|
|
|
1996
2005
|
/**
|
|
1997
2006
|
* Access the result of the root loader from a React component.
|
|
@@ -2153,10 +2162,10 @@
|
|
|
2153
2162
|
- This is an important fix to a bug with 404 routes and path-based i18n projects where some unknown routes would not properly render a 404. This fixes all new projects, but to fix existing projects, add a `($locale).tsx` route with the following contents: ([#1732](https://github.com/Shopify/hydrogen/pull/1732)) by [@blittle](https://github.com/blittle)
|
|
2154
2163
|
|
|
2155
2164
|
```ts
|
|
2156
|
-
import {type LoaderFunctionArgs} from
|
|
2165
|
+
import { type LoaderFunctionArgs } from "@remix-run/server-runtime";
|
|
2157
2166
|
|
|
2158
|
-
export async function loader({params, context}: LoaderFunctionArgs) {
|
|
2159
|
-
const {language, country} = context.storefront.i18n;
|
|
2167
|
+
export async function loader({ params, context }: LoaderFunctionArgs) {
|
|
2168
|
+
const { language, country } = context.storefront.i18n;
|
|
2160
2169
|
|
|
2161
2170
|
if (
|
|
2162
2171
|
params.locale &&
|
|
@@ -2164,7 +2173,7 @@
|
|
|
2164
2173
|
) {
|
|
2165
2174
|
// If the locale URL param is defined, yet we still are still at the default locale
|
|
2166
2175
|
// then the the locale param must be invalid, send to the 404 page
|
|
2167
|
-
throw new Response(null, {status: 404});
|
|
2176
|
+
throw new Response(null, { status: 404 });
|
|
2168
2177
|
}
|
|
2169
2178
|
|
|
2170
2179
|
return null;
|
|
@@ -2220,11 +2229,11 @@
|
|
|
2220
2229
|
```yaml
|
|
2221
2230
|
projects:
|
|
2222
2231
|
default:
|
|
2223
|
-
schema:
|
|
2232
|
+
schema: "node_modules/@shopify/hydrogen/storefront.schema.json"
|
|
2224
2233
|
documents:
|
|
2225
|
-
-
|
|
2226
|
-
-
|
|
2227
|
-
-
|
|
2234
|
+
- "!*.d.ts"
|
|
2235
|
+
- "*.{ts,tsx,js,jsx}"
|
|
2236
|
+
- "app/**/*.{ts,tsx,js,jsx}"
|
|
2228
2237
|
```
|
|
2229
2238
|
|
|
2230
2239
|
- Improve resiliency of `HydrogenSession` ([#1583](https://github.com/Shopify/hydrogen/pull/1583)) by [@blittle](https://github.com/blittle)
|
|
@@ -2439,8 +2448,8 @@
|
|
|
2439
2448
|
```ts
|
|
2440
2449
|
// root.tsx
|
|
2441
2450
|
|
|
2442
|
-
import {useMatches} from
|
|
2443
|
-
import {type SerializeFrom} from
|
|
2451
|
+
import { useMatches } from "@remix-run/react";
|
|
2452
|
+
import { type SerializeFrom } from "@shopify/remix-oxygen";
|
|
2444
2453
|
|
|
2445
2454
|
export const useRootLoaderData = () => {
|
|
2446
2455
|
const [root] = useMatches();
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import {type LoaderFunctionArgs} from '@shopify/remix-oxygen';
|
|
2
|
+
|
|
3
|
+
export async function action({params, context, request}: LoaderFunctionArgs) {
|
|
4
|
+
const response = await fetch(
|
|
5
|
+
`https://${context.env.PUBLIC_CHECKOUT_DOMAIN}/api/${params.version}/graphql.json`,
|
|
6
|
+
{
|
|
7
|
+
method: 'POST',
|
|
8
|
+
body: request.body,
|
|
9
|
+
headers: request.headers,
|
|
10
|
+
},
|
|
11
|
+
);
|
|
12
|
+
|
|
13
|
+
return new Response(response.body, {headers: new Headers(response.headers)});
|
|
14
|
+
}
|
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
import {type MetaFunction, useLoaderData} from '@remix-run/react';
|
|
2
2
|
import type {CartQueryDataReturn} from '@shopify/hydrogen';
|
|
3
3
|
import {CartForm} from '@shopify/hydrogen';
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
data,
|
|
6
|
+
type LoaderFunctionArgs,
|
|
7
|
+
type ActionFunctionArgs,
|
|
8
|
+
type HeadersFunction,
|
|
9
|
+
} from '@shopify/remix-oxygen';
|
|
5
10
|
import {CartMain} from '~/components/CartMain';
|
|
6
11
|
|
|
7
12
|
export const meta: MetaFunction = () => {
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "skeleton",
|
|
3
3
|
"private": true,
|
|
4
4
|
"sideEffects": false,
|
|
5
|
-
"version": "2025.4.
|
|
5
|
+
"version": "2025.4.1",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"scripts": {
|
|
8
8
|
"build": "shopify hydrogen build --codegen",
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"@remix-run/react": "^2.16.1",
|
|
18
18
|
"@remix-run/server-runtime": "^2.16.1",
|
|
19
19
|
"graphql": "^16.10.0",
|
|
20
|
-
"@shopify/hydrogen": "2025.4.
|
|
20
|
+
"@shopify/hydrogen": "2025.4.1",
|
|
21
21
|
"@shopify/remix-oxygen": "^2.0.12",
|
|
22
22
|
"graphql-tag": "^2.12.6",
|
|
23
23
|
"isbot": "^5.1.22",
|
|
@@ -22,7 +22,8 @@ const ROUTE_MAP = {
|
|
|
22
22
|
account: "account*",
|
|
23
23
|
search: ["search", "api.predictive-search"],
|
|
24
24
|
robots: "[robots.txt]",
|
|
25
|
-
sitemap: ["[sitemap.xml]", "sitemap.$type.$page[.xml]"]
|
|
25
|
+
sitemap: ["[sitemap.xml]", "sitemap.$type.$page[.xml]"],
|
|
26
|
+
tokenlessApi: "api.$version.[graphql.json]"
|
|
26
27
|
};
|
|
27
28
|
let allRouteTemplateFiles = [];
|
|
28
29
|
async function getResolvedRoutes(routeKeys = Object.keys(ROUTE_MAP)) {
|
package/oclif.manifest.json
CHANGED
|
@@ -880,7 +880,7 @@
|
|
|
880
880
|
"aliases": [],
|
|
881
881
|
"args": {
|
|
882
882
|
"routeName": {
|
|
883
|
-
"description": "The route to generate. One of home,page,cart,products,collections,policies,blogs,account,search,robots,sitemap,all.",
|
|
883
|
+
"description": "The route to generate. One of home,page,cart,products,collections,policies,blogs,account,search,robots,sitemap,tokenlessApi,all.",
|
|
884
884
|
"name": "routeName",
|
|
885
885
|
"options": [
|
|
886
886
|
"home",
|
|
@@ -894,6 +894,7 @@
|
|
|
894
894
|
"search",
|
|
895
895
|
"robots",
|
|
896
896
|
"sitemap",
|
|
897
|
+
"tokenlessApi",
|
|
897
898
|
"all"
|
|
898
899
|
],
|
|
899
900
|
"required": true
|
|
@@ -1748,5 +1749,5 @@
|
|
|
1748
1749
|
]
|
|
1749
1750
|
}
|
|
1750
1751
|
},
|
|
1751
|
-
"version": "10.0
|
|
1752
|
+
"version": "10.1.0"
|
|
1752
1753
|
}
|