@okendo/shopify-hydrogen 1.3.1 → 2.0.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/LICENSE.txt +1 -1
- package/README.md +377 -468
- package/dist/cjs/index.js +1 -0
- package/dist/cjs/types/components/OkendoProvider/OkendoProvider.d.ts +36 -0
- package/dist/cjs/types/components/OkendoProvider/index.d.ts +1 -0
- package/dist/cjs/types/components/OkendoReviews/OkendoReviews.d.ts +11 -0
- package/dist/cjs/types/components/OkendoReviews/index.d.ts +1 -0
- package/dist/cjs/types/components/OkendoStarRating/OkendoStarRating.d.ts +11 -0
- package/dist/cjs/types/components/OkendoStarRating/index.d.ts +1 -0
- package/dist/cjs/types/components/index.d.ts +3 -0
- package/dist/cjs/types/fragments/fragments.d.ts +2 -0
- package/dist/cjs/types/fragments/index.d.ts +1 -0
- package/dist/cjs/types/index.d.ts +2 -0
- package/dist/cjs/types/internal/OkendoWidget/OkendoWidget.d.ts +12 -0
- package/dist/cjs/types/internal/types.d.ts +3 -0
- package/dist/{esnext/shared/productUtils.d.ts → cjs/types/internal/utils.d.ts} +6 -6
- package/dist/esm/index.js +1 -0
- package/dist/esm/types/components/OkendoProvider/OkendoProvider.d.ts +36 -0
- package/dist/esm/types/components/OkendoProvider/index.d.ts +1 -0
- package/dist/esm/types/components/OkendoReviews/OkendoReviews.d.ts +11 -0
- package/dist/esm/types/components/OkendoReviews/index.d.ts +1 -0
- package/dist/esm/types/components/OkendoStarRating/OkendoStarRating.d.ts +11 -0
- package/dist/esm/types/components/OkendoStarRating/index.d.ts +1 -0
- package/dist/esm/types/components/index.d.ts +3 -0
- package/dist/esm/types/fragments/fragments.d.ts +2 -0
- package/dist/esm/types/fragments/index.d.ts +1 -0
- package/dist/esm/types/index.d.ts +2 -0
- package/dist/esm/types/internal/OkendoWidget/OkendoWidget.d.ts +12 -0
- package/dist/esm/types/internal/types.d.ts +3 -0
- package/dist/esm/types/internal/utils.d.ts +6 -0
- package/dist/index.d.ts +64 -0
- package/package.json +31 -50
- package/dist/esnext/client-components/OkendoClientStarRating.client.d.ts +0 -4
- package/dist/esnext/client-components/OkendoClientStarRating.client.js +0 -24
- package/dist/esnext/client-components/OkendoWidget.client.d.ts +0 -13
- package/dist/esnext/client-components/OkendoWidget.client.js +0 -23
- package/dist/esnext/client-components/index.d.ts +0 -1
- package/dist/esnext/client-components/index.js +0 -1
- package/dist/esnext/client.d.ts +0 -1
- package/dist/esnext/client.js +0 -1
- package/dist/esnext/components/OkendoProvider.server.d.ts +0 -15
- package/dist/esnext/components/OkendoProvider.server.js +0 -69
- package/dist/esnext/components/OkendoReviewsWidget.server.d.ts +0 -6
- package/dist/esnext/components/OkendoReviewsWidget.server.js +0 -61
- package/dist/esnext/components/OkendoStarRating.server.d.ts +0 -4
- package/dist/esnext/components/OkendoStarRating.server.js +0 -46
- package/dist/esnext/components/index.d.ts +0 -3
- package/dist/esnext/components/index.js +0 -3
- package/dist/esnext/fragments/index.d.ts +0 -1
- package/dist/esnext/fragments/index.js +0 -11
- package/dist/esnext/framework/index.d.ts +0 -0
- package/dist/esnext/framework/index.js +0 -1
- package/dist/esnext/framework/plugins/plugin.d.ts +0 -7
- package/dist/esnext/framework/plugins/plugin.js +0 -7
- package/dist/esnext/framework/plugins/suppressModuleWarning.d.ts +0 -3
- package/dist/esnext/framework/plugins/suppressModuleWarning.js +0 -18
- package/dist/esnext/index.d.ts +0 -4
- package/dist/esnext/index.js +0 -4
- package/dist/esnext/models/starRating.d.ts +0 -12
- package/dist/esnext/models/starRating.js +0 -1
- package/dist/esnext/shared/errorUtils.d.ts +0 -3
- package/dist/esnext/shared/errorUtils.js +0 -9
- package/dist/esnext/shared/logger.d.ts +0 -14
- package/dist/esnext/shared/logger.js +0 -7
- package/dist/esnext/shared/productUtils.js +0 -15
- package/dist/esnext/shared/server/requestUtils.d.ts +0 -7
- package/dist/esnext/shared/server/requestUtils.js +0 -4
- package/dist/esnext/shared/sharedTypes.d.ts +0 -5
- package/dist/esnext/shared/sharedTypes.js +0 -1
- package/dist/node/framework/index.d.ts +0 -0
- package/dist/node/framework/index.js +0 -1
- package/dist/node/framework/plugins/plugin.d.ts +0 -4
- package/dist/node/framework/plugins/plugin.js +0 -12
- package/dist/node/framework/plugins/suppressModuleWarning.d.ts +0 -3
- package/dist/node/framework/plugins/suppressModuleWarning.js +0 -20
- package/plugin.cjs +0 -1
package/README.md
CHANGED
|
@@ -1,95 +1,49 @@
|
|
|
1
|
-
|
|
1
|
+
> Note: this package is to be used on stores built with Hydrogen v2, based on Remix. If your store is built with the now deprecated Hydrogen v1, please use [version 1 of this package](https://www.npmjs.com/package/@okendo/shopify-hydrogen/v/1.3.0).
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
# Okendo Hydrogen 2 (Remix) React Components
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
This is the React component library to support Okendo Widget Plus Widgets in Shopify Hydrogen Projects.
|
|
8
|
-
|
|
9
|
-
Currently we provide the following components:
|
|
10
|
-
|
|
11
|
-
### Server Components
|
|
12
|
-
|
|
13
|
-
1. [Reviews List](#components--okendo-reviews-widget)
|
|
14
|
-
2. [Star Ratings](#components--okendo-star-rating)
|
|
15
|
-
|
|
16
|
-
### Client Components
|
|
17
|
-
|
|
18
|
-
1. [Star Ratings](#components--okendo-client-star-rating)
|
|
19
|
-
|
|
20
|
-
<br/>
|
|
21
|
-
|
|
22
|
-
# Table of contents
|
|
23
|
-
|
|
24
|
-
1. [What is Okendo Shopify Hydrogen](#introduction)
|
|
25
|
-
2. [Guided Installation](#installation)
|
|
26
|
-
- [Configure Hydrogen App](#configure-hydrogen-app-config)
|
|
27
|
-
- [Expose Shopify Metafields](#expose-shopify-metafields)
|
|
28
|
-
3. [How to Use Okendo Hydrogen Components In Your Hydrogen Apps](#how-to-use-okendo-hydrogen-components-in-your-hydrogen-app)
|
|
29
|
-
4. [Components](#components)
|
|
30
|
-
5. [GraphQL Fragments](#graphql-fragments)
|
|
31
|
-
6. [View Our Okendo Sample Hydrogen App](#view-our-okendo-sample-hydrogen-app)
|
|
32
|
-
|
|
33
|
-
<br/><br/>
|
|
34
|
-
|
|
35
|
-
# What is Okendo Shopify Hydrogen? <a id="introduction" name="introduction"></a>
|
|
36
|
-
|
|
37
|
-
Okendo Shopify Hydrogen is a React component library to be used in Shopify Hydrogen apps. This utilises [Shopify’s Hydrogen framework](https://shopify.dev/custom-storefronts/hydrogen/framework) which is used to create custom storefronts using both server-side rendered and client-side rendered React components.
|
|
38
|
-
|
|
39
|
-
The purpose of this library is for a Hydrogen-based React Shopify storefront to import this library so that the Okendo Reviews List and Okendo Star Ratings components can be rendered within their React application, providing [Okendo’s reviews display functionality](https://www.okendo.io/blog/widget-plus/).
|
|
40
|
-
|
|
41
|
-
<br/>
|
|
42
|
-
|
|
43
|
-
# Guided Installation <a id="installation" name="installation"></a>
|
|
44
|
-
|
|
45
|
-
The purpose of this documentation is to guide you on the following:
|
|
46
|
-
|
|
47
|
-
- How to configure your Shopify store ready for Okendo Shopify Hydrogen.
|
|
48
|
-
- How to install and configure Okendo Shopify Hydrogen components in your Shopify Hydrogen app.
|
|
49
|
-
|
|
50
|
-
<br/>
|
|
5
|
+
This package brings [Okendo's review widgets](https://www.okendo.io/blog/widget-plus/) to a Shopify Hydrogen store.
|
|
51
6
|
|
|
52
7
|
## Requirements
|
|
53
8
|
|
|
54
|
-
-
|
|
55
|
-
-
|
|
56
|
-
-
|
|
57
|
-
-
|
|
9
|
+
- A Shopify store with the **Okendo: Product Reviews & UCG** app installed and configured.
|
|
10
|
+
- For existing merchants, your store must be upgraded to Okendo's Widget Plus widgets. It is free to upgrade. For more information please [contact Okendo Support](mailto:support@okendo.io).
|
|
11
|
+
- A current Okendo subscription.
|
|
12
|
+
- A [Storefront access token](https://github.com/okendo/okendo-shopify-hydrogen-demo/wiki/Configure-Shopify-Storefront-API).
|
|
13
|
+
- A [Shopify Hydrogen](https://hydrogen.shopify.dev/) app.
|
|
58
14
|
|
|
59
|
-
|
|
15
|
+
## Demo Store
|
|
60
16
|
|
|
61
|
-
|
|
17
|
+
Our demo store, which is based on the demo store provided by Shopify, can be found [here](https://github.com/okendo/okendo-shopify-hydrogen-demo).
|
|
62
18
|
|
|
63
|
-
|
|
64
|
-
2. Make the following changes and save the file:
|
|
65
|
-
- Update `storeDomain` to specify your store's domain name.
|
|
66
|
-
- Update `storefrontToken` to specify your Storefront API access token.
|
|
19
|
+
## How it works
|
|
67
20
|
|
|
68
|
-
|
|
21
|
+
This package provides:
|
|
69
22
|
|
|
70
|
-
|
|
23
|
+
- one function: `getOkendoProviderData`
|
|
24
|
+
- three React components: `OkendoProvider`, `OkendoStarRating`, and `OkendoReviews`
|
|
71
25
|
|
|
72
|
-
|
|
26
|
+
The function `getOkendoProviderData` needs to be called in the `loader` function of the `root.tsx` file in the Hydrogen 2 store. The data is then retrieved in `App` through `useLoaderData` and provided to `OkendoProvider` which is added in the `body` of the HTML returned by `App`.
|
|
73
27
|
|
|
74
|
-
|
|
28
|
+
Then the components `OkendoStarRating` and `OkendoReviews` can be added on the store pages. There are a few more bits of configuration to do, please see below.
|
|
75
29
|
|
|
76
|
-
|
|
30
|
+
## Expose Shopify Metafields <a id="expose-shopify-metafields" name="expose-shopify-metafields"></a>
|
|
77
31
|
|
|
78
|
-
|
|
32
|
+
Okendo Reviews use Product and Shop [metafields](https://shopify.dev/api/examples/metafields). You will need to expose these metafields so that they can be retrieved by your Hydrogen app.
|
|
79
33
|
|
|
80
|
-
|
|
34
|
+
At the moment, Shopify does not have a way of exposing Shop Metafields through their admin UI, so the preferred method is to [contact Okendo Support](mailto:support@okendo.io).
|
|
81
35
|
|
|
82
36
|
<details>
|
|
83
|
-
|
|
37
|
+
<summary>For technical users, follow this method to expose metafields via the storefront API</summary>
|
|
84
38
|
|
|
85
|
-
|
|
39
|
+
### Exposing Metafields via GraphQL
|
|
86
40
|
|
|
87
|
-
|
|
41
|
+
#### Using Curl
|
|
88
42
|
|
|
89
|
-
You can also expose the required Okendo Shopify
|
|
43
|
+
You can also expose the required Okendo Shopify metafields by using GraphQL with curl.
|
|
90
44
|
|
|
91
45
|
1. Open a new terminal or PowerShell window.
|
|
92
|
-
2. Run the following command to expose the `
|
|
46
|
+
2. Run the following command to expose the `WidgetPreRenderStyleTags` shop metafield:
|
|
93
47
|
|
|
94
48
|
```bash
|
|
95
49
|
curl -X POST \
|
|
@@ -98,26 +52,26 @@ https://{shop}.myshopify.com/admin/api/2022-04/graphql.json \
|
|
|
98
52
|
-H 'X-Shopify-Access-Token: {access_token}' \
|
|
99
53
|
-d '
|
|
100
54
|
mutation {
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
55
|
+
metafieldStorefrontVisibilityCreate(
|
|
56
|
+
input: {
|
|
57
|
+
namespace: "okendo"
|
|
58
|
+
key: "WidgetPreRenderStyleTags"
|
|
59
|
+
ownerType: SHOP
|
|
60
|
+
}
|
|
61
|
+
) {
|
|
62
|
+
metafieldStorefrontVisibility {
|
|
63
|
+
id
|
|
64
|
+
}
|
|
65
|
+
userErrors {
|
|
66
|
+
field
|
|
67
|
+
message
|
|
68
|
+
}
|
|
69
|
+
}
|
|
116
70
|
}
|
|
117
71
|
'
|
|
118
72
|
```
|
|
119
73
|
|
|
120
|
-
3. Run the following command to expose the `WidgetPreRenderBodyStyleTags`
|
|
74
|
+
3. Run the following command to expose the `WidgetPreRenderBodyStyleTags` shop metafield:
|
|
121
75
|
|
|
122
76
|
```bash
|
|
123
77
|
curl -X POST \
|
|
@@ -126,26 +80,26 @@ https://{shop}.myshopify.com/admin/api/2022-04/graphql.json \
|
|
|
126
80
|
-H 'X-Shopify-Access-Token: {access_token}' \
|
|
127
81
|
-d '
|
|
128
82
|
mutation {
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
83
|
+
metafieldStorefrontVisibilityCreate(
|
|
84
|
+
input: {
|
|
85
|
+
namespace: "okendo"
|
|
86
|
+
key: "WidgetPreRenderBodyStyleTags"
|
|
87
|
+
ownerType: SHOP
|
|
88
|
+
}
|
|
89
|
+
) {
|
|
90
|
+
metafieldStorefrontVisibility {
|
|
91
|
+
id
|
|
92
|
+
}
|
|
93
|
+
userErrors {
|
|
94
|
+
field
|
|
95
|
+
message
|
|
96
|
+
}
|
|
97
|
+
}
|
|
144
98
|
}
|
|
145
99
|
'
|
|
146
100
|
```
|
|
147
101
|
|
|
148
|
-
4. Run the following command to expose the `ReviewsWidgetSnippet`
|
|
102
|
+
4. Run the following command to expose the `ReviewsWidgetSnippet` product metafield:
|
|
149
103
|
|
|
150
104
|
```bash
|
|
151
105
|
curl -X POST \
|
|
@@ -154,26 +108,26 @@ https://{shop}.myshopify.com/admin/api/2022-04/graphql.json \
|
|
|
154
108
|
-H 'X-Shopify-Access-Token: {access_token}' \
|
|
155
109
|
-d '
|
|
156
110
|
mutation {
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
111
|
+
metafieldStorefrontVisibilityCreate(
|
|
112
|
+
input: {
|
|
113
|
+
namespace: "okendo"
|
|
114
|
+
key: "ReviewsWidgetSnippet"
|
|
115
|
+
ownerType: PRODUCT
|
|
116
|
+
}
|
|
117
|
+
) {
|
|
118
|
+
metafieldStorefrontVisibility {
|
|
119
|
+
id
|
|
120
|
+
}
|
|
121
|
+
userErrors {
|
|
122
|
+
field
|
|
123
|
+
message
|
|
124
|
+
}
|
|
125
|
+
}
|
|
172
126
|
}
|
|
173
127
|
'
|
|
174
128
|
```
|
|
175
129
|
|
|
176
|
-
5. Run the following command to expose the `StarRatingSnippet` the
|
|
130
|
+
5. Run the following command to expose the `StarRatingSnippet` the product metafield:
|
|
177
131
|
|
|
178
132
|
```bash
|
|
179
133
|
curl -X POST \
|
|
@@ -182,21 +136,21 @@ https://{shop}.myshopify.com/admin/api/2022-04/graphql.json \
|
|
|
182
136
|
-H 'X-Shopify-Access-Token: {access_token}' \
|
|
183
137
|
-d '
|
|
184
138
|
mutation {
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
139
|
+
metafieldStorefrontVisibilityCreate(
|
|
140
|
+
input: {
|
|
141
|
+
namespace: "okendo"
|
|
142
|
+
key: "StarRatingSnippet"
|
|
143
|
+
ownerType: PRODUCT
|
|
144
|
+
}
|
|
145
|
+
) {
|
|
146
|
+
metafieldStorefrontVisibility {
|
|
147
|
+
id
|
|
148
|
+
}
|
|
149
|
+
userErrors {
|
|
150
|
+
field
|
|
151
|
+
message
|
|
152
|
+
}
|
|
153
|
+
}
|
|
200
154
|
}
|
|
201
155
|
'
|
|
202
156
|
```
|
|
@@ -204,89 +158,91 @@ mutation {
|
|
|
204
158
|
### Using GraphQL IDE
|
|
205
159
|
|
|
206
160
|
1. Open your GraphQL IDE (such as Postman) and make a `POST` request with the following details:
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
161
|
+
|
|
162
|
+
- **URL:** https://{shop}.myshopify.com/admin/api/2022-04/graphql.json
|
|
163
|
+
- **Headers:** - X-Shopify-Access-Token: {access_token} - Content-Type: application/json
|
|
164
|
+
|
|
165
|
+
2. Execute the following request to expose the `WidgetPreRenderStyleTags` shop metafield:
|
|
210
166
|
|
|
211
167
|
```graphql
|
|
212
168
|
mutation {
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
169
|
+
metafieldStorefrontVisibilityCreate(
|
|
170
|
+
input: {
|
|
171
|
+
namespace: "okendo"
|
|
172
|
+
key: "WidgetPreRenderStyleTags"
|
|
173
|
+
ownerType: SHOP
|
|
174
|
+
}
|
|
175
|
+
) {
|
|
176
|
+
metafieldStorefrontVisibility {
|
|
177
|
+
id
|
|
178
|
+
}
|
|
179
|
+
userErrors {
|
|
180
|
+
field
|
|
181
|
+
message
|
|
182
|
+
}
|
|
183
|
+
}
|
|
228
184
|
}
|
|
229
185
|
```
|
|
230
186
|
|
|
231
|
-
3. Execute the following request to expose the `WidgetPreRenderBodyStyleTags`
|
|
187
|
+
3. Execute the following request to expose the `WidgetPreRenderBodyStyleTags` shop metafield:
|
|
232
188
|
|
|
233
189
|
```graphql
|
|
234
190
|
mutation {
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
191
|
+
metafieldStorefrontVisibilityCreate(
|
|
192
|
+
input: {
|
|
193
|
+
namespace: "okendo"
|
|
194
|
+
key: "WidgetPreRenderBodyStyleTags"
|
|
195
|
+
ownerType: SHOP
|
|
196
|
+
}
|
|
197
|
+
) {
|
|
198
|
+
metafieldStorefrontVisibility {
|
|
199
|
+
id
|
|
200
|
+
}
|
|
201
|
+
userErrors {
|
|
202
|
+
field
|
|
203
|
+
message
|
|
204
|
+
}
|
|
205
|
+
}
|
|
250
206
|
}
|
|
251
207
|
```
|
|
252
208
|
|
|
253
|
-
4. Execute the following request to expose the `ReviewsWidgetSnippet`
|
|
209
|
+
4. Execute the following request to expose the `ReviewsWidgetSnippet` product metafield:
|
|
254
210
|
|
|
255
211
|
```graphql
|
|
256
212
|
mutation {
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
213
|
+
metafieldStorefrontVisibilityCreate(
|
|
214
|
+
input: {
|
|
215
|
+
namespace: "okendo"
|
|
216
|
+
key: "ReviewsWidgetSnippet"
|
|
217
|
+
ownerType: PRODUCT
|
|
218
|
+
}
|
|
219
|
+
) {
|
|
220
|
+
metafieldStorefrontVisibility {
|
|
221
|
+
id
|
|
222
|
+
}
|
|
223
|
+
userErrors {
|
|
224
|
+
field
|
|
225
|
+
message
|
|
226
|
+
}
|
|
227
|
+
}
|
|
272
228
|
}
|
|
273
229
|
```
|
|
274
230
|
|
|
275
|
-
5. Execute the following request to expose the `StarRatingSnippet` the
|
|
231
|
+
5. Execute the following request to expose the `StarRatingSnippet` the product metafield:
|
|
276
232
|
|
|
277
233
|
```graphql
|
|
278
234
|
mutation {
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
235
|
+
metafieldStorefrontVisibilityCreate(
|
|
236
|
+
input: { namespace: "okendo", key: "StarRatingSnippet", ownerType: PRODUCT }
|
|
237
|
+
) {
|
|
238
|
+
metafieldStorefrontVisibility {
|
|
239
|
+
id
|
|
240
|
+
}
|
|
241
|
+
userErrors {
|
|
242
|
+
field
|
|
243
|
+
message
|
|
244
|
+
}
|
|
245
|
+
}
|
|
290
246
|
}
|
|
291
247
|
```
|
|
292
248
|
|
|
@@ -296,337 +252,290 @@ mutation {
|
|
|
296
252
|
- [https://shopify.dev/api/admin-graphql/2022-04/mutations/metafieldstorefrontvisibilitycreate](https://shopify.dev/api/admin-graphql/2022-04/mutations/metafieldstorefrontvisibilitycreate)
|
|
297
253
|
</details>
|
|
298
254
|
|
|
299
|
-
<br/><br/>
|
|
300
|
-
|
|
301
|
-
# How to Use Okendo Hydrogen Components In Your Hydrogen App <a id="how-to-use-okendo-hydrogen-components-in-your-hydrogen-app" name="3-how-to-use-okendo-hydrogen-components-in-your-hydrogen-app"></a>
|
|
302
|
-
|
|
303
255
|
## Installation
|
|
304
256
|
|
|
305
|
-
|
|
306
|
-
2. **Optional:** Create (or add to) your `.env` file at the top level of your project (next to **hydrogen.config.ts**) the following, where `<your_subscriber_id>` is replaced with your Okendo Subscriber ID:
|
|
307
|
-
|
|
308
|
-
```sh
|
|
309
|
-
# .env
|
|
310
|
-
VITE_OKENDO_SUBSCRIBER_ID=<your_subscriber_id>
|
|
311
|
-
```
|
|
312
|
-
|
|
313
|
-
3. Open **vite.config.ts** and add `import okendo from '@okendo/shopify-hydrogen/plugin';` to the list of imports.
|
|
314
|
-
4. Add `okendo()` to the list of `plugins`.
|
|
315
|
-
|
|
316
|
-
```tsx
|
|
317
|
-
/* vite.config.ts */
|
|
318
|
-
/// <reference types="vitest" />
|
|
319
|
-
import { defineConfig } from "vite";
|
|
320
|
-
import hydrogen from "@shopify/hydrogen/plugin";
|
|
321
|
-
import okendo from "@okendo/shopify-hydrogen/plugin";
|
|
322
|
-
|
|
323
|
-
export default defineConfig({
|
|
324
|
-
plugins: [hydrogen(), okendo()],
|
|
325
|
-
resolve: {
|
|
326
|
-
alias: [{ find: /^~\/(.*)/, replacement: "/src/$1" }],
|
|
327
|
-
},
|
|
328
|
-
optimizeDeps: {
|
|
329
|
-
include: ["@headlessui/react", "clsx", "react-use", "typographic-base"],
|
|
330
|
-
},
|
|
331
|
-
test: {
|
|
332
|
-
globals: true,
|
|
333
|
-
testTimeout: 10000,
|
|
334
|
-
hookTimeout: 10000,
|
|
335
|
-
},
|
|
336
|
-
});
|
|
337
|
-
```
|
|
338
|
-
|
|
339
|
-
5. Open **App.server.tsx** and import `OkendoProvider`.
|
|
340
|
-
6. Include the `OkendoProvider` as shown below, passing through your `subscriberId` from your Vite environment variables.
|
|
341
|
-
|
|
342
|
-
```tsx
|
|
343
|
-
/* App.server.tsx */
|
|
344
|
-
import {OkendoProvider} from '@okendo/shopify-hydrogen';
|
|
345
|
-
|
|
346
|
-
function App() {
|
|
347
|
-
return (
|
|
348
|
-
<Suspense fallback={<LoadingFallback />}>
|
|
349
|
-
<ShopifyProvider>
|
|
350
|
-
<!-- *** Include OkendoProvider HERE *** -->
|
|
351
|
-
<OkendoProvider
|
|
352
|
-
subscriberId={import.meta.env.VITE_OKENDO_SUBSCRIBER_ID}
|
|
353
|
-
/>
|
|
354
|
-
<ServerCartProvider>
|
|
355
|
-
<DefaultSeo />
|
|
356
|
-
<Router>
|
|
357
|
-
<FileRoutes />
|
|
358
|
-
<Route path="*" page={<NotFound />} />
|
|
359
|
-
</Router>
|
|
360
|
-
</ServerCartProvider>
|
|
361
|
-
<PerformanceMetrics />
|
|
362
|
-
{import.meta.env.DEV && <PerformanceMetricsDebug />}
|
|
363
|
-
</ShopifyProvider>
|
|
364
|
-
</Suspense>
|
|
365
|
-
);
|
|
366
|
-
```
|
|
367
|
-
|
|
368
|
-
If your app doesn't use Vite environment variables from a `.env` file, you could also provide your Okendo Subscriber ID through other means, i.e. directly:
|
|
369
|
-
|
|
370
|
-
```tsx
|
|
371
|
-
<OkendoProvider subscriberId={okendoSubscriberId} />
|
|
372
|
-
```
|
|
373
|
-
|
|
374
|
-
## Widget Usage
|
|
375
|
-
|
|
376
|
-
### Server Components
|
|
377
|
-
|
|
378
|
-
Import `OkendoReviewsWidget` and `OkendoStarRating` and use as JSX components. Pass in the Shopify Product ID as a prop.
|
|
379
|
-
|
|
380
|
-
The `productId` prop is optional for the `OkendoReviewsWidget`. Not providing it will mean that the widget will display reviews for all products, which is ideal for homepages or collection pages.
|
|
381
|
-
|
|
382
|
-
```tsx
|
|
383
|
-
import {
|
|
384
|
-
OkendoReviewsWidget,
|
|
385
|
-
OkendoStarRating,
|
|
386
|
-
} from '@okendo/shopify-hydrogen';
|
|
257
|
+
> The code examples provided in this section are based on the [demo store provided by Shopify](https://github.com/Shopify/hydrogen/tree/2023-01/templates/demo-store). You will find the following steps already done in [our demo store](https://github.com/okendo/okendo-shopify-hydrogen-demo).
|
|
387
258
|
|
|
388
|
-
|
|
259
|
+
Run:
|
|
389
260
|
|
|
390
|
-
|
|
391
|
-
|
|
261
|
+
```bash
|
|
262
|
+
npm i @okendo/shopify-hydrogen
|
|
392
263
|
```
|
|
393
264
|
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
<br />
|
|
397
|
-
|
|
398
|
-
### Client Components
|
|
399
|
-
|
|
400
|
-
#### Star Rating Widget Usage in Client Components
|
|
401
|
-
|
|
402
|
-
We also include an `OkendoClientStarRating` component for use within client-side (e.g.`<your component>.client.tsx`) components.
|
|
265
|
+
### `app/root.tsx`
|
|
403
266
|
|
|
404
|
-
|
|
267
|
+
Open `app/root.tsx` and add the following import:
|
|
405
268
|
|
|
406
|
-
```
|
|
407
|
-
import {
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
const okendoClientStarRating = <OkendoClientStarRating productId={product.id} />;
|
|
269
|
+
```ts
|
|
270
|
+
import {
|
|
271
|
+
OkendoProvider,
|
|
272
|
+
getOkendoProviderData,
|
|
273
|
+
} from "@okendo/shopify-hydrogen";
|
|
412
274
|
```
|
|
413
275
|
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
<br />
|
|
417
|
-
|
|
418
|
-
# Components <a id="components" name="components"></a>
|
|
419
|
-
|
|
420
|
-
### OkendoProvider
|
|
421
|
-
|
|
422
|
-
Top level component for enabling Okendo Widgets.
|
|
423
|
-
|
|
424
|
-
We recommend using it directly inside the `<ShopifyProvider>` as its first child in **App.server.tsx**.
|
|
425
|
-
|
|
426
|
-
It will provide:
|
|
276
|
+
Locate the `meta` function, and append the property `oke:subscriber_id` containing your Okendo subscriber ID:
|
|
427
277
|
|
|
428
|
-
|
|
429
|
-
-
|
|
430
|
-
|
|
431
|
-
- Custom CSS specified in the Okendo Admin (if applicable)
|
|
432
|
-
- "Above the fold" CSS essential for Server-Side Rendered (SSR) widgets. This ensures styled widgets prior to client-side hydration.
|
|
433
|
-
- Okendo widget initialisation script
|
|
434
|
-
- Used to render/hydrate widgets on the page
|
|
435
|
-
|
|
436
|
-
| Name | Type | Description | Required |
|
|
437
|
-
| ------------------------------------- | ----------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- |
|
|
438
|
-
| <code>subscriberId</code> | <code>string</code> | The Okendo subscriber ID. | yes |
|
|
439
|
-
| <code>apiDomain</code> | <code>string</code> | To override the default Okendo API Domain. (Default: <code>api.okendo.io/v1</code>) | no |
|
|
440
|
-
| <code>cdnDomain</code> | <code>string</code> | To override the default Okendo CDN domain. (Default: <code>cdn-static.okendo.io</code>) | no |
|
|
441
|
-
| <code>productUrlFormatOverride</code> | <code>(product: ReviewProduct) => string</code> | By default, we use Hydrogen's out of the box product routing.<br />**Advanced Usage Only:** Function hook which allows the custom configuration of the Shopify product URLs from the Okendo Reviews Widget. | no |
|
|
442
|
-
|
|
443
|
-
### OkendoReviewsWidget<a id="components--okendo-reviews-widget" name="components--okendo-reviews-widget"></a>
|
|
444
|
-
|
|
445
|
-
The Okendo Reviews List widget.
|
|
446
|
-
|
|
447
|
-
| Name | Type | Description | Required |
|
|
448
|
-
| ---------------------- | ------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- |
|
|
449
|
-
| <code>productId</code> | <code>string</code> | The Shopify Product ID. If provided, the Reviews Widget will be configured to display reviews specific to that product. Otherwise, the Reviews Widget will display reviews for all products. | no |
|
|
450
|
-
|
|
451
|
-
### OkendoStarRating<a id="components--okendo-star-rating" name="components--okendo-star-rating"></a>
|
|
452
|
-
|
|
453
|
-
The Okendo Star Rating widget - **For use in _server_ components**.
|
|
454
|
-
|
|
455
|
-
| Name | Type | Description | Required |
|
|
456
|
-
| ---------------------- | ------------------- | ----------------------- | -------- |
|
|
457
|
-
| <code>productId</code> | <code>string</code> | The Shopify Product ID. | yes |
|
|
278
|
+
```ts
|
|
279
|
+
'oke:subscriber_id': '<your-okendo-subscriber-id>',
|
|
280
|
+
```
|
|
458
281
|
|
|
459
|
-
|
|
282
|
+
The `meta` function should now look like the following:
|
|
460
283
|
|
|
461
|
-
|
|
284
|
+
```ts
|
|
285
|
+
export const meta: MetaFunction = () => ({
|
|
286
|
+
charset: "utf-8",
|
|
287
|
+
viewport: "width=device-width,initial-scale=1",
|
|
288
|
+
"oke:subscriber_id": "<your-okendo-subscriber-id>",
|
|
289
|
+
});
|
|
290
|
+
```
|
|
462
291
|
|
|
463
|
-
|
|
292
|
+
Locate the `loader` function and append the `okendoProviderData` property to the returned data:
|
|
464
293
|
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
294
|
+
```ts
|
|
295
|
+
okendoProviderData: await getOkendoProviderData({
|
|
296
|
+
context,
|
|
297
|
+
subscriberId: '<your-okendo-subscriber-id>',
|
|
298
|
+
}),
|
|
299
|
+
```
|
|
469
300
|
|
|
470
|
-
|
|
301
|
+
The `loader` function returned data should now look like the following:
|
|
302
|
+
|
|
303
|
+
```ts
|
|
304
|
+
return defer({
|
|
305
|
+
isLoggedIn: Boolean(customerAccessToken),
|
|
306
|
+
layout,
|
|
307
|
+
selectedLocale: context.storefront.i18n,
|
|
308
|
+
cart: cartId ? getCart(context, cartId) : undefined,
|
|
309
|
+
analytics: {
|
|
310
|
+
shopifySalesChannel: ShopifySalesChannel.hydrogen,
|
|
311
|
+
shopId: layout.shop.id,
|
|
312
|
+
},
|
|
313
|
+
seo,
|
|
314
|
+
okendoProviderData: await getOkendoProviderData({
|
|
315
|
+
context,
|
|
316
|
+
subscriberId: "<your-okendo-subscriber-id>",
|
|
317
|
+
}),
|
|
318
|
+
});
|
|
319
|
+
```
|
|
471
320
|
|
|
472
|
-
|
|
321
|
+
Locate the `App` function, append `OkendoProvider` to `body`, and provide it with the data returned by `getOkendoProviderData`:
|
|
473
322
|
|
|
474
|
-
|
|
323
|
+
```tsx
|
|
324
|
+
...
|
|
325
|
+
<body>
|
|
326
|
+
<OkendoProvider okendoProviderData={data.okendoProviderData} />
|
|
327
|
+
...
|
|
328
|
+
</body>
|
|
329
|
+
...
|
|
330
|
+
```
|
|
475
331
|
|
|
476
|
-
|
|
332
|
+
### `app/data/fragments.ts`
|
|
477
333
|
|
|
478
|
-
|
|
334
|
+
Open `app/data/fragments.ts` and add the following import:
|
|
479
335
|
|
|
480
|
-
|
|
336
|
+
```ts
|
|
337
|
+
import { OKENDO_PRODUCT_STAR_RATING_FRAGMENT } from "@okendo/shopify-hydrogen";
|
|
338
|
+
```
|
|
481
339
|
|
|
482
|
-
|
|
340
|
+
Then add `${OKENDO_PRODUCT_STAR_RATING_FRAGMENT}` and `...OkendoStarRatingSnippet` to `PRODUCT_CARD_FRAGMENT`:
|
|
341
|
+
|
|
342
|
+
```ts
|
|
343
|
+
export const PRODUCT_CARD_FRAGMENT = `#graphql
|
|
344
|
+
${OKENDO_PRODUCT_STAR_RATING_FRAGMENT}
|
|
345
|
+
fragment ProductCard on Product {
|
|
346
|
+
id
|
|
347
|
+
title
|
|
348
|
+
publishedAt
|
|
349
|
+
handle
|
|
350
|
+
...OkendoStarRatingSnippet
|
|
351
|
+
variants(first: 1) {
|
|
352
|
+
...
|
|
353
|
+
```
|
|
483
354
|
|
|
484
|
-
|
|
355
|
+
### `app/components/ProductCard.tsx`
|
|
485
356
|
|
|
486
|
-
|
|
357
|
+
Open `app/components/ProductCard.tsx` and add the following import:
|
|
487
358
|
|
|
488
|
-
|
|
359
|
+
```ts
|
|
360
|
+
import {
|
|
361
|
+
OkendoStarRating,
|
|
362
|
+
WithOkendoStarRatingSnippet,
|
|
363
|
+
} from "@okendo/shopify-hydrogen";
|
|
364
|
+
```
|
|
489
365
|
|
|
490
|
-
|
|
366
|
+
Tweak the type of the `product` prop to be:
|
|
491
367
|
|
|
492
|
-
|
|
368
|
+
```ts
|
|
369
|
+
product: SerializeFrom<Product & WithOkendoStarRatingSnippet>;
|
|
370
|
+
```
|
|
493
371
|
|
|
494
|
-
|
|
372
|
+
`ProductCard` should now look like this:
|
|
495
373
|
|
|
496
|
-
|
|
374
|
+
```ts
|
|
375
|
+
export function ProductCard({
|
|
376
|
+
product,
|
|
377
|
+
label,
|
|
378
|
+
className,
|
|
379
|
+
loading,
|
|
380
|
+
onClick,
|
|
381
|
+
quickAdd,
|
|
382
|
+
}: {
|
|
383
|
+
product: SerializeFrom<Product & WithOkendoStarRatingSnippet>;
|
|
384
|
+
label?: string;
|
|
385
|
+
className?: string;
|
|
386
|
+
loading?: HTMLImageElement['loading'];
|
|
387
|
+
onClick?: () => void;
|
|
388
|
+
quickAdd?: boolean;
|
|
389
|
+
}) {
|
|
390
|
+
```
|
|
497
391
|
|
|
498
|
-
|
|
392
|
+
Add the `OkendoStarRating` component:
|
|
499
393
|
|
|
500
394
|
```tsx
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
publishedAt
|
|
506
|
-
handle
|
|
507
|
-
variants(first: 1) {
|
|
508
|
-
nodes {
|
|
509
|
-
id
|
|
510
|
-
image {
|
|
511
|
-
url
|
|
512
|
-
altText
|
|
513
|
-
width
|
|
514
|
-
height
|
|
515
|
-
}
|
|
516
|
-
priceV2 {
|
|
517
|
-
amount
|
|
518
|
-
currencyCode
|
|
519
|
-
}
|
|
520
|
-
compareAtPriceV2 {
|
|
521
|
-
amount
|
|
522
|
-
currencyCode
|
|
523
|
-
}
|
|
524
|
-
}
|
|
525
|
-
}
|
|
526
|
-
}
|
|
527
|
-
`;
|
|
395
|
+
<OkendoStarRating
|
|
396
|
+
productId={product.id}
|
|
397
|
+
okendoStarRatingSnippet={product.okendoStarRatingSnippet}
|
|
398
|
+
/>
|
|
528
399
|
```
|
|
529
400
|
|
|
530
|
-
|
|
401
|
+
For instance, you can add it below the product title, like this:
|
|
531
402
|
|
|
532
403
|
```tsx
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
id
|
|
544
|
-
image {
|
|
545
|
-
url
|
|
546
|
-
altText
|
|
547
|
-
width
|
|
548
|
-
height
|
|
549
|
-
}
|
|
550
|
-
priceV2 {
|
|
551
|
-
amount
|
|
552
|
-
currencyCode
|
|
553
|
-
}
|
|
554
|
-
compareAtPriceV2 {
|
|
555
|
-
amount
|
|
556
|
-
currencyCode
|
|
557
|
-
}
|
|
558
|
-
}
|
|
559
|
-
}
|
|
560
|
-
}
|
|
561
|
-
`;
|
|
404
|
+
<Text
|
|
405
|
+
className="w-full overflow-hidden whitespace-nowrap text-ellipsis "
|
|
406
|
+
as="h3"
|
|
407
|
+
>
|
|
408
|
+
{product.title}
|
|
409
|
+
</Text>
|
|
410
|
+
<OkendoStarRating
|
|
411
|
+
productId={product.id}
|
|
412
|
+
okendoStarRatingSnippet={product.okendoStarRatingSnippet}
|
|
413
|
+
/>
|
|
562
414
|
```
|
|
563
415
|
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
The `okendoStarRatingSnippet` is a server-side rendered version of the output of your star rating contents. This is supplied to your `Product`/`Collection` queries using the `OKENDO_PRODUCT_STAR_RATING_FRAGMENT` to fetch a metafield containg the markup.
|
|
416
|
+
### `app/routes/($lang)/products/$productHandle.tsx`
|
|
567
417
|
|
|
568
|
-
|
|
418
|
+
Open `app/routes/($lang)/products/$productHandle.tsx` and add the following imports:
|
|
569
419
|
|
|
570
|
-
|
|
420
|
+
```ts
|
|
421
|
+
import {
|
|
422
|
+
OkendoReviews,
|
|
423
|
+
OkendoStarRating,
|
|
424
|
+
WithOkendoStarRatingSnippet,
|
|
425
|
+
WithOkendoReviewsSnippet,
|
|
426
|
+
OKENDO_PRODUCT_STAR_RATING_FRAGMENT,
|
|
427
|
+
OKENDO_PRODUCT_REVIEWS_FRAGMENT,
|
|
428
|
+
} from "@okendo/shopify-hydrogen";
|
|
429
|
+
```
|
|
571
430
|
|
|
572
|
-
|
|
431
|
+
In the storefront query, tweak the type of `product` to be:
|
|
573
432
|
|
|
574
|
-
|
|
433
|
+
```ts
|
|
434
|
+
product: ProductType & {
|
|
435
|
+
selectedVariant?: ProductVariant;
|
|
436
|
+
} & WithOkendoStarRatingSnippet &
|
|
437
|
+
WithOkendoReviewsSnippet;
|
|
438
|
+
```
|
|
575
439
|
|
|
576
|
-
|
|
577
|
-
|
|
440
|
+
The storefront query should now look like this:
|
|
441
|
+
|
|
442
|
+
```ts
|
|
443
|
+
const { shop, product } = await context.storefront.query<{
|
|
444
|
+
product: ProductType & {
|
|
445
|
+
selectedVariant?: ProductVariant;
|
|
446
|
+
} & WithOkendoStarRatingSnippet &
|
|
447
|
+
WithOkendoReviewsSnippet;
|
|
448
|
+
shop: Shop;
|
|
449
|
+
}>(PRODUCT_QUERY, {
|
|
450
|
+
variables: {
|
|
451
|
+
handle: productHandle,
|
|
452
|
+
selectedOptions,
|
|
453
|
+
country: context.storefront.i18n.country,
|
|
454
|
+
language: context.storefront.i18n.language,
|
|
455
|
+
},
|
|
456
|
+
});
|
|
578
457
|
```
|
|
579
458
|
|
|
580
|
-
|
|
459
|
+
Add the `OkendoStarRating` component:
|
|
581
460
|
|
|
582
461
|
```tsx
|
|
583
|
-
|
|
584
|
-
|
|
462
|
+
<OkendoStarRating
|
|
463
|
+
productId={product.id}
|
|
464
|
+
okendoStarRatingSnippet={product.okendoStarRatingSnippet}
|
|
465
|
+
/>
|
|
585
466
|
```
|
|
586
467
|
|
|
587
|
-
|
|
468
|
+
For instance, you can add it between the product title and the store name, like this:
|
|
588
469
|
|
|
589
470
|
```tsx
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
loading?: HTMLImageElement['loading'];
|
|
601
|
-
onClick?: () => void;
|
|
602
|
-
}) {
|
|
603
|
-
...
|
|
604
|
-
}
|
|
471
|
+
<Heading as="h1" className="whitespace-normal">
|
|
472
|
+
{title}
|
|
473
|
+
</Heading>
|
|
474
|
+
<OkendoStarRating
|
|
475
|
+
productId={product.id}
|
|
476
|
+
okendoStarRatingSnippet={product.okendoStarRatingSnippet}
|
|
477
|
+
/>
|
|
478
|
+
{vendor && (
|
|
479
|
+
<Text className={'opacity-50 font-medium'}>{vendor}</Text>
|
|
480
|
+
)}
|
|
605
481
|
```
|
|
606
482
|
|
|
607
|
-
|
|
483
|
+
Add the `OkendoReviews` component:
|
|
608
484
|
|
|
609
485
|
```tsx
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
okendoStarRatingSnippet={product.okendoStarRatingSnippet}
|
|
615
|
-
/>
|
|
616
|
-
) : null;
|
|
617
|
-
}
|
|
486
|
+
<OkendoReviews
|
|
487
|
+
productId={product.id}
|
|
488
|
+
okendoReviewsSnippet={product.okendoReviewsSnippet}
|
|
489
|
+
/>
|
|
618
490
|
```
|
|
619
491
|
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
- [GraphQL Fragments](https://www.apollographql.com/docs/react/data/fragments/)
|
|
492
|
+
For instance, you can add it below the product section:
|
|
623
493
|
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
494
|
+
```tsx
|
|
495
|
+
...
|
|
496
|
+
</Section>
|
|
497
|
+
<OkendoReviews
|
|
498
|
+
productId={product.id}
|
|
499
|
+
okendoReviewsSnippet={product.okendoReviewsSnippet}
|
|
500
|
+
/>
|
|
501
|
+
<Suspense fallback={<Skeleton className="h-32" />}>
|
|
502
|
+
...
|
|
503
|
+
```
|
|
627
504
|
|
|
628
|
-
|
|
505
|
+
Locate `PRODUCT_QUERY` and add the following to it:
|
|
629
506
|
|
|
630
|
-
|
|
507
|
+
```ts
|
|
508
|
+
...
|
|
509
|
+
${OKENDO_PRODUCT_STAR_RATING_FRAGMENT}
|
|
510
|
+
${OKENDO_PRODUCT_REVIEWS_FRAGMENT}
|
|
511
|
+
...
|
|
512
|
+
...OkendoStarRatingSnippet
|
|
513
|
+
...OkendoReviewsSnippet
|
|
514
|
+
```
|
|
631
515
|
|
|
632
|
-
|
|
516
|
+
It should now look like this:
|
|
517
|
+
|
|
518
|
+
```ts
|
|
519
|
+
const PRODUCT_QUERY = `#graphql
|
|
520
|
+
${MEDIA_FRAGMENT}
|
|
521
|
+
${PRODUCT_VARIANT_FRAGMENT}
|
|
522
|
+
${OKENDO_PRODUCT_STAR_RATING_FRAGMENT}
|
|
523
|
+
${OKENDO_PRODUCT_REVIEWS_FRAGMENT}
|
|
524
|
+
query Product(
|
|
525
|
+
$country: CountryCode
|
|
526
|
+
$language: LanguageCode
|
|
527
|
+
$handle: String!
|
|
528
|
+
$selectedOptions: [SelectedOptionInput!]!
|
|
529
|
+
) @inContext(country: $country, language: $language) {
|
|
530
|
+
product(handle: $handle) {
|
|
531
|
+
id
|
|
532
|
+
title
|
|
533
|
+
vendor
|
|
534
|
+
handle
|
|
535
|
+
descriptionHtml
|
|
536
|
+
description
|
|
537
|
+
...OkendoStarRatingSnippet
|
|
538
|
+
...OkendoReviewsSnippet
|
|
539
|
+
options {
|
|
540
|
+
...
|
|
541
|
+
```
|