@okendo/shopify-hydrogen 2.2.6 → 2.3.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/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
> Note: this package is to be used on stores built with Hydrogen v2, based on Remix. If your store is built with the deprecated Hydrogen v1, please use the [version 1](https://www.npmjs.com/package/@okendo/shopify-hydrogen/v/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 deprecated Hydrogen v1, please use the [version 1](https://www.npmjs.com/package/@okendo/shopify-hydrogen/v/1.6.6) of this package.
|
|
2
2
|
|
|
3
3
|
# Okendo Hydrogen 2 (Remix) React Components
|
|
4
4
|
|
|
@@ -15,7 +15,7 @@ This package brings [Okendo's review widgets](https://www.okendo.io/blog/widget-
|
|
|
15
15
|
|
|
16
16
|
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).
|
|
17
17
|
|
|
18
|
-
> Note: there have been multiple versions of Shopify's Hydrogen demo store. If your project is based on an old version of it, consult the history of our demo store's repository.
|
|
18
|
+
> Note: there have been multiple versions of Shopify's Hydrogen demo store. If your project is based on an old version of it, consult the [history of our demo store's repository](https://github.com/okendo/okendo-shopify-hydrogen-demo/commits/master/).
|
|
19
19
|
|
|
20
20
|
## Exposition of Shopify Metafields <a id="expose-shopify-metafields" name="expose-shopify-metafields"></a>
|
|
21
21
|
|
|
@@ -42,7 +42,6 @@ unauthenticated_read_product_tags
|
|
|
42
42
|
|
|
43
43
|
Follow the instructions on [this page](https://help.shopify.com/en/manual/apps/app-types/custom-apps#create-and-install-a-custom-app) to create it.
|
|
44
44
|
|
|
45
|
-
|
|
46
45
|
#### Using Curl
|
|
47
46
|
|
|
48
47
|
Open a new terminal or PowerShell window, then:
|
|
@@ -56,22 +55,22 @@ https://{shop}.myshopify.com/admin/api/2024-10/graphql.json \
|
|
|
56
55
|
-H 'X-Shopify-Access-Token: {access_token}' \
|
|
57
56
|
-d '
|
|
58
57
|
mutation {
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
58
|
+
metafieldDefinitionCreate(
|
|
59
|
+
definition: {
|
|
60
|
+
name: "WidgetPreRenderStyleTags"
|
|
61
|
+
namespace: "$app:reviews"
|
|
62
|
+
key: "widget_pre_render_style_tags"
|
|
63
|
+
type: "multi_line_text_field"
|
|
64
|
+
ownerType: SHOP
|
|
65
|
+
access: {
|
|
66
|
+
admin: PUBLIC_READ
|
|
67
|
+
storefront: PUBLIC_READ
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
) {
|
|
71
|
+
createdDefinition { id name }
|
|
72
|
+
userErrors { field message code }
|
|
73
|
+
}
|
|
75
74
|
}
|
|
76
75
|
'
|
|
77
76
|
```
|
|
@@ -85,22 +84,22 @@ https://{shop}.myshopify.com/admin/api/2024-10/graphql.json \
|
|
|
85
84
|
-H 'X-Shopify-Access-Token: {access_token}' \
|
|
86
85
|
-d '
|
|
87
86
|
mutation {
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
87
|
+
metafieldDefinitionCreate(
|
|
88
|
+
definition: {
|
|
89
|
+
name: "WidgetPreRenderBodyStyleTags"
|
|
90
|
+
namespace: "$app:reviews"
|
|
91
|
+
key: "widget_pre_render_body_style_tags"
|
|
92
|
+
type: "multi_line_text_field"
|
|
93
|
+
ownerType: SHOP
|
|
94
|
+
access: {
|
|
95
|
+
admin: PUBLIC_READ
|
|
96
|
+
storefront: PUBLIC_READ
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
) {
|
|
100
|
+
createdDefinition { id name }
|
|
101
|
+
userErrors { field message code }
|
|
102
|
+
}
|
|
104
103
|
}
|
|
105
104
|
'
|
|
106
105
|
```
|
|
@@ -114,22 +113,22 @@ https://{shop}.myshopify.com/admin/api/2024-10/graphql.json \
|
|
|
114
113
|
-H 'X-Shopify-Access-Token: {access_token}' \
|
|
115
114
|
-d '
|
|
116
115
|
mutation {
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
116
|
+
metafieldDefinitionCreate(
|
|
117
|
+
definition: {
|
|
118
|
+
name: "ReviewsWidgetSnippet"
|
|
119
|
+
namespace: "$app:reviews"
|
|
120
|
+
key: "reviews_widget_snippet"
|
|
121
|
+
type: "multi_line_text_field"
|
|
122
|
+
ownerType: PRODUCT
|
|
123
|
+
access: {
|
|
124
|
+
admin: PUBLIC_READ
|
|
125
|
+
storefront: PUBLIC_READ
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
) {
|
|
129
|
+
createdDefinition { id name }
|
|
130
|
+
userErrors { field message code }
|
|
131
|
+
}
|
|
133
132
|
}
|
|
134
133
|
'
|
|
135
134
|
```
|
|
@@ -143,22 +142,22 @@ https://{shop}.myshopify.com/admin/api/2024-10/graphql.json \
|
|
|
143
142
|
-H 'X-Shopify-Access-Token: {access_token}' \
|
|
144
143
|
-d '
|
|
145
144
|
mutation {
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
145
|
+
metafieldDefinitionCreate(
|
|
146
|
+
definition: {
|
|
147
|
+
name: "StarRatingSnippet"
|
|
148
|
+
namespace: "$app:reviews"
|
|
149
|
+
key: "star_rating_snippet"
|
|
150
|
+
type: "multi_line_text_field"
|
|
151
|
+
ownerType: PRODUCT
|
|
152
|
+
access: {
|
|
153
|
+
admin: PUBLIC_READ
|
|
154
|
+
storefront: PUBLIC_READ
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
) {
|
|
158
|
+
createdDefinition { id name }
|
|
159
|
+
userErrors { field message code }
|
|
160
|
+
}
|
|
162
161
|
}
|
|
163
162
|
'
|
|
164
163
|
```
|
|
@@ -172,22 +171,22 @@ https://{shop}.myshopify.com/admin/api/2024-10/graphql.json \
|
|
|
172
171
|
-H 'X-Shopify-Access-Token: {access_token}' \
|
|
173
172
|
-d '
|
|
174
173
|
mutation {
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
174
|
+
metafieldDefinitionCreate(
|
|
175
|
+
definition: {
|
|
176
|
+
name: "ReviewCount"
|
|
177
|
+
namespace: "$app:reviews"
|
|
178
|
+
key: "review_count"
|
|
179
|
+
type: "number_integer"
|
|
180
|
+
ownerType: PRODUCT
|
|
181
|
+
access: {
|
|
182
|
+
admin: PUBLIC_READ
|
|
183
|
+
storefront: PUBLIC_READ
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
) {
|
|
187
|
+
createdDefinition { id name }
|
|
188
|
+
userErrors { field message code }
|
|
189
|
+
}
|
|
191
190
|
}
|
|
192
191
|
'
|
|
193
192
|
```
|
|
@@ -201,22 +200,22 @@ https://{shop}.myshopify.com/admin/api/2024-10/graphql.json \
|
|
|
201
200
|
-H 'X-Shopify-Access-Token: {access_token}' \
|
|
202
201
|
-d '
|
|
203
202
|
mutation {
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
203
|
+
metafieldDefinitionCreate(
|
|
204
|
+
definition: {
|
|
205
|
+
name: "AverageRating"
|
|
206
|
+
namespace: "$app:reviews"
|
|
207
|
+
key: "average_rating"
|
|
208
|
+
type: "rating"
|
|
209
|
+
ownerType: PRODUCT
|
|
210
|
+
access: {
|
|
211
|
+
admin: PUBLIC_READ
|
|
212
|
+
storefront: PUBLIC_READ
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
) {
|
|
216
|
+
createdDefinition { id name }
|
|
217
|
+
userErrors { field message code }
|
|
218
|
+
}
|
|
220
219
|
}
|
|
221
220
|
'
|
|
222
221
|
```
|
|
@@ -232,29 +231,26 @@ Open your GraphQL IDE (such as Postman) and make `POST` requests with the follow
|
|
|
232
231
|
|
|
233
232
|
```graphql
|
|
234
233
|
mutation {
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
code
|
|
256
|
-
}
|
|
257
|
-
}
|
|
234
|
+
metafieldDefinitionCreate(
|
|
235
|
+
definition: {
|
|
236
|
+
name: "WidgetPreRenderStyleTags"
|
|
237
|
+
namespace: "$app:reviews"
|
|
238
|
+
key: "widget_pre_render_style_tags"
|
|
239
|
+
type: "multi_line_text_field"
|
|
240
|
+
ownerType: SHOP
|
|
241
|
+
access: { admin: PUBLIC_READ, storefront: PUBLIC_READ }
|
|
242
|
+
}
|
|
243
|
+
) {
|
|
244
|
+
createdDefinition {
|
|
245
|
+
id
|
|
246
|
+
name
|
|
247
|
+
}
|
|
248
|
+
userErrors {
|
|
249
|
+
field
|
|
250
|
+
message
|
|
251
|
+
code
|
|
252
|
+
}
|
|
253
|
+
}
|
|
258
254
|
}
|
|
259
255
|
```
|
|
260
256
|
|
|
@@ -262,29 +258,26 @@ mutation {
|
|
|
262
258
|
|
|
263
259
|
```graphql
|
|
264
260
|
mutation {
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
code
|
|
286
|
-
}
|
|
287
|
-
}
|
|
261
|
+
metafieldDefinitionCreate(
|
|
262
|
+
definition: {
|
|
263
|
+
name: "WidgetPreRenderBodyStyleTags"
|
|
264
|
+
namespace: "$app:reviews"
|
|
265
|
+
key: "widget_pre_render_body_style_tags"
|
|
266
|
+
type: "multi_line_text_field"
|
|
267
|
+
ownerType: SHOP
|
|
268
|
+
access: { admin: PUBLIC_READ, storefront: PUBLIC_READ }
|
|
269
|
+
}
|
|
270
|
+
) {
|
|
271
|
+
createdDefinition {
|
|
272
|
+
id
|
|
273
|
+
name
|
|
274
|
+
}
|
|
275
|
+
userErrors {
|
|
276
|
+
field
|
|
277
|
+
message
|
|
278
|
+
code
|
|
279
|
+
}
|
|
280
|
+
}
|
|
288
281
|
}
|
|
289
282
|
```
|
|
290
283
|
|
|
@@ -292,29 +285,26 @@ mutation {
|
|
|
292
285
|
|
|
293
286
|
```graphql
|
|
294
287
|
mutation {
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
code
|
|
316
|
-
}
|
|
317
|
-
}
|
|
288
|
+
metafieldDefinitionCreate(
|
|
289
|
+
definition: {
|
|
290
|
+
name: "ReviewsWidgetSnippet"
|
|
291
|
+
namespace: "$app:reviews"
|
|
292
|
+
key: "reviews_widget_snippet"
|
|
293
|
+
type: "multi_line_text_field"
|
|
294
|
+
ownerType: PRODUCT
|
|
295
|
+
access: { admin: PUBLIC_READ, storefront: PUBLIC_READ }
|
|
296
|
+
}
|
|
297
|
+
) {
|
|
298
|
+
createdDefinition {
|
|
299
|
+
id
|
|
300
|
+
name
|
|
301
|
+
}
|
|
302
|
+
userErrors {
|
|
303
|
+
field
|
|
304
|
+
message
|
|
305
|
+
code
|
|
306
|
+
}
|
|
307
|
+
}
|
|
318
308
|
}
|
|
319
309
|
```
|
|
320
310
|
|
|
@@ -322,29 +312,26 @@ mutation {
|
|
|
322
312
|
|
|
323
313
|
```graphql
|
|
324
314
|
mutation {
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
code
|
|
346
|
-
}
|
|
347
|
-
}
|
|
315
|
+
metafieldDefinitionCreate(
|
|
316
|
+
definition: {
|
|
317
|
+
name: "StarRatingSnippet"
|
|
318
|
+
namespace: "$app:reviews"
|
|
319
|
+
key: "star_rating_snippet"
|
|
320
|
+
type: "multi_line_text_field"
|
|
321
|
+
ownerType: PRODUCT
|
|
322
|
+
access: { admin: PUBLIC_READ, storefront: PUBLIC_READ }
|
|
323
|
+
}
|
|
324
|
+
) {
|
|
325
|
+
createdDefinition {
|
|
326
|
+
id
|
|
327
|
+
name
|
|
328
|
+
}
|
|
329
|
+
userErrors {
|
|
330
|
+
field
|
|
331
|
+
message
|
|
332
|
+
code
|
|
333
|
+
}
|
|
334
|
+
}
|
|
348
335
|
}
|
|
349
336
|
```
|
|
350
337
|
|
|
@@ -352,29 +339,26 @@ mutation {
|
|
|
352
339
|
|
|
353
340
|
```graphql
|
|
354
341
|
mutation {
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
code
|
|
376
|
-
}
|
|
377
|
-
}
|
|
342
|
+
metafieldDefinitionCreate(
|
|
343
|
+
definition: {
|
|
344
|
+
name: "ReviewCount"
|
|
345
|
+
namespace: "$app:reviews"
|
|
346
|
+
key: "review_count"
|
|
347
|
+
type: "number_integer"
|
|
348
|
+
ownerType: PRODUCT
|
|
349
|
+
access: { admin: PUBLIC_READ, storefront: PUBLIC_READ }
|
|
350
|
+
}
|
|
351
|
+
) {
|
|
352
|
+
createdDefinition {
|
|
353
|
+
id
|
|
354
|
+
name
|
|
355
|
+
}
|
|
356
|
+
userErrors {
|
|
357
|
+
field
|
|
358
|
+
message
|
|
359
|
+
code
|
|
360
|
+
}
|
|
361
|
+
}
|
|
378
362
|
}
|
|
379
363
|
```
|
|
380
364
|
|
|
@@ -382,29 +366,26 @@ mutation {
|
|
|
382
366
|
|
|
383
367
|
```graphql
|
|
384
368
|
mutation {
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
code
|
|
406
|
-
}
|
|
407
|
-
}
|
|
369
|
+
metafieldDefinitionCreate(
|
|
370
|
+
definition: {
|
|
371
|
+
name: "AverageRating"
|
|
372
|
+
namespace: "$app:reviews"
|
|
373
|
+
key: "average_rating"
|
|
374
|
+
type: "rating"
|
|
375
|
+
ownerType: PRODUCT
|
|
376
|
+
access: { admin: PUBLIC_READ, storefront: PUBLIC_READ }
|
|
377
|
+
}
|
|
378
|
+
) {
|
|
379
|
+
createdDefinition {
|
|
380
|
+
id
|
|
381
|
+
name
|
|
382
|
+
}
|
|
383
|
+
userErrors {
|
|
384
|
+
field
|
|
385
|
+
message
|
|
386
|
+
code
|
|
387
|
+
}
|
|
388
|
+
}
|
|
408
389
|
}
|
|
409
390
|
```
|
|
410
391
|
|
|
@@ -463,9 +444,9 @@ Open `app/root.tsx` and add the following import:
|
|
|
463
444
|
|
|
464
445
|
```ts
|
|
465
446
|
import {
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
} from
|
|
447
|
+
OkendoProvider,
|
|
448
|
+
getOkendoProviderData,
|
|
449
|
+
} from '@okendo/shopify-hydrogen';
|
|
469
450
|
```
|
|
470
451
|
|
|
471
452
|
Locate the `loader` function, append `okendoProviderData` to the returned data as shown below, and set `subscriberId` to your Okendo subscriber ID.
|
|
@@ -473,40 +454,49 @@ Locate the `loader` function, append `okendoProviderData` to the returned data a
|
|
|
473
454
|
As explained above, set `okendoProviderData` to either `getOkendoProviderData(...)`, or `await getOkendoProviderData(...)`:
|
|
474
455
|
|
|
475
456
|
```ts
|
|
476
|
-
return defer(
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
)
|
|
457
|
+
return defer({
|
|
458
|
+
// ...
|
|
459
|
+
okendoProviderData:
|
|
460
|
+
/* place `await` here if you want server-rendered widgets */ getOkendoProviderData(
|
|
461
|
+
{
|
|
462
|
+
context: args.context,
|
|
463
|
+
subscriberId: '<your-okendo-subscriber-id>',
|
|
464
|
+
},
|
|
465
|
+
),
|
|
466
|
+
});
|
|
485
467
|
```
|
|
486
468
|
|
|
487
|
-
Locate the `
|
|
469
|
+
Locate the `Layout` component, add the `meta` tag `oke:subscriber_id` to `head`, and place your Okendo subscriber ID in its content:
|
|
488
470
|
|
|
489
|
-
```
|
|
471
|
+
```tsx
|
|
490
472
|
<head>
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
473
|
+
<meta charSet="utf-8" />
|
|
474
|
+
<meta name="viewport" content="width=device-width,initial-scale=1" />
|
|
475
|
+
<meta name="oke:subscriber_id" content="<your-okendo-subscriber-id>" />
|
|
476
|
+
...
|
|
477
|
+
</head>
|
|
495
478
|
```
|
|
496
479
|
|
|
497
480
|
Append `OkendoProvider` to `body`, and pass it the promise — or the data — returned by `getOkendoProviderData`. If Content Security Policy is active in your project, you also need to provide the `nonce` (available with `const nonce = useNonce()` in Shopify's Hydrogen demo store):
|
|
498
481
|
|
|
499
482
|
```tsx
|
|
500
|
-
...
|
|
501
483
|
<body>
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
484
|
+
{data ? (
|
|
485
|
+
<OkendoProvider nonce={nonce} okendoProviderData={data.okendoProviderData}>
|
|
486
|
+
<Analytics.Provider
|
|
487
|
+
cart={data.cart}
|
|
488
|
+
shop={data.shop}
|
|
489
|
+
consent={data.consent}
|
|
490
|
+
>
|
|
491
|
+
<PageLayout {...data}>{children}</PageLayout>
|
|
492
|
+
</Analytics.Provider>
|
|
493
|
+
</OkendoProvider>
|
|
494
|
+
) : (
|
|
495
|
+
children
|
|
496
|
+
)}
|
|
497
|
+
<ScrollRestoration nonce={nonce} />
|
|
498
|
+
<Scripts nonce={nonce} />
|
|
508
499
|
</body>
|
|
509
|
-
...
|
|
510
500
|
```
|
|
511
501
|
|
|
512
502
|
### `app/entry.server.tsx`
|
|
@@ -518,110 +508,108 @@ Note that it's necessary to to add the default values (`'self'`, etc.) when [ext
|
|
|
518
508
|
|
|
519
509
|
```ts
|
|
520
510
|
const { nonce, header, NonceProvider } = createContentSecurityPolicy({
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
511
|
+
shop: {
|
|
512
|
+
checkoutDomain: context.env.PUBLIC_CHECKOUT_DOMAIN,
|
|
513
|
+
storeDomain: context.env.PUBLIC_STORE_DOMAIN,
|
|
514
|
+
},
|
|
515
|
+
defaultSrc: [
|
|
516
|
+
"'self'",
|
|
517
|
+
'localhost:*',
|
|
518
|
+
'https://cdn.shopify.com',
|
|
519
|
+
'https://www.google.com',
|
|
520
|
+
'https://www.gstatic.com',
|
|
521
|
+
'https://d3hw6dc1ow8pp2.cloudfront.net',
|
|
522
|
+
'https://d3g5hqndtiniji.cloudfront.net',
|
|
523
|
+
'https://dov7r31oq5dkj.cloudfront.net',
|
|
524
|
+
'https://cdn-static.okendo.io',
|
|
525
|
+
'https://surveys.okendo.io',
|
|
526
|
+
'https://api.okendo.io',
|
|
527
|
+
'data:',
|
|
528
|
+
],
|
|
529
|
+
imgSrc: [
|
|
530
|
+
"'self'",
|
|
531
|
+
'https://cdn.shopify.com',
|
|
532
|
+
'data:',
|
|
533
|
+
'https://d3hw6dc1ow8pp2.cloudfront.net',
|
|
534
|
+
'https://d3g5hqndtiniji.cloudfront.net',
|
|
535
|
+
'https://dov7r31oq5dkj.cloudfront.net',
|
|
536
|
+
'https://cdn-static.okendo.io',
|
|
537
|
+
'https://surveys.okendo.io',
|
|
538
|
+
],
|
|
539
|
+
mediaSrc: [
|
|
540
|
+
"'self'",
|
|
541
|
+
'https://d3hw6dc1ow8pp2.cloudfront.net',
|
|
542
|
+
'https://d3g5hqndtiniji.cloudfront.net',
|
|
543
|
+
'https://dov7r31oq5dkj.cloudfront.net',
|
|
544
|
+
'https://cdn-static.okendo.io',
|
|
545
|
+
],
|
|
546
|
+
styleSrc: [
|
|
547
|
+
"'self'",
|
|
548
|
+
"'unsafe-inline'",
|
|
549
|
+
'https://cdn.shopify.com',
|
|
550
|
+
'https://fonts.googleapis.com',
|
|
551
|
+
'https://fonts.gstatic.com',
|
|
552
|
+
'https://d3hw6dc1ow8pp2.cloudfront.net',
|
|
553
|
+
'https://cdn-static.okendo.io',
|
|
554
|
+
'https://surveys.okendo.io',
|
|
555
|
+
],
|
|
556
|
+
scriptSrc: [
|
|
557
|
+
"'self'",
|
|
558
|
+
'https://cdn.shopify.com',
|
|
559
|
+
'https://d3hw6dc1ow8pp2.cloudfront.net',
|
|
560
|
+
'https://dov7r31oq5dkj.cloudfront.net',
|
|
561
|
+
'https://cdn-static.okendo.io',
|
|
562
|
+
'https://surveys.okendo.io',
|
|
563
|
+
'https://api.okendo.io',
|
|
564
|
+
'https://www.google.com',
|
|
565
|
+
'https://www.gstatic.com',
|
|
566
|
+
],
|
|
567
|
+
fontSrc: [
|
|
568
|
+
"'self'",
|
|
569
|
+
'https://fonts.gstatic.com',
|
|
570
|
+
'https://d3hw6dc1ow8pp2.cloudfront.net',
|
|
571
|
+
'https://dov7r31oq5dkj.cloudfront.net',
|
|
572
|
+
'https://cdn.shopify.com',
|
|
573
|
+
'https://cdn-static.okendo.io',
|
|
574
|
+
'https://surveys.okendo.io',
|
|
575
|
+
],
|
|
576
|
+
connectSrc: [
|
|
577
|
+
"'self'",
|
|
578
|
+
'https://monorail-edge.shopifysvc.com',
|
|
579
|
+
'localhost:*',
|
|
580
|
+
'ws://localhost:*',
|
|
581
|
+
'ws://127.0.0.1:*',
|
|
582
|
+
'https://api.okendo.io',
|
|
583
|
+
'https://cdn-static.okendo.io',
|
|
584
|
+
'https://surveys.okendo.io',
|
|
585
|
+
'https://api.raygun.com',
|
|
586
|
+
'https://www.google.com',
|
|
587
|
+
'https://www.gstatic.com',
|
|
588
|
+
],
|
|
589
|
+
frameSrc: ['https://www.google.com', 'https://www.gstatic.com'],
|
|
599
590
|
});
|
|
600
591
|
```
|
|
601
592
|
|
|
602
593
|
### `app/routes/_index.tsx`
|
|
603
594
|
|
|
604
|
-
Add the following
|
|
595
|
+
Add the following import:
|
|
605
596
|
|
|
606
597
|
```ts
|
|
607
|
-
import {
|
|
608
|
-
OkendoStarRating,
|
|
609
|
-
type WithOkendoStarRatingSnippet,
|
|
610
|
-
} from "@okendo/shopify-hydrogen";
|
|
598
|
+
import { OkendoStarRating } from '@okendo/shopify-hydrogen';
|
|
611
599
|
```
|
|
612
600
|
|
|
613
601
|
Add the following block just before the `RECOMMENDED_PRODUCTS_QUERY` GraphQL query:
|
|
614
602
|
|
|
615
603
|
```ts
|
|
616
604
|
const OKENDO_PRODUCT_STAR_RATING_FRAGMENT = `#graphql
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
605
|
+
fragment OkendoStarRatingSnippet on Product {
|
|
606
|
+
okendoStarRatingSnippet: metafield(
|
|
607
|
+
namespace: "okendo"
|
|
608
|
+
key: "StarRatingSnippet"
|
|
609
|
+
) {
|
|
610
|
+
value
|
|
611
|
+
}
|
|
612
|
+
}
|
|
625
613
|
` as const;
|
|
626
614
|
```
|
|
627
615
|
|
|
@@ -629,74 +617,56 @@ Then append `${OKENDO_PRODUCT_STAR_RATING_FRAGMENT}` and `...OkendoStarRatingSni
|
|
|
629
617
|
|
|
630
618
|
```ts
|
|
631
619
|
const RECOMMENDED_PRODUCTS_QUERY = `#graphql
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
620
|
+
${OKENDO_PRODUCT_STAR_RATING_FRAGMENT}
|
|
621
|
+
fragment RecommendedProduct on Product {
|
|
622
|
+
id
|
|
623
|
+
title
|
|
624
|
+
handle
|
|
625
|
+
priceRange {
|
|
626
|
+
minVariantPrice {
|
|
627
|
+
amount
|
|
628
|
+
currencyCode
|
|
629
|
+
}
|
|
630
|
+
}
|
|
631
|
+
images(first: 1) {
|
|
632
|
+
nodes {
|
|
633
|
+
id
|
|
634
|
+
url
|
|
635
|
+
altText
|
|
636
|
+
width
|
|
637
|
+
height
|
|
638
|
+
}
|
|
639
|
+
}
|
|
640
|
+
...OkendoStarRatingSnippet
|
|
641
|
+
}
|
|
642
|
+
query RecommendedProducts ($country: CountryCode, $language: LanguageCode)
|
|
643
|
+
@inContext(country: $country, language: $language) {
|
|
644
|
+
products(first: 4, sortKey: UPDATED_AT, reverse: true) {
|
|
645
|
+
nodes {
|
|
646
|
+
...RecommendedProduct
|
|
647
|
+
}
|
|
648
|
+
}
|
|
649
|
+
}
|
|
662
650
|
` as const;
|
|
663
651
|
```
|
|
664
652
|
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
```ts
|
|
668
|
-
products: Promise<{
|
|
669
|
-
products: {
|
|
670
|
-
nodes: (RecommendedProductsQuery["products"]["nodes"][0] &
|
|
671
|
-
WithOkendoStarRatingSnippet)[];
|
|
672
|
-
};
|
|
673
|
-
}>;
|
|
674
|
-
```
|
|
675
|
-
|
|
676
|
-
Add `OkendoStarRating` to `RecommendedProducts`:
|
|
677
|
-
|
|
678
|
-
```tsx
|
|
679
|
-
<OkendoStarRating
|
|
680
|
-
productId={product.id}
|
|
681
|
-
okendoStarRatingSnippet={product.okendoStarRatingSnippet}
|
|
682
|
-
/>
|
|
683
|
-
```
|
|
653
|
+
> Note: if you get a type error on `product`, restart the dev server to get the types (`storefrontapi.generated.d.ts`) regenerated from the GraphQL fragments.
|
|
684
654
|
|
|
685
|
-
|
|
655
|
+
Add `OkendoStarRating` to the `RecommendedProducts` component — for instance, we can add it below the product title, like this:
|
|
686
656
|
|
|
687
657
|
```tsx
|
|
688
658
|
<Image
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
659
|
+
data={product.images.nodes[0]}
|
|
660
|
+
aspectRatio="1/1"
|
|
661
|
+
sizes="(min-width: 45em) 20vw, 50vw"
|
|
692
662
|
/>
|
|
693
663
|
<h4>{product.title}</h4>
|
|
694
664
|
<OkendoStarRating
|
|
695
|
-
|
|
696
|
-
|
|
665
|
+
productId={product.id}
|
|
666
|
+
okendoStarRatingSnippet={product.okendoStarRatingSnippet}
|
|
697
667
|
/>
|
|
698
668
|
<small>
|
|
699
|
-
|
|
669
|
+
<Money data={product.priceRange.minVariantPrice} />
|
|
700
670
|
</small>
|
|
701
671
|
```
|
|
702
672
|
|
|
@@ -704,46 +674,41 @@ For instance, we can add it below the product title, like this:
|
|
|
704
674
|
|
|
705
675
|
We now have the Okendo Star Rating widget visible on our page:
|
|
706
676
|
|
|
707
|
-

|
|
677
|
+

|
|
678
|
+
|
|
679
|
+
You can do the same changes to the files `app/routes/collections.$handle.tsx` and `app/routes/collections.all.tsx` to make the items' Okendo Star Rating visible on collection pages.
|
|
708
680
|
|
|
709
681
|
### `app/routes/products.$handle.tsx`
|
|
710
682
|
|
|
711
|
-
Add the following
|
|
683
|
+
Add the following import:
|
|
712
684
|
|
|
713
685
|
```ts
|
|
714
|
-
import {
|
|
715
|
-
OKENDO_PRODUCT_REVIEWS_FRAGMENT,
|
|
716
|
-
OKENDO_PRODUCT_STAR_RATING_FRAGMENT,
|
|
717
|
-
OkendoReviews,
|
|
718
|
-
OkendoStarRating,
|
|
719
|
-
type WithOkendoReviewsSnippet,
|
|
720
|
-
type WithOkendoStarRatingSnippet,
|
|
721
|
-
} from "@okendo/shopify-hydrogen";
|
|
686
|
+
import { OkendoReviews, OkendoStarRating } from '@okendo/shopify-hydrogen';
|
|
722
687
|
```
|
|
723
688
|
|
|
724
|
-
Add the following block just before the `
|
|
689
|
+
Add the following block just before the `PRODUCT_FRAGMENT` GraphQL query:
|
|
725
690
|
|
|
726
691
|
```ts
|
|
727
692
|
const OKENDO_PRODUCT_STAR_RATING_FRAGMENT = `#graphql
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
693
|
+
fragment OkendoStarRatingSnippet on Product {
|
|
694
|
+
okendoStarRatingSnippet: metafield(
|
|
695
|
+
namespace: "okendo"
|
|
696
|
+
key: "StarRatingSnippet"
|
|
697
|
+
) {
|
|
698
|
+
value
|
|
699
|
+
}
|
|
700
|
+
}
|
|
736
701
|
` as const;
|
|
737
702
|
|
|
738
703
|
const OKENDO_PRODUCT_REVIEWS_FRAGMENT = `#graphql
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
704
|
+
fragment OkendoReviewsSnippet on Product {
|
|
705
|
+
okendoReviewsSnippet: metafield(
|
|
706
|
+
namespace: "okendo"
|
|
707
|
+
key: "ReviewsWidgetSnippet"
|
|
708
|
+
) {
|
|
709
|
+
value
|
|
710
|
+
}
|
|
711
|
+
}
|
|
747
712
|
` as const;
|
|
748
713
|
```
|
|
749
714
|
|
|
@@ -751,113 +716,86 @@ Then append `${OKENDO_PRODUCT_STAR_RATING_FRAGMENT}`, `${OKENDO_PRODUCT_REVIEWS_
|
|
|
751
716
|
|
|
752
717
|
```ts
|
|
753
718
|
const PRODUCT_FRAGMENT = `#graphql
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
719
|
+
${OKENDO_PRODUCT_STAR_RATING_FRAGMENT}
|
|
720
|
+
${OKENDO_PRODUCT_REVIEWS_FRAGMENT}
|
|
721
|
+
fragment Product on Product {
|
|
722
|
+
id
|
|
723
|
+
title
|
|
724
|
+
vendor
|
|
725
|
+
handle
|
|
726
|
+
descriptionHtml
|
|
727
|
+
description
|
|
728
|
+
options {
|
|
729
|
+
name
|
|
730
|
+
values
|
|
731
|
+
}
|
|
732
|
+
selectedVariant: variantBySelectedOptions(selectedOptions: $selectedOptions) {
|
|
733
|
+
...ProductVariant
|
|
734
|
+
}
|
|
735
|
+
variants(first: 1) {
|
|
736
|
+
nodes {
|
|
737
|
+
...ProductVariant
|
|
738
|
+
}
|
|
739
|
+
}
|
|
740
|
+
seo {
|
|
741
|
+
description
|
|
742
|
+
title
|
|
743
|
+
}
|
|
744
|
+
...OkendoStarRatingSnippet
|
|
745
|
+
...OkendoReviewsSnippet
|
|
746
|
+
}
|
|
747
|
+
${PRODUCT_VARIANT_FRAGMENT}
|
|
783
748
|
` as const;
|
|
784
749
|
```
|
|
785
750
|
|
|
786
|
-
|
|
751
|
+
> Note: if you get a type error on `product`, restart the dev server to get the types (`storefrontapi.generated.d.ts`) regenerated from the GraphQL fragments.
|
|
787
752
|
|
|
788
|
-
|
|
789
|
-
<OkendoReviews
|
|
790
|
-
productId={product.id}
|
|
791
|
-
okendoReviewsSnippet={product.okendoReviewsSnippet}
|
|
792
|
-
/>
|
|
793
|
-
```
|
|
794
|
-
|
|
795
|
-
For instance, we can add it below the product section, like this:
|
|
753
|
+
Add `OkendoStarRating` and `OkendoReviews` to the `Product` component:
|
|
796
754
|
|
|
797
755
|
```tsx
|
|
798
756
|
<>
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
> Note: if the widgets are rendered client-side (if you don't use `await` when calling `getOkendoProviderData`), you can provide your own placeholder by using the `placeholder` property of `OkendoReviews`.
|
|
816
|
-
|
|
817
|
-
Tweak the type of the `product` prop of `ProductMain`:
|
|
818
|
-
|
|
819
|
-
```ts
|
|
820
|
-
product: ProductFragment &
|
|
821
|
-
WithOkendoStarRatingSnippet &
|
|
822
|
-
WithOkendoReviewsSnippet;
|
|
823
|
-
```
|
|
824
|
-
|
|
825
|
-
Add `OkendoStarRating` to `ProductMain`:
|
|
757
|
+
<div className="product">
|
|
758
|
+
<ProductImage image={selectedVariant?.image} />
|
|
759
|
+
<div className="product-main">
|
|
760
|
+
<h1>{title}</h1>
|
|
761
|
+
<OkendoStarRating
|
|
762
|
+
productId={product.id}
|
|
763
|
+
okendoStarRatingSnippet={product.okendoStarRatingSnippet}
|
|
764
|
+
/>
|
|
765
|
+
<ProductPrice
|
|
766
|
+
price={selectedVariant?.price}
|
|
767
|
+
compareAtPrice={selectedVariant?.compareAtPrice}
|
|
768
|
+
/>
|
|
769
|
+
...
|
|
770
|
+
</div>
|
|
771
|
+
...
|
|
772
|
+
</div>
|
|
826
773
|
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
774
|
+
<OkendoReviews
|
|
775
|
+
productId={product.id}
|
|
776
|
+
okendoReviewsSnippet={product.okendoReviewsSnippet}
|
|
777
|
+
/>
|
|
778
|
+
</>
|
|
832
779
|
```
|
|
833
780
|
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
```tsx
|
|
837
|
-
<div className="product-main">
|
|
838
|
-
<h1>{title}</h1>
|
|
839
|
-
<OkendoStarRating
|
|
840
|
-
productId={product.id}
|
|
841
|
-
okendoStarRatingSnippet={product.okendoStarRatingSnippet}
|
|
842
|
-
/>
|
|
843
|
-
<ProductPrice selectedVariant={selectedVariant} />
|
|
844
|
-
```
|
|
781
|
+
> Note: if the widgets are rendered client-side (if you don't use `await` when calling `getOkendoProviderData`), you can provide your own placeholder by using the `placeholder` property of `OkendoStarRating` and `OkendoReviews`.
|
|
845
782
|
|
|
846
783
|
We now have the Okendo Star Rating and Reviews widgets visible on our product page:
|
|
847
784
|
|
|
848
|
-

|
|
785
|
+

|
|
849
786
|
|
|
850
787
|
### All Reviews Widget - Client Side Only
|
|
851
|
-
If you would like to include a copy of the Okendo Reviews Widget which displays all reviews for a given store (to be used on a reviews page for example), please add the OkendoReviewsWidget without supplying the `productId`.
|
|
852
788
|
|
|
853
|
-
|
|
789
|
+
If you would like to include a copy of the Okendo Reviews Widget which displays all reviews for a given store (to be used on a reviews page for example), please add the `OkendoReviewsWidget` without supplying the `productId`.
|
|
790
|
+
|
|
791
|
+
Please note the all reviews widget loads on the client, not the server.
|
|
854
792
|
|
|
855
793
|
```tsx
|
|
856
794
|
import { type MetaFunction } from '@remix-run/react';
|
|
857
795
|
import { OkendoReviews } from '@okendo/shopify-hydrogen';
|
|
858
796
|
|
|
859
797
|
export const meta: MetaFunction = () => {
|
|
860
|
-
return [{title: `Hydrogen | Okendo All Reviews`}];
|
|
798
|
+
return [{ title: `Hydrogen | Okendo All Reviews` }];
|
|
861
799
|
};
|
|
862
800
|
|
|
863
801
|
export default function ReviewsPage() {
|
|
@@ -868,4 +806,4 @@ export default function ReviewsPage() {
|
|
|
868
806
|
</div>
|
|
869
807
|
);
|
|
870
808
|
}
|
|
871
|
-
```
|
|
809
|
+
```
|
package/package.json
CHANGED
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@okendo/shopify-hydrogen",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.3.0",
|
|
4
4
|
"description": "Okendo React components for Shopify Hydrogen 2 (Remix)",
|
|
5
5
|
"author": "Okendo",
|
|
6
6
|
"license": "SEE LICENSE IN LICENSE.txt",
|
|
7
7
|
"engines": {
|
|
8
|
-
"node": ">=
|
|
8
|
+
"node": ">=18.0.0"
|
|
9
9
|
},
|
|
10
10
|
"main": "dist/cjs/index.js",
|
|
11
11
|
"module": "dist/esm/index.js",
|
|
12
12
|
"files": [
|
|
13
|
-
"dist"
|
|
13
|
+
"dist",
|
|
14
|
+
"readme-res"
|
|
14
15
|
],
|
|
15
16
|
"types": "dist/index.d.ts",
|
|
16
17
|
"scripts": {
|
|
Binary file
|
|
Binary file
|