@shopify/hydrogen 0.13.2 → 0.16.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/CHANGELOG.md +144 -0
- package/dist/esnext/client.d.ts +4 -0
- package/dist/esnext/client.js +4 -0
- package/dist/esnext/components/CartProvider/CartProvider.client.js +23 -0
- package/dist/esnext/components/DevTools.d.ts +1 -0
- package/dist/esnext/components/DevTools.js +128 -0
- package/dist/esnext/components/Link/Link.client.d.ts +6 -0
- package/dist/esnext/components/Link/Link.client.js +85 -3
- package/dist/esnext/components/LocalizationProvider/LocalizationContext.client.d.ts +1 -1
- package/dist/esnext/components/LocalizationProvider/LocalizationProvider.server.d.ts +16 -0
- package/dist/esnext/components/LocalizationProvider/LocalizationProvider.server.js +7 -2
- package/dist/esnext/components/Seo/DefaultPageSeo.client.js +1 -2
- package/dist/esnext/constants.d.ts +6 -0
- package/dist/esnext/constants.js +6 -0
- package/dist/esnext/entry-client.js +20 -4
- package/dist/esnext/entry-server.d.ts +1 -1
- package/dist/esnext/entry-server.js +42 -23
- package/dist/esnext/foundation/Analytics/Analytics.client.d.ts +3 -0
- package/dist/esnext/foundation/Analytics/Analytics.client.js +28 -0
- package/dist/esnext/foundation/Analytics/Analytics.server.d.ts +1 -0
- package/dist/esnext/foundation/Analytics/Analytics.server.js +38 -0
- package/dist/esnext/foundation/Analytics/ClientAnalytics.d.ts +24 -0
- package/dist/esnext/foundation/Analytics/ClientAnalytics.js +91 -0
- package/dist/esnext/foundation/Analytics/ServerAnalyticsRoute.server.d.ts +2 -0
- package/dist/esnext/foundation/Analytics/ServerAnalyticsRoute.server.js +33 -0
- package/dist/esnext/foundation/Analytics/const.d.ts +8 -0
- package/dist/esnext/foundation/Analytics/const.js +8 -0
- package/dist/esnext/foundation/Analytics/hook.d.ts +1 -0
- package/dist/esnext/foundation/Analytics/hook.js +7 -0
- package/dist/esnext/foundation/Analytics/index.d.ts +2 -0
- package/dist/esnext/foundation/Analytics/index.js +2 -0
- package/dist/esnext/foundation/Analytics/types.d.ts +5 -0
- package/dist/esnext/{components/LocalizationProvider/LocalizationQuery.js → foundation/Analytics/types.js} +0 -0
- package/dist/esnext/foundation/Analytics/utils.d.ts +1 -0
- package/dist/esnext/foundation/Analytics/utils.js +8 -0
- package/dist/esnext/foundation/Boomerang/Boomerang.client.js +3 -1
- package/dist/esnext/foundation/Route/Route.server.js +4 -0
- package/dist/esnext/foundation/Router/BrowserRouter.client.js +68 -15
- package/dist/esnext/foundation/ServerRequestProvider/ServerRequestProvider.js +1 -1
- package/dist/esnext/foundation/ServerStateProvider/ServerStateProvider.d.ts +6 -1
- package/dist/esnext/foundation/ServerStateProvider/ServerStateProvider.js +27 -22
- package/dist/esnext/foundation/ShopifyProvider/ShopifyProvider.server.js +4 -1
- package/dist/esnext/foundation/ShopifyProvider/types.d.ts +5 -6
- package/dist/esnext/foundation/constants.d.ts +1 -1
- package/dist/esnext/foundation/constants.js +1 -1
- package/dist/esnext/foundation/fetchSync/client/fetchSync.d.ts +10 -0
- package/dist/esnext/foundation/fetchSync/client/fetchSync.js +27 -0
- package/dist/esnext/foundation/fetchSync/server/fetchSync.d.ts +8 -0
- package/dist/esnext/foundation/fetchSync/server/fetchSync.js +27 -0
- package/dist/esnext/foundation/fetchSync/types.d.ts +5 -0
- package/dist/esnext/foundation/fetchSync/types.js +1 -0
- package/dist/esnext/foundation/useQuery/hooks.d.ts +4 -2
- package/dist/esnext/foundation/useQuery/hooks.js +10 -6
- package/dist/esnext/foundation/useUrl/useUrl.js +8 -1
- package/dist/esnext/framework/Hydration/ServerComponentRequest.server.d.ts +1 -0
- package/dist/esnext/framework/Hydration/ServerComponentRequest.server.js +14 -7
- package/dist/esnext/framework/cache/in-memory.js +5 -5
- package/dist/esnext/framework/cache.d.ts +1 -10
- package/dist/esnext/framework/cache.js +67 -30
- package/dist/esnext/framework/plugin.js +10 -0
- package/dist/esnext/framework/plugins/vite-plugin-css-modules-rsc.js +1 -1
- package/dist/esnext/framework/plugins/vite-plugin-hydrogen-config.js +9 -2
- package/dist/esnext/hooks/useParsedMetafields/useParsedMetafields.d.ts +1 -1
- package/dist/esnext/hooks/useShopQuery/hooks.d.ts +1 -1
- package/dist/esnext/hooks/useShopQuery/hooks.js +37 -22
- package/dist/esnext/index.d.ts +2 -0
- package/dist/esnext/index.js +2 -0
- package/dist/esnext/storefront-api-types.d.ts +150 -3
- package/dist/esnext/storefront-api-types.js +16 -0
- package/dist/esnext/types.d.ts +6 -1
- package/dist/esnext/utilities/apiRoutes.d.ts +2 -3
- package/dist/esnext/utilities/apiRoutes.js +14 -9
- package/dist/esnext/utilities/hash.d.ts +2 -0
- package/dist/esnext/utilities/hash.js +7 -0
- package/dist/esnext/utilities/log/log-cache-api-status.js +1 -1
- package/dist/esnext/utilities/log/log-cache-header.js +1 -1
- package/dist/esnext/utilities/log/log-query-timeline.js +1 -1
- package/dist/esnext/utilities/storefrontApi.d.ts +4 -0
- package/dist/esnext/utilities/storefrontApi.js +21 -0
- package/dist/esnext/utilities/suspense.d.ts +5 -0
- package/dist/esnext/utilities/suspense.js +32 -0
- package/dist/esnext/utilities/template.js +1 -1
- package/dist/esnext/version.d.ts +1 -1
- package/dist/esnext/version.js +1 -1
- package/dist/node/constants.d.ts +6 -0
- package/dist/node/constants.js +7 -1
- package/dist/node/entry-server.d.ts +1 -1
- package/dist/node/entry-server.js +41 -25
- package/dist/node/foundation/Analytics/Analytics.client.d.ts +3 -0
- package/dist/node/foundation/Analytics/Analytics.client.js +32 -0
- package/dist/node/foundation/Analytics/Analytics.server.d.ts +1 -0
- package/dist/node/foundation/Analytics/Analytics.server.js +45 -0
- package/dist/node/foundation/Analytics/ClientAnalytics.d.ts +24 -0
- package/dist/node/foundation/Analytics/ClientAnalytics.js +94 -0
- package/dist/node/foundation/Analytics/ServerAnalyticsRoute.server.d.ts +2 -0
- package/dist/node/foundation/Analytics/ServerAnalyticsRoute.server.js +37 -0
- package/dist/node/foundation/Analytics/const.d.ts +8 -0
- package/dist/node/foundation/Analytics/const.js +11 -0
- package/dist/node/foundation/Analytics/hook.d.ts +1 -0
- package/dist/node/foundation/Analytics/hook.js +11 -0
- package/dist/node/foundation/Analytics/index.d.ts +2 -0
- package/dist/node/foundation/Analytics/index.js +7 -0
- package/dist/node/foundation/Analytics/types.d.ts +5 -0
- package/dist/node/foundation/Analytics/types.js +2 -0
- package/dist/node/foundation/Analytics/utils.d.ts +1 -0
- package/dist/node/foundation/Analytics/utils.js +12 -0
- package/dist/node/foundation/Router/BrowserRouter.client.js +67 -14
- package/dist/node/foundation/ServerRequestProvider/ServerRequestProvider.js +2 -2
- package/dist/node/foundation/ServerStateProvider/ServerStateProvider.d.ts +6 -1
- package/dist/node/foundation/ServerStateProvider/ServerStateProvider.js +27 -22
- package/dist/node/foundation/ShopifyProvider/types.d.ts +5 -6
- package/dist/node/framework/Hydration/ServerComponentRequest.server.d.ts +1 -0
- package/dist/node/framework/Hydration/ServerComponentRequest.server.js +16 -9
- package/dist/node/framework/cache/in-memory.js +5 -5
- package/dist/node/framework/cache.d.ts +1 -10
- package/dist/node/framework/cache.js +71 -36
- package/dist/node/framework/plugin.js +10 -0
- package/dist/node/framework/plugins/vite-plugin-css-modules-rsc.js +1 -1
- package/dist/node/framework/plugins/vite-plugin-hydrogen-config.js +9 -2
- package/dist/node/storefront-api-types.d.ts +150 -3
- package/dist/node/storefront-api-types.js +17 -1
- package/dist/node/types.d.ts +6 -1
- package/dist/node/utilities/apiRoutes.d.ts +2 -3
- package/dist/node/utilities/apiRoutes.js +14 -9
- package/dist/node/utilities/flattenConnection/flattenConnection.d.ts +6 -0
- package/dist/node/utilities/flattenConnection/flattenConnection.js +15 -0
- package/dist/node/utilities/flattenConnection/index.d.ts +1 -0
- package/dist/node/utilities/flattenConnection/index.js +5 -0
- package/dist/node/utilities/hash.d.ts +2 -0
- package/dist/node/utilities/hash.js +11 -0
- package/dist/node/utilities/image_size.d.ts +30 -0
- package/dist/node/utilities/image_size.js +110 -0
- package/dist/node/utilities/index.d.ts +11 -0
- package/dist/node/utilities/index.js +32 -0
- package/dist/node/utilities/isClient/index.d.ts +1 -0
- package/dist/node/utilities/isClient/index.js +5 -0
- package/dist/node/utilities/isClient/isClient.d.ts +4 -0
- package/dist/node/utilities/isClient/isClient.js +10 -0
- package/dist/node/utilities/isServer/index.d.ts +1 -0
- package/dist/node/utilities/isServer/index.js +5 -0
- package/dist/node/utilities/isServer/isServer.d.ts +4 -0
- package/dist/node/utilities/isServer/isServer.js +11 -0
- package/dist/node/utilities/load_script.d.ts +3 -0
- package/dist/node/utilities/load_script.js +27 -0
- package/dist/node/utilities/log/log-cache-api-status.js +1 -1
- package/dist/node/utilities/log/log-cache-header.js +2 -2
- package/dist/node/utilities/log/log-query-timeline.js +2 -2
- package/dist/node/utilities/measurement.d.ts +3 -0
- package/dist/node/utilities/measurement.js +103 -0
- package/dist/node/utilities/parseMetafieldValue/index.d.ts +1 -0
- package/dist/node/utilities/parseMetafieldValue/index.js +5 -0
- package/dist/node/utilities/parseMetafieldValue/parseMetafieldValue.d.ts +6 -0
- package/dist/node/utilities/parseMetafieldValue/parseMetafieldValue.js +39 -0
- package/dist/node/utilities/storefrontApi.d.ts +4 -0
- package/dist/node/utilities/storefrontApi.js +25 -0
- package/dist/node/utilities/suspense.d.ts +12 -0
- package/dist/node/utilities/suspense.js +64 -0
- package/dist/node/utilities/template.js +1 -1
- package/dist/node/utilities/video_parameters.d.ts +47 -0
- package/dist/node/utilities/video_parameters.js +27 -0
- package/dist/node/version.d.ts +1 -1
- package/dist/node/version.js +1 -1
- package/package.json +3 -3
- package/vendor/react-server-dom-vite/cjs/react-server-dom-vite-plugin.js +9 -21
- package/vendor/react-server-dom-vite/cjs/react-server-dom-vite-writer.browser.development.server.js +51 -47
- package/vendor/react-server-dom-vite/cjs/react-server-dom-vite-writer.browser.production.min.server.js +30 -29
- package/vendor/react-server-dom-vite/cjs/react-server-dom-vite-writer.node.development.server.js +51 -47
- package/vendor/react-server-dom-vite/cjs/react-server-dom-vite-writer.node.production.min.server.js +17 -17
- package/vendor/react-server-dom-vite/esm/react-server-dom-vite-client-proxy.js +55 -45
- package/vendor/react-server-dom-vite/esm/react-server-dom-vite-plugin.js +9 -21
- package/vendor/react-server-dom-vite/esm/react-server-dom-vite-writer.browser.server.js +51 -47
- package/vendor/react-server-dom-vite/esm/react-server-dom-vite-writer.node.server.js +51 -47
- package/vendor/react-server-dom-vite/package.json +3 -3
- package/dist/esnext/components/LocalizationProvider/LocalizationQuery.d.ts +0 -23
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,149 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.16.0
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#1082](https://github.com/Shopify/hydrogen/pull/1082) [`bd14340c`](https://github.com/Shopify/hydrogen/commit/bd14340c3099a0bf375a5879410cdf0697ed22f6) Thanks [@jplhomer](https://github.com/jplhomer)! - Update `useUrl()` to allow a developer to subscribe to a reactive version of the current router location.
|
|
8
|
+
|
|
9
|
+
Example:
|
|
10
|
+
|
|
11
|
+
```jsx
|
|
12
|
+
import {useUrl} from '@shopify/hydrogen/client';
|
|
13
|
+
|
|
14
|
+
function MyClientComponent() {
|
|
15
|
+
const url = useUrl();
|
|
16
|
+
|
|
17
|
+
useEffect(() => {
|
|
18
|
+
// Record navigation, analytics, etc
|
|
19
|
+
}, [url]);
|
|
20
|
+
}
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
* [#1075](https://github.com/Shopify/hydrogen/pull/1075) [`05dea552`](https://github.com/Shopify/hydrogen/commit/05dea552c90862a125b5111993003355a019b556) Thanks [@jplhomer](https://github.com/jplhomer)! - Properly set buyer IP and secret token for API Route queryShop helper
|
|
24
|
+
|
|
25
|
+
## 0.15.0
|
|
26
|
+
|
|
27
|
+
### Minor Changes
|
|
28
|
+
|
|
29
|
+
- [#983](https://github.com/Shopify/hydrogen/pull/983) [`52af261b`](https://github.com/Shopify/hydrogen/commit/52af261ba2bf6ed08e232b9fb2d75e69905f4cc6) Thanks [@jplhomer](https://github.com/jplhomer)! - Introduce Suspense-friendly `fetchSync` API for server and client components.
|
|
30
|
+
|
|
31
|
+
When using `fetchSync` in server components, you provide options for caching and preloading. This is similar to the [`useQuery` hook](<[/api/hydrogen/hooks/global/useQuery](https://shopify.dev/api/hydrogen/hooks/global/usequery)>):
|
|
32
|
+
|
|
33
|
+
```jsx
|
|
34
|
+
import {fetchSync, CacheMinutes} from '@shopify/hydrogen';
|
|
35
|
+
import {Suspense} from 'react';
|
|
36
|
+
|
|
37
|
+
export function MyServerComponent() {
|
|
38
|
+
return (
|
|
39
|
+
<Suspense fallback="Loading...">
|
|
40
|
+
<MyThings />
|
|
41
|
+
</Suspense>
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function MyThings() {
|
|
46
|
+
const things = fetchSync('https://3p.api.com/things.json', {
|
|
47
|
+
preload: true,
|
|
48
|
+
cache: CacheMinutes(),
|
|
49
|
+
}).json();
|
|
50
|
+
|
|
51
|
+
return <h2>{things.title}</h2>;
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
When using `fetchSync` in client components, you cannot provide options for caching and preloading. You must import `fetchSync` from `@shopify/hydrogen/client`:
|
|
56
|
+
|
|
57
|
+
```jsx
|
|
58
|
+
import {fetchSync} from '@shopify/hydrogen/client';
|
|
59
|
+
import {Suspense} from 'react';
|
|
60
|
+
|
|
61
|
+
export function MyClientComponent() {
|
|
62
|
+
return (
|
|
63
|
+
<Suspense fallback="Loading...">
|
|
64
|
+
<MyThings />
|
|
65
|
+
</Suspense>
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function MyThings() {
|
|
70
|
+
const things = fetchSync('https://3p.api.com/things.json').json();
|
|
71
|
+
|
|
72
|
+
return <h2>{things.title}</h2>;
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
* [#890](https://github.com/Shopify/hydrogen/pull/890) [`a4c6d6c4`](https://github.com/Shopify/hydrogen/commit/a4c6d6c4d31337cecbd4d5afb76887bcd31ceb65) Thanks [@wizardlyhel](https://github.com/wizardlyhel)! - Analytics instrumentation - this provides integration points for both server
|
|
77
|
+
and client side analytics instrumentations
|
|
78
|
+
|
|
79
|
+
- [Usage documentation](https://shopify.dev/custom-storefronts/hydrogen/framework/analytics)
|
|
80
|
+
|
|
81
|
+
### Patch Changes
|
|
82
|
+
|
|
83
|
+
- [#1061](https://github.com/Shopify/hydrogen/pull/1061) [`a4aa3887`](https://github.com/Shopify/hydrogen/commit/a4aa3887be9f448ec1f4322fadb9821e0d19a0b5) Thanks [@jplhomer](https://github.com/jplhomer)! - Support script tags in index.html that contain line breaks
|
|
84
|
+
|
|
85
|
+
* [#1057](https://github.com/Shopify/hydrogen/pull/1057) [`06d92ddc`](https://github.com/Shopify/hydrogen/commit/06d92ddc44e03d37d2dd8a9bbeaa5fab4c4bbbd1) Thanks [@frandiox](https://github.com/frandiox)! - Ability to concatenate requests in API route handlers without leaving the server by returning a new Request instance.
|
|
86
|
+
|
|
87
|
+
```jsx
|
|
88
|
+
// src/routes/my-page.server.jsx
|
|
89
|
+
|
|
90
|
+
export async function api(request) {
|
|
91
|
+
if (request.method === 'POST') {
|
|
92
|
+
// do some work here...
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
return new Request(request.url, {method: 'GET'});
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
export default function Page() {
|
|
99
|
+
return (
|
|
100
|
+
<form action="/my-page" method="POST">
|
|
101
|
+
...
|
|
102
|
+
</form>
|
|
103
|
+
);
|
|
104
|
+
}
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
In the previous example, a POST request to `/my-page` would run the API handler and automatically continue with the server component rendering (GET). This is useful for handling HTML forms without waterfall requests.
|
|
108
|
+
|
|
109
|
+
- [#1049](https://github.com/Shopify/hydrogen/pull/1049) [`b88a885d`](https://github.com/Shopify/hydrogen/commit/b88a885d6b062209497a97d8ce7bcd438787d53c) Thanks [@wizardlyhel](https://github.com/wizardlyhel)! - Support sub request cache control header `stale-while-revalidate` everywhere
|
|
110
|
+
|
|
111
|
+
* [#1047](https://github.com/Shopify/hydrogen/pull/1047) [`5268bf85`](https://github.com/Shopify/hydrogen/commit/5268bf85f61f8abf0e97788b7ae925ad4f3183b2) Thanks [@jplhomer](https://github.com/jplhomer)! - Restore scroll position when navigating using the back and forward buttons.
|
|
112
|
+
|
|
113
|
+
- [#1062](https://github.com/Shopify/hydrogen/pull/1062) [`cc172ae7`](https://github.com/Shopify/hydrogen/commit/cc172ae778bad0d654adcd2f41d4a548d1d94a0a) Thanks [@jplhomer](https://github.com/jplhomer)! - Fix encoding of quotes in CSS Modules which caused hydration errors
|
|
114
|
+
|
|
115
|
+
* [#1046](https://github.com/Shopify/hydrogen/pull/1046) [`3947d53a`](https://github.com/Shopify/hydrogen/commit/3947d53a99868a1e218bfab958b824ce0484615a) Thanks [@michenly](https://github.com/michenly)! - Fixed server Cookie bug where initializing with empty string will resulted in 1 item in the Cookies Map.
|
|
116
|
+
|
|
117
|
+
- [#1059](https://github.com/Shopify/hydrogen/pull/1059) [`401f329d`](https://github.com/Shopify/hydrogen/commit/401f329d331bebc4842204d4df39c4dd6797b4e1) Thanks [@frandiox](https://github.com/frandiox)! - Fix link prefetch mismatch due to query-string
|
|
118
|
+
|
|
119
|
+
* [#1072](https://github.com/Shopify/hydrogen/pull/1072) [`47c0c184`](https://github.com/Shopify/hydrogen/commit/47c0c18411eb20fa6652a981b09fd65cbed38304) Thanks [@michenly](https://github.com/michenly)! - Improve type for ShopifyContextValue to be based on ShopifyConfig.
|
|
120
|
+
|
|
121
|
+
## 0.14.0
|
|
122
|
+
|
|
123
|
+
### Minor Changes
|
|
124
|
+
|
|
125
|
+
- [#1028](https://github.com/Shopify/hydrogen/pull/1028) [`ba174588`](https://github.com/Shopify/hydrogen/commit/ba174588d8f4a9f1054779a9bf32a92e8d2c921c) Thanks [@michenly](https://github.com/michenly)! - Starting from SF API version `2022-04`, the preferred way to request translatable resources is using the `@inContext` directive. See the [API docs](https://shopify.dev/api/examples/multiple-languages#retrieve-translations-with-the-storefront-api) on how to do this and which resources have translatable properties.
|
|
126
|
+
|
|
127
|
+
This causes a breaking change to the `useShopQuery` hook. The `locale` property has been removed from the argument object; `Accept-Language` is no longer being send with every request, and we are no longer using locale as part of the cache key.
|
|
128
|
+
|
|
129
|
+
The `useShop` hook will now return the `languageCode` key, which is the first two characters of the existing `locale` key.
|
|
130
|
+
|
|
131
|
+
Both `locale` & `languageCode` values are also now capitalized to make it easier to pass into a GraphQL `@inContext` directive.
|
|
132
|
+
|
|
133
|
+
* [#1020](https://github.com/Shopify/hydrogen/pull/1020) [`e9529bc8`](https://github.com/Shopify/hydrogen/commit/e9529bc81410e0d99f9d3dbdb138ae61d00f876b) Thanks [@jplhomer](https://github.com/jplhomer)! - Preload `Link` URLs by default when a user signals intent to visit the URL. This includes hovering or focusing on the URL. To disable preloading, pass `<Link preload={false} />` to the component.
|
|
134
|
+
|
|
135
|
+
### Patch Changes
|
|
136
|
+
|
|
137
|
+
- [#1017](https://github.com/Shopify/hydrogen/pull/1017) [`4c87fb63`](https://github.com/Shopify/hydrogen/commit/4c87fb639a79da883f99c58acde0d17c713c7620) Thanks [@frandiox](https://github.com/frandiox)! - Do not cache Storefront API responses that contain GraphQL errors (amend previous fix).
|
|
138
|
+
|
|
139
|
+
* [#1039](https://github.com/Shopify/hydrogen/pull/1039) [`3a297862`](https://github.com/Shopify/hydrogen/commit/3a29786202947fab0bfe876042b37a91923ed637) Thanks [@frandiox](https://github.com/frandiox)! - Update to Vite 2.9
|
|
140
|
+
|
|
141
|
+
- [#1026](https://github.com/Shopify/hydrogen/pull/1026) [`836b064d`](https://github.com/Shopify/hydrogen/commit/836b064d1648fb1a9f209a08a82ee5c20f7dfba9) Thanks [@frehner](https://github.com/frehner)! - Updated the Typescript types and GraphQL schema to the newest updates from Storefront API 2022-04. Of note in this update is the ability to skip `edges` and go directly to `node`, for example: `product.nodes[0]` instead of `product.edges[0].node`
|
|
142
|
+
|
|
143
|
+
* [#1032](https://github.com/Shopify/hydrogen/pull/1032) [`03488083`](https://github.com/Shopify/hydrogen/commit/034880833dc500f66f9b67417c00099c283dfa67) Thanks [@jplhomer](https://github.com/jplhomer)! - Catch hydration errors related to experimental server components bugs and prevent them from being logged in production.
|
|
144
|
+
|
|
145
|
+
- [#1037](https://github.com/Shopify/hydrogen/pull/1037) [`13376efb`](https://github.com/Shopify/hydrogen/commit/13376efbe4db93efd705b6900a6198708bc37e69) Thanks [@jplhomer](https://github.com/jplhomer)! - Use new header for private Storefront token
|
|
146
|
+
|
|
3
147
|
## 0.13.2
|
|
4
148
|
|
|
5
149
|
### Patch Changes
|
package/dist/esnext/client.d.ts
CHANGED
|
@@ -2,8 +2,12 @@ export * from './components';
|
|
|
2
2
|
export * from './hooks';
|
|
3
3
|
export * from './foundation/useServerState';
|
|
4
4
|
export * from './foundation/useShop';
|
|
5
|
+
export * from './foundation/useUrl';
|
|
5
6
|
export * from './foundation/ServerStateProvider';
|
|
6
7
|
export { Head } from './foundation/Head';
|
|
7
8
|
export * from './utilities';
|
|
9
|
+
export { ClientAnalytics } from './foundation/Analytics';
|
|
8
10
|
export { useRouteParams } from './foundation/useRouteParams/useRouteParams';
|
|
9
11
|
export { useNavigate } from './foundation/useNavigate/useNavigate';
|
|
12
|
+
export { fetchSync } from './foundation/fetchSync/client/fetchSync';
|
|
13
|
+
export { suspendFunction, preloadFunction } from './utilities/suspense';
|
package/dist/esnext/client.js
CHANGED
|
@@ -2,8 +2,12 @@ export * from './components';
|
|
|
2
2
|
export * from './hooks';
|
|
3
3
|
export * from './foundation/useServerState';
|
|
4
4
|
export * from './foundation/useShop';
|
|
5
|
+
export * from './foundation/useUrl';
|
|
5
6
|
export * from './foundation/ServerStateProvider';
|
|
6
7
|
export { Head } from './foundation/Head';
|
|
7
8
|
export * from './utilities';
|
|
9
|
+
export { ClientAnalytics } from './foundation/Analytics';
|
|
8
10
|
export { useRouteParams } from './foundation/useRouteParams/useRouteParams';
|
|
9
11
|
export { useNavigate } from './foundation/useNavigate/useNavigate';
|
|
12
|
+
export { fetchSync } from './foundation/fetchSync/client/fetchSync';
|
|
13
|
+
export { suspendFunction, preloadFunction } from './utilities/suspense';
|
|
@@ -5,6 +5,7 @@ import { useCartFetch } from './hooks';
|
|
|
5
5
|
import { CartContext } from './context';
|
|
6
6
|
import { CART_ID_STORAGE_KEY } from './constants';
|
|
7
7
|
import { useServerState } from '../../foundation/useServerState';
|
|
8
|
+
import { ClientAnalytics } from '../../foundation/Analytics';
|
|
8
9
|
function cartReducer(state, action) {
|
|
9
10
|
switch (action.type) {
|
|
10
11
|
case 'cartFetch': {
|
|
@@ -200,6 +201,12 @@ export function CartProvider({ children, numCartLines, onCreate, onLineAdd, onLi
|
|
|
200
201
|
});
|
|
201
202
|
}
|
|
202
203
|
if ((_b = data === null || data === void 0 ? void 0 : data.cartCreate) === null || _b === void 0 ? void 0 : _b.cart) {
|
|
204
|
+
if (cart.lines) {
|
|
205
|
+
ClientAnalytics.publish(ClientAnalytics.eventNames.ADD_TO_CART, true, {
|
|
206
|
+
addedCartLines: cart.lines,
|
|
207
|
+
cart: data.cartCreate.cart,
|
|
208
|
+
});
|
|
209
|
+
}
|
|
203
210
|
dispatch({
|
|
204
211
|
type: 'resolve',
|
|
205
212
|
cart: cartFromGraphQL(data.cartCreate.cart),
|
|
@@ -228,6 +235,10 @@ export function CartProvider({ children, numCartLines, onCreate, onLineAdd, onLi
|
|
|
228
235
|
});
|
|
229
236
|
}
|
|
230
237
|
if ((_a = data === null || data === void 0 ? void 0 : data.cartLinesAdd) === null || _a === void 0 ? void 0 : _a.cart) {
|
|
238
|
+
ClientAnalytics.publish(ClientAnalytics.eventNames.ADD_TO_CART, true, {
|
|
239
|
+
addedCartLines: lines,
|
|
240
|
+
cart: data.cartLinesAdd.cart,
|
|
241
|
+
});
|
|
231
242
|
dispatch({
|
|
232
243
|
type: 'resolve',
|
|
233
244
|
cart: cartFromGraphQL(data.cartLinesAdd.cart),
|
|
@@ -256,6 +267,10 @@ export function CartProvider({ children, numCartLines, onCreate, onLineAdd, onLi
|
|
|
256
267
|
});
|
|
257
268
|
}
|
|
258
269
|
if ((_a = data === null || data === void 0 ? void 0 : data.cartLinesRemove) === null || _a === void 0 ? void 0 : _a.cart) {
|
|
270
|
+
ClientAnalytics.publish(ClientAnalytics.eventNames.REMOVE_FROM_CART, true, {
|
|
271
|
+
removedCartLines: lines,
|
|
272
|
+
cart: data.cartLinesRemove.cart,
|
|
273
|
+
});
|
|
259
274
|
dispatch({
|
|
260
275
|
type: 'resolve',
|
|
261
276
|
cart: cartFromGraphQL(data.cartLinesRemove.cart),
|
|
@@ -284,6 +299,10 @@ export function CartProvider({ children, numCartLines, onCreate, onLineAdd, onLi
|
|
|
284
299
|
});
|
|
285
300
|
}
|
|
286
301
|
if ((_a = data === null || data === void 0 ? void 0 : data.cartLinesUpdate) === null || _a === void 0 ? void 0 : _a.cart) {
|
|
302
|
+
ClientAnalytics.publish(ClientAnalytics.eventNames.UPDATE_CART, true, {
|
|
303
|
+
updatedCartLines: lines,
|
|
304
|
+
oldCart: state.cart,
|
|
305
|
+
});
|
|
287
306
|
dispatch({
|
|
288
307
|
type: 'resolve',
|
|
289
308
|
cart: cartFromGraphQL(data.cartLinesUpdate.cart),
|
|
@@ -396,6 +415,10 @@ export function CartProvider({ children, numCartLines, onCreate, onLineAdd, onLi
|
|
|
396
415
|
});
|
|
397
416
|
}
|
|
398
417
|
if ((_a = data === null || data === void 0 ? void 0 : data.cartDiscountCodesUpdate) === null || _a === void 0 ? void 0 : _a.cart) {
|
|
418
|
+
ClientAnalytics.publish(ClientAnalytics.eventNames.DISCOUNT_CODE_UPDATED, true, {
|
|
419
|
+
updatedDiscountCodes: discountCodes,
|
|
420
|
+
cart: data.cartDiscountCodesUpdate.cart,
|
|
421
|
+
});
|
|
399
422
|
dispatch({
|
|
400
423
|
type: 'resolve',
|
|
401
424
|
cart: cartFromGraphQL(data.cartDiscountCodesUpdate.cart),
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default function DevTools(): JSX.Element | null;
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import React, { useEffect, useState, useCallback } from 'react';
|
|
2
|
+
export default function DevTools() {
|
|
3
|
+
const [warnings, setWarnings] = useState(null);
|
|
4
|
+
const [open, setOpen] = useState(false);
|
|
5
|
+
const [activePanel, setActivePanel] = useState('warnings');
|
|
6
|
+
const toggleOpen = useCallback(() => setOpen((state) => !state), []);
|
|
7
|
+
const [hasMounted, setHasMounted] = React.useState(false);
|
|
8
|
+
useEffect(() => {
|
|
9
|
+
setHasMounted(true);
|
|
10
|
+
if (import.meta.hot) {
|
|
11
|
+
import.meta.hot.on('hydrogen', ({ type, data }) => {
|
|
12
|
+
if (type === 'warn') {
|
|
13
|
+
setWarnings((state) => [...(state || []), data]);
|
|
14
|
+
}
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
}, []);
|
|
18
|
+
const perfData = performance.getEntriesByType('navigation');
|
|
19
|
+
const entry = perfData[0];
|
|
20
|
+
let activePanelContent = null;
|
|
21
|
+
switch (activePanel) {
|
|
22
|
+
case 'warnings':
|
|
23
|
+
const warningsMarkup = warnings
|
|
24
|
+
? warnings.map((war, i) => React.createElement("li", { key: war + i }, war))
|
|
25
|
+
: null;
|
|
26
|
+
activePanelContent = (React.createElement(React.Fragment, null,
|
|
27
|
+
React.createElement(PanelHeading, null, "Overfetched graphQL fields"),
|
|
28
|
+
React.createElement("ul", { style: {
|
|
29
|
+
fontFamily: 'monospace',
|
|
30
|
+
paddingTop: '1em',
|
|
31
|
+
fontSize: '0.9em',
|
|
32
|
+
} }, warningsMarkup)));
|
|
33
|
+
break;
|
|
34
|
+
case 'network':
|
|
35
|
+
activePanelContent = (React.createElement(React.Fragment, null,
|
|
36
|
+
React.createElement(PanelHeading, null, "Metrics"),
|
|
37
|
+
React.createElement("ul", { style: {
|
|
38
|
+
fontFamily: 'monospace',
|
|
39
|
+
paddingTop: '1em',
|
|
40
|
+
fontSize: '0.9em',
|
|
41
|
+
} }, Object.entries(entry.toJSON())
|
|
42
|
+
.filter(([key]) => ['duration', 'domInteractive'].includes(key))
|
|
43
|
+
.map(([key, value]) => (React.createElement("li", { key: key },
|
|
44
|
+
React.createElement("strong", null, key),
|
|
45
|
+
" ",
|
|
46
|
+
(value / 1000).toFixed(2),
|
|
47
|
+
"s"))))));
|
|
48
|
+
break;
|
|
49
|
+
}
|
|
50
|
+
const buttonText = (React.createElement("svg", { style: {
|
|
51
|
+
height: '3em',
|
|
52
|
+
width: '3em',
|
|
53
|
+
}, width: "131", height: "130", viewBox: "0 0 131 130", fill: "none", xmlns: "http://www.w3.org/2000/svg" },
|
|
54
|
+
React.createElement("path", { d: "M64.9548 106.281L27.1377 86.1894L40.0714 79.3723L54.6329 87.1049L66.851 80.6638L52.2895 72.9313L65.2231 66.0979L103.04 86.1894L90.1065 93.0064L76.35 85.6989L64.114 92.1563L77.8884 99.4638L64.9548 106.281Z", fill: "white" }),
|
|
55
|
+
React.createElement("path", { fillRule: "evenodd", clipRule: "evenodd", d: "M65.2247 25L105.178 46.2267L90.105 54.1716L76.3488 46.8642L66.2525 52.1924L80.028 59.5005L64.9532 67.446L25 46.2196L40.0734 38.2748L54.6349 46.0073L64.713 40.6944L50.1533 32.9628L65.2247 25ZM54.4262 32.9673L68.9896 40.7008L54.6315 48.27L40.0699 40.5374L29.276 46.2267L64.9569 65.1833L75.7495 59.4947L61.9761 52.1878L76.3518 44.6012L90.1087 51.9088L100.902 46.2196L65.2221 27.2634L54.4262 32.9673Z", fill: "white" })));
|
|
56
|
+
if (import.meta.env.DEV && hasMounted) {
|
|
57
|
+
return (React.createElement("div", { style: {
|
|
58
|
+
position: 'fixed',
|
|
59
|
+
right: open ? 0 : '2em',
|
|
60
|
+
left: open ? 0 : '2em',
|
|
61
|
+
bottom: open ? 0 : '-2em',
|
|
62
|
+
borderRadius: open ? 0 : '2em',
|
|
63
|
+
top: '100%',
|
|
64
|
+
zIndex: 10000,
|
|
65
|
+
display: 'flex',
|
|
66
|
+
flexDirection: 'column',
|
|
67
|
+
overflow: 'hidden',
|
|
68
|
+
height: open ? '75%' : '4em',
|
|
69
|
+
transform: open ? 'translateY(-100%)' : 'translateY(-5em)',
|
|
70
|
+
} },
|
|
71
|
+
React.createElement("button", { style: {
|
|
72
|
+
position: 'absolute',
|
|
73
|
+
top: '0.35em',
|
|
74
|
+
right: '1em',
|
|
75
|
+
overflow: 'hidden',
|
|
76
|
+
zIndex: 10,
|
|
77
|
+
}, onClick: toggleOpen }, buttonText),
|
|
78
|
+
React.createElement("div", { style: {
|
|
79
|
+
overflow: 'scroll',
|
|
80
|
+
color: 'white',
|
|
81
|
+
height: '100%',
|
|
82
|
+
padding: '2em',
|
|
83
|
+
background: 'rgba(0, 0, 0, 0.95)',
|
|
84
|
+
borderRadius: open ? 0 : '2em',
|
|
85
|
+
} },
|
|
86
|
+
React.createElement("div", { style: {
|
|
87
|
+
position: 'absolute',
|
|
88
|
+
padding: '1.2em 2em',
|
|
89
|
+
top: 0,
|
|
90
|
+
left: '-0.5em',
|
|
91
|
+
right: 0,
|
|
92
|
+
background: 'rgba(0, 0, 0, 0.95)',
|
|
93
|
+
borderRadius: open ? 0 : '2em',
|
|
94
|
+
display: 'flex',
|
|
95
|
+
alignItems: 'center',
|
|
96
|
+
} },
|
|
97
|
+
warnings && warnings.length > 0 && (React.createElement("button", { onClick: () => {
|
|
98
|
+
setOpen(true);
|
|
99
|
+
setActivePanel('warnings');
|
|
100
|
+
}, style: {
|
|
101
|
+
margin: '0 0.5em',
|
|
102
|
+
textDecoration: open && activePanel === 'warnings' ? 'underline' : 'none',
|
|
103
|
+
} },
|
|
104
|
+
"Warnings",
|
|
105
|
+
' ',
|
|
106
|
+
warnings && (React.createElement("strong", { style: {
|
|
107
|
+
borderRadius: '2em',
|
|
108
|
+
padding: '.25em 0.5em',
|
|
109
|
+
background: 'white',
|
|
110
|
+
margin: '0 0.25em',
|
|
111
|
+
color: 'black',
|
|
112
|
+
textAlign: 'center',
|
|
113
|
+
} }, warnings.length)))),
|
|
114
|
+
React.createElement("button", { onClick: () => {
|
|
115
|
+
setOpen(true);
|
|
116
|
+
setActivePanel('network');
|
|
117
|
+
}, disabled: activePanel === 'network', style: {
|
|
118
|
+
margin: '0 0.5em',
|
|
119
|
+
textDecoration: open && activePanel === 'network' ? 'underline' : 'none',
|
|
120
|
+
} }, "Network")),
|
|
121
|
+
React.createElement("div", { style: { paddingTop: '2em' } }, activePanelContent))));
|
|
122
|
+
}
|
|
123
|
+
return null;
|
|
124
|
+
}
|
|
125
|
+
const PanelHeading = ({ children }) => (React.createElement("h1", { style: {
|
|
126
|
+
paddingTop: '1em',
|
|
127
|
+
fontWeight: 'bold',
|
|
128
|
+
} }, children));
|
|
@@ -8,6 +8,8 @@ export interface LinkProps extends Omit<React.AnchorHTMLAttributes<HTMLAnchorEle
|
|
|
8
8
|
clientState?: any;
|
|
9
9
|
/** Whether to reload the whole document on navigation. */
|
|
10
10
|
reloadDocument?: boolean;
|
|
11
|
+
/** Whether to prefetch the link source when the user signals intent. Defaults to `true`. For more information, refer to [Prefetching a link source](/custom-storefronts/hydrogen/framework/routes#prefetching-a-link-source). */
|
|
12
|
+
prefetch?: boolean;
|
|
11
13
|
}
|
|
12
14
|
/**
|
|
13
15
|
* The `Link` component is used to navigate between routes. Because it renders an underlying `<a>` element, all
|
|
@@ -15,3 +17,7 @@ export interface LinkProps extends Omit<React.AnchorHTMLAttributes<HTMLAnchorEle
|
|
|
15
17
|
* For more information, refer to the [`<a>` element documentation](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#attributes).
|
|
16
18
|
*/
|
|
17
19
|
export declare const Link: React.ForwardRefExoticComponent<LinkProps & React.RefAttributes<HTMLAnchorElement>>;
|
|
20
|
+
/**
|
|
21
|
+
* Credit: Remix's <Link> component.
|
|
22
|
+
*/
|
|
23
|
+
export declare function composeEventHandlers<EventType extends React.SyntheticEvent | Event>(theirHandler: ((event: EventType) => any) | undefined, ourHandler: (event: EventType) => any): (event: EventType) => any;
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import React, { useCallback } from 'react';
|
|
1
|
+
import React, { useCallback, useEffect, useState } from 'react';
|
|
2
2
|
import { useRouter } from '../../foundation/Router/BrowserRouter.client';
|
|
3
3
|
import { createPath } from 'history';
|
|
4
4
|
import { useNavigate } from '../../foundation/useNavigate/useNavigate';
|
|
5
|
+
import { useServerState } from '../../foundation/useServerState';
|
|
6
|
+
import { RSC_PATHNAME } from '../../constants';
|
|
5
7
|
/**
|
|
6
8
|
* The `Link` component is used to navigate between routes. Because it renders an underlying `<a>` element, all
|
|
7
9
|
* properties available to the `<a>` element are also available to the `Link` component.
|
|
@@ -10,7 +12,13 @@ import { useNavigate } from '../../foundation/useNavigate/useNavigate';
|
|
|
10
12
|
export const Link = React.forwardRef(function Link(props, ref) {
|
|
11
13
|
const navigate = useNavigate();
|
|
12
14
|
const { location } = useRouter();
|
|
13
|
-
const
|
|
15
|
+
const [_, startTransition] = React.useTransition();
|
|
16
|
+
/**
|
|
17
|
+
* Inspired by Remix's Link component
|
|
18
|
+
*/
|
|
19
|
+
const [shouldPrefetch, setShouldPrefetch] = useState(false);
|
|
20
|
+
const [maybePrefetch, setMaybePrefetch] = useState(false);
|
|
21
|
+
const { reloadDocument, target, replace: _replace, to, onClick, clientState, prefetch = true, } = props;
|
|
14
22
|
const internalClick = useCallback((e) => {
|
|
15
23
|
if (onClick)
|
|
16
24
|
onClick(e);
|
|
@@ -28,8 +36,82 @@ export const Link = React.forwardRef(function Link(props, ref) {
|
|
|
28
36
|
});
|
|
29
37
|
}
|
|
30
38
|
}, [reloadDocument, target, _replace, to, clientState, onClick, location]);
|
|
31
|
-
|
|
39
|
+
const signalPrefetchIntent = () => {
|
|
40
|
+
/**
|
|
41
|
+
* startTransition to yield to more important updates
|
|
42
|
+
*/
|
|
43
|
+
startTransition(() => {
|
|
44
|
+
if (prefetch) {
|
|
45
|
+
setMaybePrefetch(true);
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
};
|
|
49
|
+
const cancelPrefetchIntent = () => {
|
|
50
|
+
/**
|
|
51
|
+
* startTransition to yield to more important updates
|
|
52
|
+
*/
|
|
53
|
+
startTransition(() => {
|
|
54
|
+
if (prefetch) {
|
|
55
|
+
setMaybePrefetch(false);
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
};
|
|
59
|
+
/**
|
|
60
|
+
* Wrapping `maybePrefetch` inside useEffect allows the user to quickly graze over
|
|
61
|
+
* a link without triggering a prefetch.
|
|
62
|
+
*/
|
|
63
|
+
useEffect(() => {
|
|
64
|
+
if (maybePrefetch) {
|
|
65
|
+
const id = setTimeout(() => {
|
|
66
|
+
setShouldPrefetch(true);
|
|
67
|
+
}, 100);
|
|
68
|
+
return () => {
|
|
69
|
+
clearTimeout(id);
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
}, [maybePrefetch]);
|
|
73
|
+
const onMouseEnter = composeEventHandlers(props.onMouseEnter, signalPrefetchIntent);
|
|
74
|
+
const onMouseLeave = composeEventHandlers(props.onMouseLeave, cancelPrefetchIntent);
|
|
75
|
+
const onFocus = composeEventHandlers(props.onFocus, signalPrefetchIntent);
|
|
76
|
+
const onBlur = composeEventHandlers(props.onBlur, cancelPrefetchIntent);
|
|
77
|
+
const onTouchStart = composeEventHandlers(props.onTouchStart, signalPrefetchIntent);
|
|
78
|
+
return (React.createElement(React.Fragment, null,
|
|
79
|
+
React.createElement("a", { ...without(props, [
|
|
80
|
+
'to',
|
|
81
|
+
'replace',
|
|
82
|
+
'clientState',
|
|
83
|
+
'reloadDocument',
|
|
84
|
+
'prefetch',
|
|
85
|
+
]), ref: ref, onClick: internalClick, onMouseEnter: onMouseEnter, onMouseLeave: onMouseLeave, onFocus: onFocus, onBlur: onBlur, onTouchStart: onTouchStart, href: props.to }, props.children),
|
|
86
|
+
shouldPrefetch && React.createElement(Prefetch, { pathname: to })));
|
|
32
87
|
});
|
|
88
|
+
function Prefetch({ pathname }) {
|
|
89
|
+
const { getProposedServerState } = useServerState();
|
|
90
|
+
const { location } = useRouter();
|
|
91
|
+
const newPath = createPath({ pathname });
|
|
92
|
+
if (pathname.startsWith('http') || newPath === createPath(location)) {
|
|
93
|
+
return null;
|
|
94
|
+
}
|
|
95
|
+
const newLocation = new URL(newPath, window.location.href);
|
|
96
|
+
const proposedServerState = getProposedServerState({
|
|
97
|
+
pathname: newLocation.pathname,
|
|
98
|
+
search: newLocation.search,
|
|
99
|
+
});
|
|
100
|
+
const href = `${RSC_PATHNAME}?state=` +
|
|
101
|
+
encodeURIComponent(JSON.stringify(proposedServerState));
|
|
102
|
+
return React.createElement("link", { rel: "prefetch", as: "fetch", href: href });
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Credit: Remix's <Link> component.
|
|
106
|
+
*/
|
|
107
|
+
export function composeEventHandlers(theirHandler, ourHandler) {
|
|
108
|
+
return (event) => {
|
|
109
|
+
theirHandler === null || theirHandler === void 0 ? void 0 : theirHandler(event);
|
|
110
|
+
if (!event.defaultPrevented) {
|
|
111
|
+
ourHandler(event);
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
}
|
|
33
115
|
function isModifiedEvent(event) {
|
|
34
116
|
return !!(event.metaKey || event.altKey || event.ctrlKey || event.shiftKey);
|
|
35
117
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { LocalizationQuery } from './
|
|
1
|
+
import type { LocalizationQuery } from './LocalizationProvider.server';
|
|
2
2
|
export declare type Localization = LocalizationQuery['localization'];
|
|
3
3
|
export interface LocalizationContextValue {
|
|
4
4
|
country?: Localization['country'];
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { ReactNode } from 'react';
|
|
2
2
|
import { PreloadOptions } from '../../types';
|
|
3
|
+
import { Country, Currency } from '../../storefront-api-types';
|
|
3
4
|
export interface LocalizationProviderProps {
|
|
4
5
|
/** A `ReactNode` element. */
|
|
5
6
|
children: ReactNode;
|
|
@@ -19,3 +20,18 @@ export interface LocalizationProviderProps {
|
|
|
19
20
|
* `@inContext` directive as the `country` value.
|
|
20
21
|
*/
|
|
21
22
|
export declare function LocalizationProvider(props: LocalizationProviderProps): JSX.Element;
|
|
23
|
+
export declare type LocalizationQuery = {
|
|
24
|
+
__typename?: 'QueryRoot';
|
|
25
|
+
} & {
|
|
26
|
+
localization: {
|
|
27
|
+
__typename?: 'Localization';
|
|
28
|
+
} & {
|
|
29
|
+
country: {
|
|
30
|
+
__typename?: 'Country';
|
|
31
|
+
} & Pick<Country, 'isoCode' | 'name'> & {
|
|
32
|
+
currency: {
|
|
33
|
+
__typename?: 'Currency';
|
|
34
|
+
} & Pick<Currency, 'isoCode'>;
|
|
35
|
+
};
|
|
36
|
+
};
|
|
37
|
+
};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import LocalizationClientProvider from './LocalizationClientProvider.client';
|
|
3
|
+
import { useShop } from '../../foundation/useShop';
|
|
3
4
|
import { useShopQuery } from '../../hooks/useShopQuery';
|
|
4
5
|
import { CacheDays } from '../../framework/CachingStrategy';
|
|
5
6
|
/**
|
|
@@ -12,15 +13,19 @@ import { CacheDays } from '../../framework/CachingStrategy';
|
|
|
12
13
|
* `@inContext` directive as the `country` value.
|
|
13
14
|
*/
|
|
14
15
|
export function LocalizationProvider(props) {
|
|
16
|
+
const { languageCode } = useShop();
|
|
15
17
|
const { data: { localization }, } = useShopQuery({
|
|
16
18
|
query: query,
|
|
19
|
+
variables: { language: languageCode },
|
|
17
20
|
cache: CacheDays(),
|
|
18
21
|
preload: props.preload,
|
|
19
22
|
});
|
|
20
23
|
return (React.createElement(LocalizationClientProvider, { localization: localization }, props.children));
|
|
21
24
|
}
|
|
22
|
-
const query = `
|
|
23
|
-
|
|
25
|
+
const query = `
|
|
26
|
+
query Localization($language: LanguageCode)
|
|
27
|
+
@inContext(language: $language) {
|
|
28
|
+
localization {
|
|
24
29
|
country {
|
|
25
30
|
isoCode
|
|
26
31
|
name
|
|
@@ -5,8 +5,7 @@ import { TitleSeo } from './TitleSeo.client';
|
|
|
5
5
|
import { DescriptionSeo } from './DescriptionSeo.client';
|
|
6
6
|
import { TwitterSeo } from './TwitterSeo.client';
|
|
7
7
|
export function DefaultPageSeo({ title, description, url, titleTemplate, lang, }) {
|
|
8
|
-
const {
|
|
9
|
-
const fallBacklang = locale.split(/[-_]/)[0];
|
|
8
|
+
const { languageCode: fallBacklang } = useShop();
|
|
10
9
|
return (React.createElement(React.Fragment, null,
|
|
11
10
|
React.createElement(Head, { defaultTitle: title !== null && title !== void 0 ? title : '', titleTemplate: titleTemplate !== null && titleTemplate !== void 0 ? titleTemplate : `%s - ${title}` },
|
|
12
11
|
React.createElement("html", { lang: lang !== null && lang !== void 0 ? lang : fallBacklang }),
|
|
@@ -1 +1,7 @@
|
|
|
1
1
|
export declare const RSC_PATHNAME = "/__rsc";
|
|
2
|
+
export declare const EVENT_PATHNAME = "/__event";
|
|
3
|
+
export declare const EVENT_PATHNAME_REGEX: RegExp;
|
|
4
|
+
export declare const OXYGEN_SECRET_TOKEN_ENVIRONMENT_VARIABLE = "SHOPIFY_STOREFRONT_API_SECRET_TOKEN";
|
|
5
|
+
export declare const STOREFRONT_API_SECRET_TOKEN_HEADER = "Shopify-Storefront-Private-Token";
|
|
6
|
+
export declare const STOREFRONT_API_PUBLIC_TOKEN_HEADER = "X-Shopify-Storefront-Access-Token";
|
|
7
|
+
export declare const STOREFRONT_API_BUYER_IP_HEADER = "Shopify-Storefront-Buyer-IP";
|
package/dist/esnext/constants.js
CHANGED
|
@@ -1 +1,7 @@
|
|
|
1
1
|
export const RSC_PATHNAME = '/__rsc';
|
|
2
|
+
export const EVENT_PATHNAME = '/__event';
|
|
3
|
+
export const EVENT_PATHNAME_REGEX = new RegExp(`^${EVENT_PATHNAME}\/`);
|
|
4
|
+
export const OXYGEN_SECRET_TOKEN_ENVIRONMENT_VARIABLE = 'SHOPIFY_STOREFRONT_API_SECRET_TOKEN';
|
|
5
|
+
export const STOREFRONT_API_SECRET_TOKEN_HEADER = 'Shopify-Storefront-Private-Token';
|
|
6
|
+
export const STOREFRONT_API_PUBLIC_TOKEN_HEADER = 'X-Shopify-Storefront-Access-Token';
|
|
7
|
+
export const STOREFRONT_API_BUYER_IP_HEADER = 'Shopify-Storefront-Buyer-IP';
|
|
@@ -4,6 +4,7 @@ import { hydrateRoot } from 'react-dom/client';
|
|
|
4
4
|
import { ErrorBoundary } from 'react-error-boundary';
|
|
5
5
|
import { useServerResponse } from './framework/Hydration/rsc';
|
|
6
6
|
import { ServerStateProvider } from './foundation/ServerStateProvider';
|
|
7
|
+
const DevTools = React.lazy(() => import('./components/DevTools'));
|
|
7
8
|
const renderHydrogen = async (ClientWrapper, config) => {
|
|
8
9
|
const root = document.getElementById('root');
|
|
9
10
|
if (!root) {
|
|
@@ -19,10 +20,25 @@ const renderHydrogen = async (ClientWrapper, config) => {
|
|
|
19
20
|
}
|
|
20
21
|
// default to StrictMode on, unless explicitly turned off
|
|
21
22
|
const RootComponent = (config === null || config === void 0 ? void 0 : config.strictMode) !== false ? StrictMode : Fragment;
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
23
|
+
let hasCaughtError = false;
|
|
24
|
+
hydrateRoot(root, React.createElement(React.Fragment, null,
|
|
25
|
+
React.createElement(RootComponent, null,
|
|
26
|
+
React.createElement(ErrorBoundary, { FallbackComponent: Error },
|
|
27
|
+
React.createElement(Suspense, { fallback: null },
|
|
28
|
+
React.createElement(Content, { clientWrapper: ClientWrapper })))),
|
|
29
|
+
typeof DevTools !== 'undefined' && (config === null || config === void 0 ? void 0 : config.showDevTools) ? (React.createElement(DevTools, null)) : null), {
|
|
30
|
+
onRecoverableError(e) {
|
|
31
|
+
if (__DEV__ && !hasCaughtError) {
|
|
32
|
+
hasCaughtError = true;
|
|
33
|
+
console.log(`React encountered an error while attempting to hydrate the application. ` +
|
|
34
|
+
`This is likely due to a bug in React's Suspense behavior related to experimental server components, ` +
|
|
35
|
+
`and it is safe to ignore this error.\n` +
|
|
36
|
+
`Visit this issue to learn more: https://github.com/Shopify/hydrogen/issues/920.\n\n` +
|
|
37
|
+
`The original error is printed below:`);
|
|
38
|
+
console.log(e);
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
});
|
|
26
42
|
};
|
|
27
43
|
export default renderHydrogen;
|
|
28
44
|
function Content({ clientWrapper: ClientWrapper = ({ children }) => children, }) {
|
|
@@ -19,5 +19,5 @@ interface RequestHandlerOptions {
|
|
|
19
19
|
export interface RequestHandler {
|
|
20
20
|
(request: Request | IncomingMessage, options: RequestHandlerOptions): Promise<Response | undefined>;
|
|
21
21
|
}
|
|
22
|
-
export declare const renderHydrogen: (App: any, { shopifyConfig, routes }: ServerHandlerConfig) => RequestHandler;
|
|
22
|
+
export declare const renderHydrogen: (App: any, { shopifyConfig, routes, serverAnalyticsConnectors }: ServerHandlerConfig) => RequestHandler;
|
|
23
23
|
export default renderHydrogen;
|