@cartbase/storefront 0.19.0 → 0.20.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 +21 -21
- package/package.json +258 -258
- package/src/api/auth.ts +108 -108
- package/src/api/carts.ts +523 -523
- package/src/api/categories.ts +184 -184
- package/src/api/checkout.ts +526 -526
- package/src/api/collections.ts +130 -130
- package/src/api/consent.ts +75 -75
- package/src/api/content.ts +125 -125
- package/src/api/customers.ts +303 -303
- package/src/api/gift-cards.ts +112 -112
- package/src/api/http.ts +180 -180
- package/src/api/index.ts +30 -30
- package/src/api/menus.ts +77 -77
- package/src/api/metaobjects.ts +136 -136
- package/src/api/orders.ts +290 -290
- package/src/api/redirects.ts +37 -37
- package/src/api/regions.ts +200 -200
- package/src/api/reviews.ts +22 -1
- package/src/api/search.ts +163 -163
- package/src/api/store.ts +35 -35
- package/src/api/types.ts +91 -91
- package/src/cart-drawer/context.tsx +778 -778
- package/src/cart-drawer/cross-sell-carousel.tsx +211 -211
- package/src/cart-drawer/cross-sell-sidebar.tsx +158 -158
- package/src/cart-drawer/gift-wrap.tsx +82 -82
- package/src/cart-drawer/item/index.tsx +162 -162
- package/src/cart-drawer/item/upsell.tsx +110 -110
- package/src/cart-drawer/labels.ts +123 -123
- package/src/cart-drawer/mutation-queue.ts +78 -78
- package/src/cart-drawer/notes.tsx +131 -131
- package/src/cart-drawer/sticky-footer.tsx +73 -73
- package/src/cart-drawer/summary-breakdown.tsx +197 -197
- package/src/checkout/address-error-copy.ts +117 -117
- package/src/checkout/boxnow-locker-selector.tsx +410 -410
- package/src/checkout/compare-addresses.ts +40 -40
- package/src/checkout/discount-section.tsx +218 -218
- package/src/checkout/error-copy-codes.ts +63 -63
- package/src/checkout/geocode.ts +154 -154
- package/src/checkout/gift-card-section.tsx +224 -224
- package/src/checkout/index.ts +72 -72
- package/src/checkout/labels.ts +495 -495
- package/src/checkout/payment-button.tsx +372 -372
- package/src/checkout/payment-error-copy.ts +154 -154
- package/src/checkout/promotion-error-copy.ts +91 -91
- package/src/common/country-flag.tsx +52 -52
- package/src/common/country-select.tsx +11 -11
- package/src/common/index.ts +20 -20
- package/src/common/market-select.tsx +57 -57
- package/src/index.ts +12 -12
- package/src/lib/country-name.ts +59 -59
- package/src/lib/get-product-price.ts +133 -133
- package/src/lib/media-image.tsx +39 -39
- package/src/lib/payment-constants.ts +53 -53
- package/src/lib/platform.ts +13 -13
- package/src/lib/price.tsx +39 -39
- package/src/lib/store-api-error.ts +36 -36
- package/src/lib/variant-caption.ts +32 -32
- package/src/locales/bg.ts +3 -2
- package/src/locales/context.ts +37 -37
- package/src/locales/en.ts +26 -26
- package/src/locales/es.ts +3 -2
- package/src/locales/index.ts +19 -19
- package/src/locales/provider.tsx +59 -59
- package/src/locales/types.ts +77 -77
- package/src/order/index.ts +62 -62
- package/src/order/labels.ts +79 -79
- package/src/order/order-totals.tsx +250 -250
- package/src/primitives/select-field.tsx +93 -93
- package/src/products/image-gallery.tsx +43 -43
- package/src/products/option-select.tsx +67 -67
- package/src/products/product-info.tsx +5 -5
- package/src/products/product-price.tsx +69 -69
- package/src/products/product-promises.tsx +61 -61
- package/src/products/product-specs.tsx +65 -65
- package/src/products/product-tabs.tsx +123 -123
- package/src/products/purchase-options.tsx +130 -130
- package/src/products/sets.ts +110 -110
- package/src/products/variant-matching.ts +71 -71
- package/src/products/variant-url.ts +74 -74
- package/src/reviews-ui/index.ts +12 -0
- package/src/reviews-ui/labels.ts +5 -2
- package/src/reviews-ui/lightbox-state.ts +46 -46
- package/src/reviews-ui/review-header.tsx +166 -0
- package/src/reviews-ui/review-lightbox.tsx +271 -271
- package/src/reviews-ui/review-list.tsx +193 -191
- package/src/reviews-ui/review-widget.tsx +63 -71
- package/src/reviews-ui/star-badge.tsx +6 -4
- package/src/reviews-ui/widget-options.ts +55 -0
- package/src/store/category-template.tsx +136 -136
- package/src/store/index.ts +40 -40
- package/src/tracking/chatgpt-pixel.tsx +99 -99
- package/src/tracking/consent-init.tsx +62 -62
- package/src/tracking/events.ts +348 -348
- package/src/tracking/ga4.tsx +93 -93
- package/src/tracking/google-ads.ts +84 -84
- package/src/tracking/gtm.tsx +60 -60
- package/src/tracking/inline-script.ts +49 -49
- package/src/tracking/oaiq.ts +206 -206
- package/src/tracking/tiktok-pixel.tsx +91 -91
- package/src/tracking/track-init.tsx +56 -56
- package/src/tracking/track-order-purchase.tsx +122 -122
- package/src/tracking/ttq.ts +180 -180
- package/src/tracking/use-tracking-config.ts +54 -54
- package/theme/index.css +25 -25
|
@@ -1,62 +1,62 @@
|
|
|
1
|
-
import { consentInitSnippet } from "./consent"
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* ConsentInit — the synchronous Consent Mode v2 "default" snippet.
|
|
5
|
-
*
|
|
6
|
-
* Ported from the Cartbase reference implementation
|
|
7
|
-
* `src/components/storefront/consent/consent-init.tsx` (itself from
|
|
8
|
-
* `@1click/ui/src/tracking/consent-init.tsx` v2.3.1); the snippet lives in
|
|
9
|
-
* ./consent.ts (`consentInitSnippet`) so its ordering contract is
|
|
10
|
-
* unit-testable.
|
|
11
|
-
*
|
|
12
|
-
* Render it as the FIRST child of <body> (App Router layouts don't
|
|
13
|
-
* expose <head> for inline scripts). A plain inline <script>
|
|
14
|
-
* (deliberately NOT next/script) executes at HTML-parse time — long
|
|
15
|
-
* before the afterInteractive <GA4>/<MetaPixel> loaders, which run
|
|
16
|
-
* post-hydration. Google's consent-mode docs require the default to be
|
|
17
|
-
* set synchronously ahead of the tag; an async default races the
|
|
18
|
-
* loader and the first hit of a returning consented visitor would
|
|
19
|
-
* ship denied.
|
|
20
|
-
*
|
|
21
|
-
* `required` is the store's consent switch, `consent.enabled` from
|
|
22
|
-
* `GET /api/store/consent`, which the layout already fetches for the
|
|
23
|
-
* banner. It is REQUIRED on purpose: with it absent there is no safe
|
|
24
|
-
* default to fall back on. Defaulting to true would keep the pixels of a
|
|
25
|
-
* store that switched its banner off silent forever (the defect fixed on
|
|
26
|
-
* 2026-09-14); defaulting to false would fire them on an EU store whose
|
|
27
|
-
* layout forgot the prop. So the layout states it, and a layout that does
|
|
28
|
-
* not fails to compile.
|
|
29
|
-
*
|
|
30
|
-
* Behavior:
|
|
31
|
-
* - `required` and no stored choice (first visit) → default ALL DENIED.
|
|
32
|
-
* Tags still load (advanced consent mode): gtag sends cookieless
|
|
33
|
-
* pings, the Pixel queues client-side. The <ConsentBanner> then
|
|
34
|
-
* collects the choice and applies the live 'update'.
|
|
35
|
-
* - not `required` and no stored choice → default ALL GRANTED: the store
|
|
36
|
-
* collects no consent, so there is nothing to wait for.
|
|
37
|
-
* - Stored choice → default mirrors it, whatever the switch, so
|
|
38
|
-
* returning visitors are correct from the very first hit with no
|
|
39
|
-
* banner and no race, and a visitor who declined keeps that decision.
|
|
40
|
-
*
|
|
41
|
-
* `ads_data_redaction` strips ad-click identifiers (gclid et al.) from
|
|
42
|
-
* the cookieless pings while ad_storage is denied, per Google's docs.
|
|
43
|
-
*
|
|
44
|
-
* The script interpolates one boolean literal and the shared cookie name,
|
|
45
|
-
* nothing typed by a person — safe as a server-component inline script
|
|
46
|
-
* with a stable id. CARD TRAP: it must NEVER wait on the
|
|
47
|
-
* /api/store/consent fetch inside the browser; the layout resolves the
|
|
48
|
-
* setting on the server and inlines it here.
|
|
49
|
-
*/
|
|
50
|
-
export function ConsentInit({
|
|
51
|
-
required,
|
|
52
|
-
}: {
|
|
53
|
-
/** The store's consent switch: `consent.enabled` from `GET /api/store/consent`. */
|
|
54
|
-
required: boolean
|
|
55
|
-
}) {
|
|
56
|
-
return (
|
|
57
|
-
<script
|
|
58
|
-
id="1click-consent-init"
|
|
59
|
-
dangerouslySetInnerHTML={{ __html: consentInitSnippet(required) }}
|
|
60
|
-
/>
|
|
61
|
-
)
|
|
62
|
-
}
|
|
1
|
+
import { consentInitSnippet } from "./consent"
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* ConsentInit — the synchronous Consent Mode v2 "default" snippet.
|
|
5
|
+
*
|
|
6
|
+
* Ported from the Cartbase reference implementation
|
|
7
|
+
* `src/components/storefront/consent/consent-init.tsx` (itself from
|
|
8
|
+
* `@1click/ui/src/tracking/consent-init.tsx` v2.3.1); the snippet lives in
|
|
9
|
+
* ./consent.ts (`consentInitSnippet`) so its ordering contract is
|
|
10
|
+
* unit-testable.
|
|
11
|
+
*
|
|
12
|
+
* Render it as the FIRST child of <body> (App Router layouts don't
|
|
13
|
+
* expose <head> for inline scripts). A plain inline <script>
|
|
14
|
+
* (deliberately NOT next/script) executes at HTML-parse time — long
|
|
15
|
+
* before the afterInteractive <GA4>/<MetaPixel> loaders, which run
|
|
16
|
+
* post-hydration. Google's consent-mode docs require the default to be
|
|
17
|
+
* set synchronously ahead of the tag; an async default races the
|
|
18
|
+
* loader and the first hit of a returning consented visitor would
|
|
19
|
+
* ship denied.
|
|
20
|
+
*
|
|
21
|
+
* `required` is the store's consent switch, `consent.enabled` from
|
|
22
|
+
* `GET /api/store/consent`, which the layout already fetches for the
|
|
23
|
+
* banner. It is REQUIRED on purpose: with it absent there is no safe
|
|
24
|
+
* default to fall back on. Defaulting to true would keep the pixels of a
|
|
25
|
+
* store that switched its banner off silent forever (the defect fixed on
|
|
26
|
+
* 2026-09-14); defaulting to false would fire them on an EU store whose
|
|
27
|
+
* layout forgot the prop. So the layout states it, and a layout that does
|
|
28
|
+
* not fails to compile.
|
|
29
|
+
*
|
|
30
|
+
* Behavior:
|
|
31
|
+
* - `required` and no stored choice (first visit) → default ALL DENIED.
|
|
32
|
+
* Tags still load (advanced consent mode): gtag sends cookieless
|
|
33
|
+
* pings, the Pixel queues client-side. The <ConsentBanner> then
|
|
34
|
+
* collects the choice and applies the live 'update'.
|
|
35
|
+
* - not `required` and no stored choice → default ALL GRANTED: the store
|
|
36
|
+
* collects no consent, so there is nothing to wait for.
|
|
37
|
+
* - Stored choice → default mirrors it, whatever the switch, so
|
|
38
|
+
* returning visitors are correct from the very first hit with no
|
|
39
|
+
* banner and no race, and a visitor who declined keeps that decision.
|
|
40
|
+
*
|
|
41
|
+
* `ads_data_redaction` strips ad-click identifiers (gclid et al.) from
|
|
42
|
+
* the cookieless pings while ad_storage is denied, per Google's docs.
|
|
43
|
+
*
|
|
44
|
+
* The script interpolates one boolean literal and the shared cookie name,
|
|
45
|
+
* nothing typed by a person — safe as a server-component inline script
|
|
46
|
+
* with a stable id. CARD TRAP: it must NEVER wait on the
|
|
47
|
+
* /api/store/consent fetch inside the browser; the layout resolves the
|
|
48
|
+
* setting on the server and inlines it here.
|
|
49
|
+
*/
|
|
50
|
+
export function ConsentInit({
|
|
51
|
+
required,
|
|
52
|
+
}: {
|
|
53
|
+
/** The store's consent switch: `consent.enabled` from `GET /api/store/consent`. */
|
|
54
|
+
required: boolean
|
|
55
|
+
}) {
|
|
56
|
+
return (
|
|
57
|
+
<script
|
|
58
|
+
id="1click-consent-init"
|
|
59
|
+
dangerouslySetInnerHTML={{ __html: consentInitSnippet(required) }}
|
|
60
|
+
/>
|
|
61
|
+
)
|
|
62
|
+
}
|