fontdue-js 2.28.0 → 3.0.0-alpha10
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/.babelrc.cjs +72 -0
- package/README.md +639 -93
- package/dist/__generated__/AddToCartBannerQuery.graphql.js +1 -8
- package/dist/__generated__/AddToCartBanner_item.graphql.js +1 -8
- package/dist/__generated__/AddToCartBanner_order.graphql.js +1 -8
- package/dist/__generated__/AddressFieldsRefetchQuery.graphql.js +1 -8
- package/dist/__generated__/AddressFields_viewer.graphql.js +3 -11
- package/dist/__generated__/BuyButtonIDQuery.graphql.js +1 -8
- package/dist/__generated__/BuyButtonSlugQuery.graphql.js +1 -8
- package/dist/__generated__/BuyButton_collection.graphql.js +1 -8
- package/dist/__generated__/CartButtonQuery.graphql.js +1 -8
- package/dist/__generated__/CartButton_order.graphql.js +1 -8
- package/dist/__generated__/CartItemAdditionalLicenses_licenses.graphql.js +1 -8
- package/dist/__generated__/CartItemAdditionalLicenses_orderItem.graphql.js +1 -8
- package/dist/__generated__/CartItemLicense_selection.graphql.js +1 -8
- package/dist/__generated__/CartItemProduct_product.graphql.js +1 -8
- package/dist/__generated__/CartItemVariable_selection.graphql.js +1 -8
- package/dist/__generated__/CartItemVariable_variable.graphql.js +1 -8
- package/dist/__generated__/CartItem_node.graphql.js +1 -8
- package/dist/__generated__/CartOrderCompleteOrderMutation.graphql.js +1 -8
- package/dist/__generated__/CartOrderRemoveDiscountMutation.graphql.js +1 -8
- package/dist/__generated__/CartOrderUpdateMutation.graphql.js +1 -8
- package/dist/__generated__/CartOrder_UpdateErrors.graphql.js +1 -8
- package/dist/__generated__/CartOrder_order.graphql.js +1 -8
- package/dist/__generated__/CartOrder_viewer.graphql.js +1 -8
- package/dist/__generated__/CartQuery.graphql.js +1 -8
- package/dist/__generated__/CartStateRemoveDiscountMutation.graphql.js +1 -8
- package/dist/__generated__/CartStateUpdateMutation.graphql.js +1 -8
- package/dist/__generated__/CartState_order.graphql.js +1 -8
- package/dist/__generated__/CartTotals_order.graphql.js +1 -8
- package/dist/__generated__/CharacterViewerIDQuery.graphql.js +1 -8
- package/dist/__generated__/CharacterViewerSlugQuery.graphql.js +1 -8
- package/dist/__generated__/CharacterViewerStyleRefetchQuery.graphql.js +1 -8
- package/dist/__generated__/CharacterViewer_collection.graphql.js +1 -8
- package/dist/__generated__/CharacterViewer_family.graphql.js +1 -8
- package/dist/__generated__/CharacterViewer_style.graphql.js +3 -11
- package/dist/__generated__/CheckoutUpdateCustomerMutation.graphql.js +1 -8
- package/dist/__generated__/CheckoutUpdateOrderMutation.graphql.js +1 -8
- package/dist/__generated__/Checkout_UpdateOrderErrors.graphql.js +1 -8
- package/dist/__generated__/Checkout_identity.graphql.js +1 -8
- package/dist/__generated__/Checkout_order.graphql.js +1 -8
- package/dist/__generated__/Checkout_viewer.graphql.js +1 -8
- package/dist/__generated__/CollectionAa_Query.graphql.js +1 -8
- package/dist/__generated__/CollectionAa_product.graphql.js +1 -8
- package/dist/__generated__/CouponCodeInputApplyCouponMutation.graphql.js +1 -8
- package/dist/__generated__/CouponText_coupon.graphql.js +1 -8
- package/dist/__generated__/CustomerLoginFormLoginMutation.graphql.js +1 -8
- package/dist/__generated__/CustomerLoginFormQuery.graphql.js +1 -8
- package/dist/__generated__/DownloadRefetchQuery.graphql.js +1 -8
- package/dist/__generated__/Download_order.graphql.js +1 -8
- package/dist/__generated__/FamilyList_node.graphql.js +1 -8
- package/dist/__generated__/Family_node.graphql.js +1 -8
- package/dist/__generated__/FontFamiliesQuery.graphql.js +1 -8
- package/dist/__generated__/FontStyle_fontStyle.graphql.js +1 -8
- package/dist/__generated__/FontdueAdminToolbarStaffQuery.graphql.d.ts +20 -0
- package/dist/__generated__/{TestModeBannerQuery.graphql.js → FontdueAdminToolbarStaffQuery.graphql.js} +11 -18
- package/dist/__generated__/FontdueAdminToolbarTokenMutation.graphql.d.ts +18 -0
- package/dist/__generated__/FontdueAdminToolbarTokenMutation.graphql.js +56 -0
- package/dist/__generated__/FontdueProviderQuery.graphql.d.ts +19 -0
- package/dist/__generated__/FontdueProviderQuery.graphql.js +140 -0
- package/dist/__generated__/IdentityBox_identity.graphql.js +1 -8
- package/dist/__generated__/License_node.graphql.js +1 -8
- package/dist/__generated__/NewsletterSignupQuery.graphql.js +1 -8
- package/dist/__generated__/NewsletterSignupUpdateCustomerMutation.graphql.js +1 -8
- package/dist/__generated__/NodePasswordFormAccessNodeMutation.graphql.js +1 -8
- package/dist/__generated__/NodePasswordFormIDQuery.graphql.js +1 -8
- package/dist/__generated__/NodePasswordFormSlugQuery.graphql.js +1 -8
- package/dist/__generated__/OrderVariableSelectionReduxRefetchQuery.graphql.js +1 -8
- package/dist/__generated__/OrderVariableSelectionRedux_viewer.graphql.js +3 -11
- package/dist/__generated__/OrderVariableSelection_variables.graphql.js +1 -8
- package/dist/__generated__/PrecartAddToCartMutation.graphql.js +1 -8
- package/dist/__generated__/PrecartClearCartMutation.graphql.js +1 -8
- package/dist/__generated__/PrecartQuery.graphql.js +1 -8
- package/dist/__generated__/Precart_collection.graphql.js +1 -8
- package/dist/__generated__/Precart_license.graphql.js +1 -8
- package/dist/__generated__/Precart_viewer.graphql.js +1 -8
- package/dist/__generated__/PriceBarSectionRefetchQuery.graphql.js +1 -8
- package/dist/__generated__/PriceBarSection_node.graphql.js +3 -11
- package/dist/__generated__/PriceBar_node.graphql.js +1 -8
- package/dist/__generated__/Price_price.graphql.js +1 -8
- package/dist/__generated__/SKUPrice_sku.graphql.js +1 -8
- package/dist/__generated__/SelectButton_sku.graphql.js +1 -8
- package/dist/__generated__/ServerConfigProvider_viewer.graphql.d.ts +23 -0
- package/dist/__generated__/ServerConfigProvider_viewer.graphql.js +57 -0
- package/dist/__generated__/ShareCartCreateSnapshotMutation.graphql.js +1 -8
- package/dist/__generated__/SpecimenLinkQuery.graphql.js +1 -8
- package/dist/__generated__/StoreModalBundleButton_bundle.graphql.js +1 -8
- package/dist/__generated__/StoreModalCartQuery.graphql.js +1 -8
- package/dist/__generated__/StoreModalCheckoutQuery.graphql.js +1 -8
- package/dist/__generated__/StoreModalContainerQuery.graphql.js +1 -8
- package/dist/__generated__/StoreModalDownloadRefetchQuery.graphql.js +1 -8
- package/dist/__generated__/StoreModalDownload_order.graphql.js +1 -8
- package/dist/__generated__/StoreModalFamilyButton_collection.graphql.js +1 -8
- package/dist/__generated__/StoreModalFamily_collection.graphql.js +1 -8
- package/dist/__generated__/StoreModalIndexItem_fontCollection.graphql.js +1 -8
- package/dist/__generated__/StoreModalIndexQuery.graphql.js +1 -8
- package/dist/__generated__/StoreModalOrderVariableSelection_order.graphql.js +1 -8
- package/dist/__generated__/StoreModalOrderVariableSelection_viewer.graphql.js +1 -8
- package/dist/__generated__/StoreModalProductContent_collection.graphql.js +3 -11
- package/dist/__generated__/StoreModalProductLicenseSelection_collection.graphql.js +1 -8
- package/dist/__generated__/StoreModalProductLicense_license.graphql.js +1 -8
- package/dist/__generated__/StoreModalProductQuery.graphql.js +1 -8
- package/dist/__generated__/StoreModalProductRefetchQuery.graphql.js +1 -8
- package/dist/__generated__/StoreModalProductSummaryAddToCartMutation.graphql.js +1 -8
- package/dist/__generated__/StoreModalProductSummaryClearCartMutation.graphql.js +1 -8
- package/dist/__generated__/StoreModalProductSummaryRefetchQuery.graphql.js +1 -8
- package/dist/__generated__/StoreModalProductSummary_viewer.graphql.js +3 -11
- package/dist/__generated__/StoreModalReviewIdentity_identity.graphql.js +1 -8
- package/dist/__generated__/StoreModalStyleButton_fontStyle.graphql.js +1 -8
- package/dist/__generated__/StoreModalUnifiedCheckoutCompleteOrderMutation.graphql.js +1 -8
- package/dist/__generated__/StoreModalUnifiedCheckoutUpdateCustomerMutation.graphql.js +1 -8
- package/dist/__generated__/StoreModalUnifiedCheckoutUpdateOrderMutation.graphql.js +1 -8
- package/dist/__generated__/StoreModalUnifiedCheckout_order.graphql.js +1 -8
- package/dist/__generated__/StoreModalUnifiedCheckout_viewer.graphql.js +1 -8
- package/dist/__generated__/StripeProviderCreateCheckoutSessionMutation.graphql.js +1 -8
- package/dist/__generated__/StripeProvider_viewer.graphql.js +1 -8
- package/dist/__generated__/TestFontsFormUpdateCustomerMutation.graphql.js +1 -8
- package/dist/__generated__/TestFontsForm_Query.graphql.js +1 -8
- package/dist/__generated__/TestModeBanner_viewer.graphql.d.ts +19 -0
- package/dist/__generated__/TestModeBanner_viewer.graphql.js +36 -0
- package/dist/__generated__/ThemeConfig_viewer.graphql.d.ts +19 -0
- package/dist/__generated__/ThemeConfig_viewer.graphql.js +36 -0
- package/dist/__generated__/TypeTesterFamiliesQuery.graphql.js +1 -8
- package/dist/__generated__/TypeTesterFamiliesStylesQuery.graphql.js +1 -8
- package/dist/__generated__/TypeTesterFeaturesButton_fontStyle.graphql.js +1 -8
- package/dist/__generated__/TypeTesterFeatures_fontStyle.graphql.js +1 -8
- package/dist/__generated__/TypeTesterFloatingToolbar_testers.graphql.js +1 -8
- package/dist/__generated__/TypeTesterStandaloneChangedStylesQuery.graphql.js +1 -8
- package/dist/__generated__/TypeTesterStandaloneQuery.graphql.js +1 -8
- package/dist/__generated__/TypeTesterStyleSelectData_fontStyle.graphql.js +1 -8
- package/dist/__generated__/TypeTesterStyleSelectData_fontStyleData.graphql.js +1 -8
- package/dist/__generated__/TypeTesterToolbar_fontStyle.graphql.js +1 -8
- package/dist/__generated__/TypeTesterVariableAxes_fontStyle.graphql.js +1 -8
- package/dist/__generated__/TypeTester_fontStyle.graphql.js +1 -8
- package/dist/__generated__/TypeTestersChangedStylesQuery.graphql.js +1 -8
- package/dist/__generated__/TypeTestersIDQuery.graphql.js +1 -8
- package/dist/__generated__/TypeTestersRefetchQuery.graphql.js +1 -8
- package/dist/__generated__/TypeTestersSlugQuery.graphql.js +1 -8
- package/dist/__generated__/TypeTesters_collection.graphql.js +3 -11
- package/dist/__generated__/VariableTableAmounts_option.graphql.js +1 -8
- package/dist/__generated__/VariableTableAmounts_variable.graphql.js +1 -8
- package/dist/__generated__/orderTrackingUpdateOrderTrackingMutation.graphql.js +1 -8
- package/dist/__generated__/productState_Query.graphql.js +1 -8
- package/dist/__generated__/productState_bundle.graphql.js +1 -8
- package/dist/__generated__/productState_collection.graphql.js +1 -8
- package/dist/__generated__/productState_collectionBundle.graphql.js +1 -8
- package/dist/__generated__/productState_node.graphql.js +1 -8
- package/dist/__generated__/productState_sku.graphql.js +1 -8
- package/dist/__generated__/useFeaturesData_fontStyle.graphql.js +1 -8
- package/dist/__generated__/useFontStyle_fontStyle.graphql.js +1 -8
- package/dist/__generated__/useTotalStyles_fontCollection.graphql.js +1 -8
- package/dist/__tests__/collectionBundleSelection.test.js +221 -222
- package/dist/__tests__/fontLoader.test.js +24 -26
- package/dist/__tests__/licenseExclusions.test.js +27 -30
- package/dist/__tests__/networkFetch.test.js +66 -0
- package/dist/__tests__/nextAdapter.test.js +447 -0
- package/dist/components/AddToCartBanner/index.js +19 -29
- package/dist/components/BuyButton/index.d.ts +29 -6
- package/dist/components/BuyButton/index.js +98 -57
- package/dist/components/BuyButton/index.server.d.ts +9 -2
- package/dist/components/BuyButton/index.server.js +20 -17
- package/dist/components/BuyingOptions/index.d.ts +9 -0
- package/dist/components/BuyingOptions/index.js +4 -12
- package/dist/components/Cart/AddressFields.d.ts +2 -2
- package/dist/components/Cart/AddressFields.js +25 -35
- package/dist/components/Cart/CartItem/CartItemAdditionalLicenses.d.ts +2 -2
- package/dist/components/Cart/CartItem/CartItemAdditionalLicenses.js +9 -16
- package/dist/components/Cart/CartItem/CartItemLicense.d.ts +2 -2
- package/dist/components/Cart/CartItem/CartItemLicense.js +15 -24
- package/dist/components/Cart/CartItem/CartItemProduct.d.ts +1 -1
- package/dist/components/Cart/CartItem/CartItemProduct.js +16 -23
- package/dist/components/Cart/CartItem/CartItemVariable.d.ts +3 -3
- package/dist/components/Cart/CartItem/CartItemVariable.js +16 -23
- package/dist/components/Cart/CartItem/VariableTextInput.js +13 -21
- package/dist/components/Cart/CartItem/index.d.ts +2 -2
- package/dist/components/Cart/CartItem/index.js +18 -27
- package/dist/components/Cart/CartOrder.d.ts +2 -2
- package/dist/components/Cart/CartOrder.js +102 -113
- package/dist/components/Cart/CartState.d.ts +3 -3
- package/dist/components/Cart/CartState.js +18 -25
- package/dist/components/Cart/CartTotals.d.ts +1 -1
- package/dist/components/Cart/CartTotals.js +31 -38
- package/dist/components/Cart/Checkout.d.ts +3 -3
- package/dist/components/Cart/Checkout.js +109 -118
- package/dist/components/Cart/CheckoutSteps.js +1 -8
- package/dist/components/Cart/CouponCodeInput.js +22 -32
- package/dist/components/Cart/CustomerFields.d.ts +1 -1
- package/dist/components/Cart/CustomerFields.js +21 -31
- package/dist/components/Cart/Download.d.ts +1 -1
- package/dist/components/Cart/Download.js +17 -27
- package/dist/components/Cart/EmptyCart.js +15 -23
- package/dist/components/Cart/IdentityBox.d.ts +1 -1
- package/dist/components/Cart/IdentityBox.js +12 -19
- package/dist/components/Cart/ShareCart.js +24 -32
- package/dist/components/Cart/index.js +13 -21
- package/dist/components/Cart/injectRelayEnvironment.js +5 -13
- package/dist/components/Cart/orderTracking.js +8 -15
- package/dist/components/Cart/types.d.ts +1 -1
- package/dist/components/Cart/types.js +1 -5
- package/dist/components/Cart/utils.js +2 -9
- package/dist/components/CartButton/index.d.ts +5 -8
- package/dist/components/CartButton/index.js +53 -62
- package/dist/components/CharacterViewer/StyleSelect.d.ts +1 -1
- package/dist/components/CharacterViewer/StyleSelect.js +10 -17
- package/dist/components/CharacterViewer/index.d.ts +29 -6
- package/dist/components/CharacterViewer/index.js +150 -102
- package/dist/components/CharacterViewer/index.server.d.ts +9 -2
- package/dist/components/CharacterViewer/index.server.js +21 -17
- package/dist/components/Checkbox/index.js +9 -19
- package/dist/components/CollectionAa/index.d.ts +1 -1
- package/dist/components/CollectionAa/index.js +12 -21
- package/dist/components/ComponentsContext.d.ts +1 -1
- package/dist/components/ComponentsContext.js +4 -10
- package/dist/components/ConfigContext.d.ts +13 -12
- package/dist/components/ConfigContext.js +29 -11
- package/dist/components/ConsentBanner/consent.js +6 -17
- package/dist/components/ConsentBanner/index.js +19 -29
- package/dist/components/CookieNotification/index.d.ts +13 -0
- package/dist/components/CookieNotification/index.js +23 -31
- package/dist/components/CorsErrorModal.js +13 -20
- package/dist/components/CouponText/index.d.ts +1 -1
- package/dist/components/CouponText/index.js +9 -18
- package/dist/components/CustomerLoginForm/index.js +37 -38
- package/dist/components/Family/FamilyList.d.ts +1 -1
- package/dist/components/Family/FamilyList.js +10 -17
- package/dist/components/Family/index.d.ts +1 -1
- package/dist/components/Family/index.js +37 -46
- package/dist/components/FontFamilies/index.js +18 -28
- package/dist/components/FontStyle/index.d.ts +2 -2
- package/dist/components/FontStyle/index.js +8 -15
- package/dist/components/FontdueAdminToolbar/index.d.ts +2 -0
- package/dist/components/FontdueAdminToolbar/index.js +146 -0
- package/dist/components/FontdueContextProvider/index.d.ts +18 -0
- package/dist/components/FontdueContextProvider/index.js +148 -0
- package/dist/components/FontdueProvider/index.d.ts +19 -3
- package/dist/components/FontdueProvider/index.js +75 -13
- package/dist/components/FontdueProvider/index.server.d.ts +6 -3
- package/dist/components/FontdueProvider/index.server.js +37 -21
- package/dist/components/Icons/Align.js +13 -22
- package/dist/components/Icons/ArrowDownRight.js +5 -13
- package/dist/components/Icons/ArrowLeft.js +5 -13
- package/dist/components/Icons/ArrowRight.js +5 -13
- package/dist/components/Icons/CarrotDown.js +5 -13
- package/dist/components/Icons/CarrotUp.js +5 -13
- package/dist/components/Icons/Cart.js +7 -15
- package/dist/components/Icons/CartNew.js +7 -15
- package/dist/components/Icons/Check.js +5 -13
- package/dist/components/Icons/Checkbox.js +5 -13
- package/dist/components/Icons/CheckboxChecked.js +5 -13
- package/dist/components/Icons/CheckboxCrossed.js +6 -14
- package/dist/components/Icons/CircledCheck.js +6 -14
- package/dist/components/Icons/CircledInfo.js +6 -14
- package/dist/components/Icons/CircledMinus.js +6 -14
- package/dist/components/Icons/ColorPicker.js +5 -13
- package/dist/components/Icons/CreditCard.js +6 -14
- package/dist/components/Icons/DownArrow.js +5 -13
- package/dist/components/Icons/DownloadFonts.js +8 -16
- package/dist/components/Icons/FrowningFace.js +8 -16
- package/dist/components/Icons/License.js +5 -13
- package/dist/components/Icons/Receipt.js +8 -16
- package/dist/components/Icons/User.js +5 -13
- package/dist/components/Icons/X.js +5 -13
- package/dist/components/Icons/index.d.ts +23 -23
- package/dist/components/Icons/index.js +23 -167
- package/dist/components/NewsletterSignup/NewsletterSignupElement.d.ts +1 -1
- package/dist/components/NewsletterSignup/NewsletterSignupElement.js +4 -11
- package/dist/components/NewsletterSignup/index.d.ts +11 -6
- package/dist/components/NewsletterSignup/index.js +75 -60
- package/dist/components/NewsletterSignup/index.server.d.ts +7 -2
- package/dist/components/NewsletterSignup/index.server.js +17 -14
- package/dist/components/NodePasswordForm/index.js +25 -33
- package/dist/components/OrderVariableSelection/OrderVariableSelectionRedux.d.ts +1 -1
- package/dist/components/OrderVariableSelection/OrderVariableSelectionRedux.js +18 -27
- package/dist/components/OrderVariableSelection/index.d.ts +1 -1
- package/dist/components/OrderVariableSelection/index.js +28 -36
- package/dist/components/Precart/License.d.ts +1 -1
- package/dist/components/Precart/License.js +22 -30
- package/dist/components/Precart/index.js +64 -74
- package/dist/components/Price/index.d.ts +1 -1
- package/dist/components/Price/index.js +10 -20
- package/dist/components/PriceBar/PriceBarSection.d.ts +1 -1
- package/dist/components/PriceBar/PriceBarSection.js +23 -33
- package/dist/components/PriceBar/index.d.ts +1 -1
- package/dist/components/PriceBar/index.js +13 -23
- package/dist/components/Root/index.d.ts +1 -1
- package/dist/components/Root/index.js +41 -51
- package/dist/components/Root/productState.d.ts +1 -1
- package/dist/components/Root/productState.js +20 -29
- package/dist/components/SKUPrice/index.d.ts +2 -2
- package/dist/components/SKUPrice/index.js +12 -20
- package/dist/components/Select/index.js +9 -17
- package/dist/components/SelectButton/index.d.ts +2 -2
- package/dist/components/SelectButton/index.js +20 -29
- package/dist/components/ServerConfigProvider/index.d.ts +4 -2
- package/dist/components/ServerConfigProvider/index.js +12 -20
- package/dist/components/SpecimenLink/index.js +12 -20
- package/dist/components/StickyNav/index.js +16 -26
- package/dist/components/StoreModal/StoreModalBundleButton.d.ts +1 -1
- package/dist/components/StoreModal/StoreModalBundleButton.js +16 -23
- package/dist/components/StoreModal/StoreModalCart.d.ts +1 -1
- package/dist/components/StoreModal/StoreModalCart.js +29 -38
- package/dist/components/StoreModal/StoreModalCheckout.js +9 -17
- package/dist/components/StoreModal/StoreModalCheckoutContext.d.ts +1 -1
- package/dist/components/StoreModal/StoreModalCheckoutContext.js +6 -12
- package/dist/components/StoreModal/StoreModalContainer.js +25 -35
- package/dist/components/StoreModal/StoreModalDownload.d.ts +1 -1
- package/dist/components/StoreModal/StoreModalDownload.js +14 -24
- package/dist/components/StoreModal/StoreModalFamily.d.ts +1 -1
- package/dist/components/StoreModal/StoreModalFamily.js +14 -23
- package/dist/components/StoreModal/StoreModalFamilyButton.d.ts +1 -1
- package/dist/components/StoreModal/StoreModalFamilyButton.js +23 -30
- package/dist/components/StoreModal/StoreModalIndex.d.ts +1 -1
- package/dist/components/StoreModal/StoreModalIndex.js +9 -17
- package/dist/components/StoreModal/StoreModalIndexItem.d.ts +1 -1
- package/dist/components/StoreModal/StoreModalIndexItem.js +20 -30
- package/dist/components/StoreModal/StoreModalLicenseeIsBillingSelection.js +8 -17
- package/dist/components/StoreModal/StoreModalLoader.js +6 -15
- package/dist/components/StoreModal/StoreModalOrderVariableSelection.d.ts +3 -3
- package/dist/components/StoreModal/StoreModalOrderVariableSelection.js +12 -21
- package/dist/components/StoreModal/StoreModalProduct.d.ts +1 -1
- package/dist/components/StoreModal/StoreModalProduct.js +55 -65
- package/dist/components/StoreModal/StoreModalReviewIdentity.d.ts +1 -1
- package/dist/components/StoreModal/StoreModalReviewIdentity.js +6 -15
- package/dist/components/StoreModal/StoreModalRouter.js +12 -22
- package/dist/components/StoreModal/StoreModalStyleButton.d.ts +1 -1
- package/dist/components/StoreModal/StoreModalStyleButton.js +20 -27
- package/dist/components/StoreModal/index.d.ts +5 -1
- package/dist/components/StoreModal/index.js +24 -20
- package/dist/components/StoreModal/routes.d.ts +4 -4
- package/dist/components/StoreModal/routes.js +18 -26
- package/dist/components/StoreModal/types.js +1 -5
- package/dist/components/StoreModalProductLicenseSelection/LicenseElement.js +12 -22
- package/dist/components/StoreModalProductLicenseSelection/LicenseVariableElement.js +7 -15
- package/dist/components/StoreModalProductLicenseSelection/LicenseVariableRadioElement.js +9 -19
- package/dist/components/StoreModalProductLicenseSelection/StoreModalProductLicense.d.ts +1 -1
- package/dist/components/StoreModalProductLicenseSelection/StoreModalProductLicense.js +19 -28
- package/dist/components/StoreModalProductLicenseSelection/index.d.ts +1 -1
- package/dist/components/StoreModalProductLicenseSelection/index.js +10 -17
- package/dist/components/StoreModalProductSummary/index.d.ts +1 -1
- package/dist/components/StoreModalProductSummary/index.js +45 -55
- package/dist/components/StripeLogo.js +4 -11
- package/dist/components/StripeProvider/index.d.ts +1 -1
- package/dist/components/StripeProvider/index.js +19 -29
- package/dist/components/Switch/index.js +1 -7
- package/dist/components/TestFontsForm/TestFontsFormElement.js +4 -12
- package/dist/components/TestFontsForm/index.d.ts +11 -4
- package/dist/components/TestFontsForm/index.js +80 -65
- package/dist/components/TestFontsForm/index.server.d.ts +7 -2
- package/dist/components/TestFontsForm/index.server.js +17 -14
- package/dist/components/TestModeBanner/index.d.ts +4 -1
- package/dist/components/TestModeBanner/index.js +13 -27
- package/dist/components/TextField/index.js +9 -17
- package/dist/components/ThemeConfig/index.d.ts +3 -5
- package/dist/components/ThemeConfig/index.js +12 -36
- package/dist/components/Tracking/index.js +11 -18
- package/dist/components/TypeTester/TypeTesterAlignButtons.d.ts +1 -1
- package/dist/components/TypeTester/TypeTesterAlignButtons.js +8 -16
- package/dist/components/TypeTester/TypeTesterBullet.d.ts +1 -1
- package/dist/components/TypeTester/TypeTesterBullet.js +4 -12
- package/dist/components/TypeTester/TypeTesterContent.d.ts +2 -2
- package/dist/components/TypeTester/TypeTesterContent.js +22 -21
- package/dist/components/TypeTester/TypeTesterContext.d.ts +2 -2
- package/dist/components/TypeTester/TypeTesterContext.js +10 -17
- package/dist/components/TypeTester/TypeTesterEditAll.js +10 -20
- package/dist/components/TypeTester/TypeTesterFamilies.d.ts +1 -1
- package/dist/components/TypeTester/TypeTesterFamilies.js +26 -37
- package/dist/components/TypeTester/TypeTesterFeatures.d.ts +1 -1
- package/dist/components/TypeTester/TypeTesterFeatures.js +28 -37
- package/dist/components/TypeTester/TypeTesterFeaturesButton.d.ts +1 -1
- package/dist/components/TypeTester/TypeTesterFeaturesButton.js +20 -30
- package/dist/components/TypeTester/TypeTesterFitter.d.ts +1 -1
- package/dist/components/TypeTester/TypeTesterFitter.js +5 -13
- package/dist/components/TypeTester/TypeTesterFloatingToolbar.d.ts +1 -1
- package/dist/components/TypeTester/TypeTesterFloatingToolbar.js +19 -28
- package/dist/components/TypeTester/TypeTesterInput.js +12 -22
- package/dist/components/TypeTester/TypeTesterSlider.js +7 -16
- package/dist/components/TypeTester/TypeTesterStandalone.d.ts +20 -6
- package/dist/components/TypeTester/TypeTesterStandalone.js +49 -39
- package/dist/components/TypeTester/TypeTesterStandalone.server.d.ts +6 -2
- package/dist/components/TypeTester/TypeTesterStandalone.server.js +20 -16
- package/dist/components/TypeTester/TypeTesterStandaloneElement.js +7 -16
- package/dist/components/TypeTester/TypeTesterState.d.ts +2 -2
- package/dist/components/TypeTester/TypeTesterState.js +6 -14
- package/dist/components/TypeTester/TypeTesterStyleSelect.d.ts +1 -1
- package/dist/components/TypeTester/TypeTesterStyleSelect.js +9 -17
- package/dist/components/TypeTester/TypeTesterStyleSelectData.d.ts +3 -3
- package/dist/components/TypeTester/TypeTesterStyleSelectData.js +31 -40
- package/dist/components/TypeTester/TypeTesterToolbar.d.ts +2 -2
- package/dist/components/TypeTester/TypeTesterToolbar.js +29 -39
- package/dist/components/TypeTester/TypeTesterVariableAxes.d.ts +1 -1
- package/dist/components/TypeTester/TypeTesterVariableAxes.js +16 -24
- package/dist/components/TypeTester/features.js +1 -8
- package/dist/components/TypeTester/index.d.ts +2 -2
- package/dist/components/TypeTester/index.js +45 -55
- package/dist/components/TypeTester/types.js +3 -11
- package/dist/components/TypeTester/useFeaturesData.d.ts +1 -1
- package/dist/components/TypeTester/useFeaturesData.js +7 -15
- package/dist/components/TypeTester/useTypeTesterStyler.d.ts +3 -3
- package/dist/components/TypeTester/useTypeTesterStyler.js +6 -13
- package/dist/components/TypeTesters/TypeTestersElement.js +4 -12
- package/dist/components/TypeTesters/index.d.ts +22 -5
- package/dist/components/TypeTesters/index.js +118 -71
- package/dist/components/TypeTesters/index.server.d.ts +7 -2
- package/dist/components/TypeTesters/index.server.js +20 -17
- package/dist/components/UrlContext.js +6 -12
- package/dist/components/VariableTableAmounts/index.d.ts +2 -2
- package/dist/components/VariableTableAmounts/index.js +9 -16
- package/dist/components/elements/Button/index.js +3 -11
- package/dist/components/elements/EmptyCart/index.js +10 -20
- package/dist/components/elements/StoreModalCartLayout/index.js +10 -18
- package/dist/components/elements/StoreModalContainer/StoreModalContainerContext.js +3 -9
- package/dist/components/elements/StoreModalContainer/index.js +17 -27
- package/dist/components/elements/StoreModalDownloadLayout/index.js +7 -15
- package/dist/components/elements/StoreModalFamily/index.js +8 -16
- package/dist/components/elements/StoreModalFamilyButton/index.d.ts +1 -1
- package/dist/components/elements/StoreModalFamilyButton/index.js +11 -20
- package/dist/components/elements/StoreModalIndexItem/index.js +9 -17
- package/dist/components/elements/StoreModalLicenseeIsBillingIdentityElement.js +20 -29
- package/dist/components/elements/StoreModalLoadingScreen/index.js +4 -12
- package/dist/components/elements/StoreModalPageContainer/index.js +5 -13
- package/dist/components/elements/StoreModalStyleButton/index.d.ts +1 -1
- package/dist/components/elements/StoreModalStyleButton/index.js +10 -18
- package/dist/components/elements/StoreModalUnifiedCheckout.d.ts +2 -2
- package/dist/components/elements/StoreModalUnifiedCheckout.js +114 -122
- package/dist/components/useConsent.js +4 -9
- package/dist/components/useFont.d.ts +1 -1
- package/dist/components/useFont.js +8 -15
- package/dist/components/useFontStyle.d.ts +1 -1
- package/dist/components/useFontStyle.js +12 -20
- package/dist/components/useInterval.js +5 -12
- package/dist/components/useTotalStyles.d.ts +1 -1
- package/dist/components/useTotalStyles.js +4 -12
- package/dist/corsError.js +4 -14
- package/dist/data/unicodeData.js +1 -1
- package/dist/fontLoader.js +3 -11
- package/dist/fontdue.css +127 -12
- package/dist/global-shim.d.ts +1 -0
- package/dist/global-shim.js +8 -0
- package/dist/hooks/useAutofit.js +11 -19
- package/dist/hooks/useLicenseAndOrderVariables.d.ts +2 -2
- package/dist/hooks/useLicenseAndOrderVariables.js +7 -12
- package/dist/hooks/useRefetchOnLicenseChanges.d.ts +1 -1
- package/dist/hooks/useRefetchOnLicenseChanges.js +7 -13
- package/dist/hooks/useResizeObserver.d.ts +11 -0
- package/dist/hooks/useResizeObserver.js +23 -0
- package/dist/hooks.js +9 -16
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/loadFontdueProviderQuery.d.ts +3 -0
- package/dist/loadFontdueProviderQuery.js +10 -0
- package/dist/next/config.d.ts +41 -0
- package/dist/next/config.js +193 -0
- package/dist/next/image-loader.d.ts +7 -0
- package/dist/next/image-loader.js +39 -0
- package/dist/next/index.d.ts +2 -0
- package/dist/next/index.js +10 -0
- package/dist/next/revalidate.d.ts +1 -0
- package/dist/next/revalidate.js +37 -0
- package/dist/next/tenant.d.ts +26 -0
- package/dist/next/tenant.js +169 -0
- package/dist/react-ranger.d.js +0 -1
- package/dist/react-ranger.js +17 -24
- package/dist/reducer.d.ts +5 -5
- package/dist/reducer.js +15 -36
- package/dist/relay/environment.d.ts +1 -0
- package/dist/relay/environment.js +74 -34
- package/dist/relay/loadSerializableQuery.d.ts +3 -1
- package/dist/relay/loadSerializableQuery.js +4 -8
- package/dist/relay/serverConfig.d.ts +16 -0
- package/dist/relay/serverConfig.js +38 -0
- package/dist/relay/useSerializablePreloadedQuery.d.ts +3 -3
- package/dist/relay/useSerializablePreloadedQuery.js +26 -22
- package/dist/retryImport.js +1 -7
- package/dist/scripts/updateUnicodeData.js +0 -2
- package/dist/utils.d.ts +2 -2
- package/dist/utils.js +14 -36
- package/dist/vanilla/FontStyle.js +3 -11
- package/dist/vanilla/TruncatedMarkdown.js +2 -9
- package/dist/vite.d.ts +2 -0
- package/dist/vite.js +141 -0
- package/package.json +13 -9
- package/scripts/addJsExtensionsBabelPlugin.cjs +62 -0
- package/types/globals.d.ts +3 -0
- package/types/next-cache.d.ts +6 -0
- package/types/next-navigation.d.ts +6 -0
- package/vitest.config.ts +4 -0
- package/dist/__generated__/ServerConfigProviderQuery.graphql.d.ts +0 -24
- package/dist/__generated__/ServerConfigProviderQuery.graphql.js +0 -108
- package/dist/__generated__/TestModeBannerQuery.graphql.d.ts +0 -20
- package/dist/__generated__/ThemeConfigQuery.graphql.d.ts +0 -20
- package/dist/__generated__/ThemeConfigQuery.graphql.js +0 -87
- package/dist/components/CartButton/index.server.d.ts +0 -3
- package/dist/components/CartButton/index.server.js +0 -18
- package/dist/components/FontdueProvider/FontdueProviderClientComponent.d.ts +0 -14
- package/dist/components/FontdueProvider/FontdueProviderClientComponent.js +0 -61
- package/dist/components/ThemeConfig/index.server.d.ts +0 -2
- package/dist/components/ThemeConfig/index.server.js +0 -17
- package/fontdue.css +0 -2733
- package/fontdue.css.map +0 -1
package/README.md
CHANGED
|
@@ -1,62 +1,83 @@
|
|
|
1
1
|
# fontdue-js
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
React components for [Fontdue](https://fontdue.com) sites. Framework-agnostic: works in Next.js, Astro, React Router 7, TanStack Start, Vike, Remix, and any other React SSR or client-only environment.
|
|
4
4
|
|
|
5
5
|
## Requirements
|
|
6
6
|
|
|
7
|
-
- `react`
|
|
8
|
-
- `node` >=
|
|
9
|
-
|
|
10
|
-
If using TypeScript, update to >= 4.7 and change your `tsconfig.json` moduleResolution setting to `node16`:
|
|
11
|
-
|
|
12
|
-
``` json
|
|
7
|
+
- `react` 18 or 19
|
|
8
|
+
- `node` >= 18
|
|
9
|
+
- TypeScript (if used) with `moduleResolution` set to `node16`, `nodenext`, or `bundler` so the package's `exports` map resolves:
|
|
13
10
|
|
|
11
|
+
```json
|
|
14
12
|
{
|
|
15
13
|
"compilerOptions": {
|
|
16
|
-
"moduleResolution": "
|
|
14
|
+
"moduleResolution": "nodenext"
|
|
17
15
|
}
|
|
18
16
|
}
|
|
19
|
-
|
|
20
17
|
```
|
|
21
18
|
|
|
19
|
+
`fontdue-js` is published ESM-only.
|
|
20
|
+
|
|
22
21
|
## Installation
|
|
23
22
|
|
|
24
|
-
```
|
|
23
|
+
```shell
|
|
25
24
|
npm install fontdue-js@latest
|
|
26
25
|
```
|
|
27
26
|
|
|
28
|
-
##
|
|
27
|
+
## Configuration
|
|
28
|
+
|
|
29
|
+
Point fontdue-js at your Fontdue URL via an environment variable. Pick the one your framework already uses for public env vars:
|
|
30
|
+
|
|
31
|
+
| Framework | Variable |
|
|
32
|
+
| --- | --- |
|
|
33
|
+
| Astro | `PUBLIC_FONTDUE_URL` |
|
|
34
|
+
| React Router 7 / TanStack Start / Vike / Remix (Vite) | `VITE_FONTDUE_URL` |
|
|
35
|
+
| Next.js | `NEXT_PUBLIC_FONTDUE_URL` |
|
|
36
|
+
| Other / framework-less SSR | `FONTDUE_URL` |
|
|
37
|
+
|
|
38
|
+
A single variable covers both server and client in every supported framework — Vite exposes `import.meta.env.PUBLIC_*` / `VITE_*` on both sides, and Next inlines `NEXT_PUBLIC_*` on both sides.
|
|
29
39
|
|
|
30
|
-
|
|
31
|
-
2. If using Next.js, add an environment variable to your app `NEXT_PUBLIC_FONTDUE_URL` pointing to your Fontdue store URL. Otherwise, you can include the `url` prop on the `FontdueProvider`.
|
|
32
|
-
3. Render the [`StoreModal`](#storemodal) component so that is it available on every page.
|
|
33
|
-
4. Import the `fontdue-js/fontdue.css` CSS file. (This example uses Next.js)
|
|
40
|
+
## Setup
|
|
34
41
|
|
|
35
|
-
|
|
42
|
+
Pick the section that matches your framework. All four examples below have a working repo linked at the bottom.
|
|
36
43
|
|
|
44
|
+
The general pattern in every framework:
|
|
37
45
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
46
|
+
1. Mount `<FontdueProvider>` once at the layout level — it sets up the Relay environment + Redux store and renders auxiliary UI (theme config, test-mode banner, consent banner, analytics tracking).
|
|
47
|
+
2. Mount `<StoreModal />` once, alongside the provider — opens when a `<BuyButton>` or `<CartButton>` is clicked.
|
|
48
|
+
3. (SSR only.) Preload in the layout with `loadFontdueProviderQuery()` and pass it as `<FontdueProvider preloadedQuery={…}>`. This ensures the page hydrates with preloaded data.
|
|
49
|
+
4. (SSR only.) Preload per-page components with their `load{Component}Query()` helpers in route loaders / frontmatter / server components.
|
|
50
|
+
|
|
51
|
+
The shape of step 3 and 4 is the only thing that changes between frameworks.
|
|
52
|
+
|
|
53
|
+
<details>
|
|
54
|
+
<summary><b>Next.js (App Router)</b></summary>
|
|
55
|
+
|
|
56
|
+
No Vite plugin needed — wrap your Next config with [`withFontdue`](#nextjs-adapter) instead:
|
|
57
|
+
|
|
58
|
+
```js
|
|
59
|
+
// next.config.mjs
|
|
60
|
+
import { withFontdue } from "fontdue-js/next/config";
|
|
61
|
+
|
|
62
|
+
export default withFontdue({
|
|
63
|
+
// your Next config
|
|
64
|
+
});
|
|
41
65
|
```
|
|
42
66
|
|
|
67
|
+
The simplest setup omits the layout preload — with React Server Components, each fontdue-js component preloads its own query internally on the server and streams to the client.
|
|
68
|
+
|
|
43
69
|
```tsx
|
|
44
70
|
// app/layout.tsx
|
|
45
71
|
import FontdueProvider from "fontdue-js/FontdueProvider";
|
|
46
72
|
import StoreModal from "fontdue-js/StoreModal";
|
|
47
73
|
import "fontdue-js/fontdue.css";
|
|
48
74
|
|
|
49
|
-
export default
|
|
50
|
-
children,
|
|
51
|
-
}: {
|
|
52
|
-
children: React.ReactNode;
|
|
53
|
-
}) {
|
|
75
|
+
export default function RootLayout({ children }: { children: React.ReactNode }) {
|
|
54
76
|
return (
|
|
55
77
|
<html lang="en">
|
|
56
78
|
<body>
|
|
57
79
|
<FontdueProvider>
|
|
58
80
|
{children}
|
|
59
|
-
|
|
60
81
|
<StoreModal />
|
|
61
82
|
</FontdueProvider>
|
|
62
83
|
</body>
|
|
@@ -65,183 +86,708 @@ export default async function RootLayout({
|
|
|
65
86
|
}
|
|
66
87
|
```
|
|
67
88
|
|
|
68
|
-
|
|
89
|
+
```tsx
|
|
90
|
+
// app/fonts/[slug]/page.tsx — no explicit preload needed.
|
|
91
|
+
import TypeTester from "fontdue-js/TypeTester";
|
|
69
92
|
|
|
70
|
-
|
|
93
|
+
export default function FontPage() {
|
|
94
|
+
return <TypeTester familyName="Example" styleName="Regular" />;
|
|
95
|
+
}
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
Beyond the components, Next.js projects get a few extra entry points — config wrapping, cache revalidation, and helpers for your own GraphQL fetches. See [Next.js adapter](#nextjs-adapter).
|
|
99
|
+
|
|
100
|
+
Example repo: [`fontdue/fontdue-example-next`](https://github.com/fontdue/fontdue-example-next)
|
|
101
|
+
|
|
102
|
+
</details>
|
|
103
|
+
|
|
104
|
+
<details>
|
|
105
|
+
<summary><b>Astro</b></summary>
|
|
106
|
+
|
|
107
|
+
Add the Vite plugin to `astro.config.mjs`:
|
|
108
|
+
|
|
109
|
+
```ts
|
|
110
|
+
import { defineConfig } from "astro/config";
|
|
111
|
+
import react from "@astrojs/react";
|
|
112
|
+
import fontdueJs from "fontdue-js/vite";
|
|
113
|
+
|
|
114
|
+
export default defineConfig({
|
|
115
|
+
integrations: [react()],
|
|
116
|
+
vite: { plugins: [fontdueJs()] },
|
|
117
|
+
});
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
In Astro, every `client:*` component is its own React island — `<FontdueProvider>` doesn't form a React parent of your page components. Instead, it's a sibling island that sets up Fontdue's core on your site. Per-page components (`<TypeTester>`, etc.) self-wrap their own context when no parent provider is in scope.
|
|
121
|
+
|
|
122
|
+
Because of this, there's **no global config** in Astro: `config` set on `<FontdueProvider>` doesn't reach your page components. Pass `config` to each component instead — see [UI config](#ui-config).
|
|
123
|
+
|
|
124
|
+
```astro
|
|
125
|
+
---
|
|
126
|
+
// src/layouts/Layout.astro
|
|
127
|
+
import FontdueProvider, { loadFontdueProviderQuery } from "fontdue-js/FontdueProvider";
|
|
128
|
+
import StoreModal from "fontdue-js/StoreModal";
|
|
129
|
+
import "fontdue-js/fontdue.css";
|
|
130
|
+
|
|
131
|
+
const fontduePreload = await loadFontdueProviderQuery();
|
|
132
|
+
---
|
|
133
|
+
|
|
134
|
+
<html lang="en">
|
|
135
|
+
<body>
|
|
136
|
+
<FontdueProvider client:load preloadedQuery={fontduePreload} />
|
|
137
|
+
<StoreModal client:load />
|
|
138
|
+
<slot />
|
|
139
|
+
</body>
|
|
140
|
+
</html>
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
Per-page preload runs in frontmatter:
|
|
144
|
+
|
|
145
|
+
```astro
|
|
146
|
+
---
|
|
147
|
+
// src/pages/fonts/[slug].astro
|
|
148
|
+
import Layout from "../../layouts/Layout.astro";
|
|
149
|
+
import TypeTester, { loadTypeTesterQuery } from "fontdue-js/TypeTester";
|
|
150
|
+
|
|
151
|
+
const preloaded = await loadTypeTesterQuery({
|
|
152
|
+
familyName: "Example",
|
|
153
|
+
styleName: "Regular",
|
|
154
|
+
});
|
|
155
|
+
---
|
|
156
|
+
|
|
157
|
+
<Layout>
|
|
158
|
+
<TypeTester client:load preloadedQuery={preloaded} content="The quick brown fox" fontSize={64} />
|
|
159
|
+
</Layout>
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
Example repo: [`fontdue/example-astro`](https://github.com/fontdue/example-astro)
|
|
163
|
+
|
|
164
|
+
</details>
|
|
165
|
+
|
|
166
|
+
<details>
|
|
167
|
+
<summary><b>React Router 7</b></summary>
|
|
168
|
+
|
|
169
|
+
Add the Vite plugin to `vite.config.ts`:
|
|
170
|
+
|
|
171
|
+
```ts
|
|
172
|
+
import { defineConfig } from "vite";
|
|
173
|
+
import { reactRouter } from "@react-router/dev/vite";
|
|
174
|
+
import fontdueJs from "fontdue-js/vite";
|
|
175
|
+
|
|
176
|
+
export default defineConfig({
|
|
177
|
+
plugins: [reactRouter(), fontdueJs()],
|
|
178
|
+
});
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
Preload in the root route's loader, pass the result through `loaderData`:
|
|
182
|
+
|
|
183
|
+
```tsx
|
|
184
|
+
// app/root.tsx
|
|
185
|
+
import { Outlet } from "react-router";
|
|
186
|
+
import FontdueProvider, { loadFontdueProviderQuery } from "fontdue-js/FontdueProvider";
|
|
187
|
+
import StoreModal from "fontdue-js/StoreModal";
|
|
188
|
+
import "fontdue-js/fontdue.css";
|
|
189
|
+
import type { Route } from "./+types/root";
|
|
190
|
+
|
|
191
|
+
export async function loader() {
|
|
192
|
+
return { fontduePreload: await loadFontdueProviderQuery() };
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
export default function App({ loaderData }: Route.ComponentProps) {
|
|
196
|
+
return (
|
|
197
|
+
<FontdueProvider preloadedQuery={loaderData.fontduePreload}>
|
|
198
|
+
<Outlet />
|
|
199
|
+
<StoreModal />
|
|
200
|
+
</FontdueProvider>
|
|
201
|
+
);
|
|
202
|
+
}
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
Per-page preload mirrors the same shape:
|
|
206
|
+
|
|
207
|
+
```tsx
|
|
208
|
+
// app/routes/fonts.$slug.tsx
|
|
209
|
+
import TypeTester, { loadTypeTesterQuery } from "fontdue-js/TypeTester";
|
|
210
|
+
|
|
211
|
+
export async function loader() {
|
|
212
|
+
return {
|
|
213
|
+
preloadedQuery: await loadTypeTesterQuery({
|
|
214
|
+
familyName: "Example",
|
|
215
|
+
styleName: "Regular",
|
|
216
|
+
}),
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
export default function FontPage({ loaderData }) {
|
|
221
|
+
return <TypeTester preloadedQuery={loaderData.preloadedQuery} content="…" fontSize={64} />;
|
|
222
|
+
}
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
Example repo: [`fontdue/example-react-router`](https://github.com/fontdue/example-react-router)
|
|
226
|
+
|
|
227
|
+
</details>
|
|
228
|
+
|
|
229
|
+
<details>
|
|
230
|
+
<summary><b>TanStack Start</b></summary>
|
|
231
|
+
|
|
232
|
+
Add the Vite plugin to `vite.config.ts` (alongside TanStack's plugin). Preload in the root route's `loader`:
|
|
233
|
+
|
|
234
|
+
```tsx
|
|
235
|
+
// src/routes/__root.tsx
|
|
236
|
+
import { Outlet, createRootRoute } from "@tanstack/react-router";
|
|
237
|
+
import FontdueProvider, { loadFontdueProviderQuery } from "fontdue-js/FontdueProvider";
|
|
238
|
+
import StoreModal from "fontdue-js/StoreModal";
|
|
239
|
+
import "fontdue-js/fontdue.css";
|
|
240
|
+
|
|
241
|
+
export const Route = createRootRoute({
|
|
242
|
+
loader: async () => ({ fontduePreload: await loadFontdueProviderQuery() }),
|
|
243
|
+
component: RootComponent,
|
|
244
|
+
});
|
|
245
|
+
|
|
246
|
+
function RootComponent() {
|
|
247
|
+
const { fontduePreload } = Route.useLoaderData();
|
|
248
|
+
return (
|
|
249
|
+
<FontdueProvider preloadedQuery={fontduePreload}>
|
|
250
|
+
<Outlet />
|
|
251
|
+
<StoreModal />
|
|
252
|
+
</FontdueProvider>
|
|
253
|
+
);
|
|
254
|
+
}
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
Per-page preload uses each route's `loader`:
|
|
258
|
+
|
|
259
|
+
```tsx
|
|
260
|
+
// src/routes/fonts.$slug.tsx
|
|
261
|
+
import { createFileRoute } from "@tanstack/react-router";
|
|
262
|
+
import TypeTester, { loadTypeTesterQuery } from "fontdue-js/TypeTester";
|
|
263
|
+
|
|
264
|
+
export const Route = createFileRoute("/fonts/$slug")({
|
|
265
|
+
loader: async () => ({
|
|
266
|
+
preloadedQuery: await loadTypeTesterQuery({
|
|
267
|
+
familyName: "Example",
|
|
268
|
+
styleName: "Regular",
|
|
269
|
+
}),
|
|
270
|
+
}),
|
|
271
|
+
component: FontPage,
|
|
272
|
+
});
|
|
273
|
+
|
|
274
|
+
function FontPage() {
|
|
275
|
+
const { preloadedQuery } = Route.useLoaderData();
|
|
276
|
+
return <TypeTester preloadedQuery={preloadedQuery} content="…" fontSize={64} />;
|
|
277
|
+
}
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
Example repo: [`fontdue/example-tanstack`](https://github.com/fontdue/example-tanstack)
|
|
281
|
+
|
|
282
|
+
</details>
|
|
283
|
+
|
|
284
|
+
<details>
|
|
285
|
+
<summary><b>Other Vite-based frameworks (Vike, Remix, plain Vite SSR)</b></summary>
|
|
286
|
+
|
|
287
|
+
Add `fontdueJs()` to your Vite plugins. Run `loadFontdueProviderQuery()` wherever your framework loads layout-level data (Vike's `+data.ts`, Remix's root `loader`, etc.) and pass the result to `<FontdueProvider preloadedQuery>`. The component-level `load*Query()` helpers work the same way for per-page data.
|
|
288
|
+
|
|
289
|
+
Vike example — `+data.ts` for the layout, plus a per-page data loader. Re-export `Data = Awaited<ReturnType<typeof data>>` from each `+data.ts` so `useData<Data>()` gets a proper type without restating the shape:
|
|
290
|
+
|
|
291
|
+
```ts
|
|
292
|
+
// pages/+data.ts
|
|
293
|
+
import { loadFontdueProviderQuery } from "fontdue-js/FontdueProvider";
|
|
294
|
+
|
|
295
|
+
export const data = async () => ({
|
|
296
|
+
fontduePreload: await loadFontdueProviderQuery(),
|
|
297
|
+
});
|
|
298
|
+
export type Data = Awaited<ReturnType<typeof data>>;
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
```tsx
|
|
302
|
+
// pages/+Layout.tsx
|
|
303
|
+
import { useData } from "vike-react/useData";
|
|
304
|
+
import FontdueProvider from "fontdue-js/FontdueProvider";
|
|
305
|
+
import StoreModal from "fontdue-js/StoreModal";
|
|
306
|
+
import "fontdue-js/fontdue.css";
|
|
307
|
+
import type { Data } from "./+data";
|
|
308
|
+
|
|
309
|
+
export default function Layout({ children }: { children: React.ReactNode }) {
|
|
310
|
+
const { fontduePreload } = useData<Data>();
|
|
311
|
+
return (
|
|
312
|
+
<FontdueProvider preloadedQuery={fontduePreload}>
|
|
313
|
+
{children}
|
|
314
|
+
<StoreModal />
|
|
315
|
+
</FontdueProvider>
|
|
316
|
+
);
|
|
317
|
+
}
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
```ts
|
|
321
|
+
// pages/fonts/@slug/+data.ts
|
|
322
|
+
import { loadTypeTesterQuery } from "fontdue-js/TypeTester";
|
|
323
|
+
|
|
324
|
+
export const data = async () => ({
|
|
325
|
+
preloadedQuery: await loadTypeTesterQuery({
|
|
326
|
+
familyName: "Example",
|
|
327
|
+
styleName: "Regular",
|
|
328
|
+
}),
|
|
329
|
+
});
|
|
330
|
+
export type Data = Awaited<ReturnType<typeof data>>;
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
```tsx
|
|
334
|
+
// pages/fonts/@slug/+Page.tsx
|
|
335
|
+
import { useData } from "vike-react/useData";
|
|
336
|
+
import TypeTester from "fontdue-js/TypeTester";
|
|
337
|
+
import type { Data } from "./+data";
|
|
338
|
+
|
|
339
|
+
export default function FontPage() {
|
|
340
|
+
const { preloadedQuery } = useData<Data>();
|
|
341
|
+
return <TypeTester preloadedQuery={preloadedQuery} content="…" fontSize={64} />;
|
|
342
|
+
}
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
Remix follows the same shape with root `loader` / route `loader` + `useLoaderData()`. We don't ship an example repo for these yet — open an issue if you'd like one.
|
|
346
|
+
|
|
347
|
+
</details>
|
|
348
|
+
|
|
349
|
+
<details>
|
|
350
|
+
<summary><b>Client-only / no SSR</b></summary>
|
|
351
|
+
|
|
352
|
+
Mount `<FontdueProvider>` (no `preloadedQuery`) and render components with their lazy props (`{collectionId}`, `{familyName, styleName}`, etc.). They fetch on mount.
|
|
353
|
+
|
|
354
|
+
```tsx
|
|
355
|
+
import FontdueProvider from "fontdue-js/FontdueProvider";
|
|
356
|
+
import StoreModal from "fontdue-js/StoreModal";
|
|
357
|
+
import TypeTester from "fontdue-js/TypeTester";
|
|
358
|
+
import "fontdue-js/fontdue.css";
|
|
359
|
+
|
|
360
|
+
export default function App() {
|
|
361
|
+
return (
|
|
362
|
+
<FontdueProvider>
|
|
363
|
+
<TypeTester familyName="Example" styleName="Regular" />
|
|
364
|
+
<StoreModal />
|
|
365
|
+
</FontdueProvider>
|
|
366
|
+
);
|
|
367
|
+
}
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
</details>
|
|
371
|
+
|
|
372
|
+
## Next.js adapter
|
|
373
|
+
|
|
374
|
+
Next.js App Router projects get a few extra entry points beyond the components. The [example repo](https://github.com/fontdue/fontdue-example-next) wires up all of them.
|
|
375
|
+
|
|
376
|
+
### `withFontdue` — next.config wrapper
|
|
377
|
+
|
|
378
|
+
```js
|
|
379
|
+
// next.config.mjs
|
|
380
|
+
import { withFontdue } from "fontdue-js/next/config";
|
|
381
|
+
|
|
382
|
+
export default withFontdue({
|
|
383
|
+
// your Next config
|
|
384
|
+
});
|
|
385
|
+
```
|
|
386
|
+
|
|
387
|
+
What it installs:
|
|
388
|
+
|
|
389
|
+
- **Image settings** — `images.remotePatterns` entries for Fontdue's image hosts (plus `dangerouslyAllowSVG`, since font specimens are often SVGs), merged with your own `images` config.
|
|
390
|
+
- **Correct 404 statuses** — Next's streamed metadata locks in a `200` response before a `notFound()` thrown during `generateMetadata` can take effect ([vercel/next.js#82041](https://github.com/vercel/next.js/issues/82041)). `withFontdue` sets `htmlLimitedBots` to match every user agent so metadata rendering blocks the response and missing pages come out as real 404s.
|
|
391
|
+
|
|
392
|
+
The rest of your config — `rewrites` included — passes through unchanged.
|
|
393
|
+
|
|
394
|
+
#### Optional: image optimization on Cloudflare
|
|
395
|
+
|
|
396
|
+
If you have a Cloudflare zone with [image transformations](https://developers.cloudflare.com/images/transform-images/) enabled, set:
|
|
397
|
+
|
|
398
|
+
```shell
|
|
399
|
+
NEXT_PUBLIC_FONTDUE_IMAGE_HOST=img.your-domain.com
|
|
400
|
+
NEXT_PUBLIC_FONTDUE_IMAGE_ORIGINS=cdn.fontdue.com
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
`next/image` optimization then moves to the Cloudflare edge, and your deployment needs neither the `/_next/image` endpoint nor sharp. `NEXT_PUBLIC_FONTDUE_IMAGE_ORIGINS` (comma-separated hostnames) should mirror the transformation host's allowed source origins — sources on other hosts are served as originals rather than as transform URLs Cloudflare would refuse. Both variables must be present when `next build` runs (the loader is inlined into the client bundle), not just at serve time.
|
|
404
|
+
|
|
405
|
+
### Updating content: `/api/revalidate`
|
|
406
|
+
|
|
407
|
+
fontdue-js's server-side fetches are cached by Next and tagged `graphql`. Re-export the deploy-hook route handler:
|
|
408
|
+
|
|
409
|
+
```ts
|
|
410
|
+
// app/api/revalidate/route.ts
|
|
411
|
+
export { POST } from "fontdue-js/next/revalidate";
|
|
412
|
+
```
|
|
413
|
+
|
|
414
|
+
and set the Deploy hook URL in your Fontdue admin (Settings → Website settings) to `https://your-site.example/api/revalidate`. Fontdue calls it whenever your site's content changes, purging everything tagged `graphql` so the next request renders fresh.
|
|
415
|
+
|
|
416
|
+
fontdue-js's own server-side fetches opt into Next's data cache (and the `graphql` tag) automatically — static pages revalidated by the deploy hook is the intended way to run a Fontdue site, not dynamic rendering. Give your own fetches the same treatment; `currentFontdueEndpoint()` below shows how.
|
|
71
417
|
|
|
72
|
-
|
|
418
|
+
### Your own GraphQL fetches
|
|
73
419
|
|
|
74
|
-
|
|
420
|
+
`currentFontdueEndpoint()` (from `fontdue-js/next`) describes the endpoint your own server-side [GraphQL](https://docs.fontdue.com/graphql-api) fetches should use — the base origin, required headers, and the cache tags that tie them into `/api/revalidate`:
|
|
421
|
+
|
|
422
|
+
```ts
|
|
423
|
+
import { currentFontdueEndpoint } from "fontdue-js/next";
|
|
424
|
+
|
|
425
|
+
export async function fetchGraphql(query: string, variables?: unknown) {
|
|
426
|
+
const endpoint = currentFontdueEndpoint();
|
|
427
|
+
const response = await fetch(`${endpoint.origin}/graphql`, {
|
|
428
|
+
method: "POST",
|
|
429
|
+
body: JSON.stringify({ query, variables }),
|
|
430
|
+
headers: { "content-type": "application/json", ...endpoint.headers },
|
|
431
|
+
// Cache explicitly (Next 15 doesn't cache fetch by default), tagged so
|
|
432
|
+
// the deploy hook purges this too.
|
|
433
|
+
cache: "force-cache",
|
|
434
|
+
next: { tags: endpoint.tags },
|
|
435
|
+
});
|
|
436
|
+
return (await response.json()).data;
|
|
437
|
+
}
|
|
438
|
+
```
|
|
439
|
+
|
|
440
|
+
The shape is exported as `type FontdueEndpoint`.
|
|
441
|
+
|
|
442
|
+
## Migrating a Next.js site from v2
|
|
443
|
+
|
|
444
|
+
For a site built on the [example repo](https://github.com/fontdue/example-next) (App Router), v3 is a small, mechanical upgrade — component imports, props, and `NEXT_PUBLIC_FONTDUE_URL` all stay the same. Work through this checklist:
|
|
445
|
+
|
|
446
|
+
1. **Install the v3 line:**
|
|
447
|
+
|
|
448
|
+
```shell
|
|
449
|
+
npm install fontdue-js@alpha
|
|
450
|
+
```
|
|
451
|
+
|
|
452
|
+
v3 is ESM-only and needs `react` 18/19 and `node` >= 18. If TypeScript can't resolve the imports, set `moduleResolution` to `"bundler"` (or `node16`/`nodenext`) in `tsconfig.json` — see [Requirements](#requirements).
|
|
453
|
+
|
|
454
|
+
2. **Wrap your Next config with `withFontdue`.** It installs the Fontdue image settings (`remotePatterns`, `dangerouslyAllowSVG`) and the `htmlLimitedBots` workaround for correct 404 statuses, so you can delete those from your own config — for many sites the whole file shrinks to:
|
|
455
|
+
|
|
456
|
+
```js
|
|
457
|
+
// next.config.mjs (replaces next.config.js — the package is ESM)
|
|
458
|
+
import { withFontdue } from "fontdue-js/next/config";
|
|
459
|
+
|
|
460
|
+
export default withFontdue({});
|
|
461
|
+
```
|
|
462
|
+
|
|
463
|
+
3. **Replace your `/api/revalidate` handler with the re-export.** v3 caches and tags its own server-side fetches, and the shared handler purges everything carrying the `graphql` tag:
|
|
464
|
+
|
|
465
|
+
```ts
|
|
466
|
+
// app/api/revalidate/route.ts
|
|
467
|
+
export { POST } from "fontdue-js/next/revalidate";
|
|
468
|
+
```
|
|
469
|
+
|
|
470
|
+
Keep the Deploy hook URL in your Fontdue admin pointed at it.
|
|
471
|
+
|
|
472
|
+
4. **Delete caching workarounds you no longer need.** `export const fetchCache = "default-cache"` in the layout (if you added it) is obsolete — fontdue-js opts its own fetches into the data cache now. Your app's own GraphQL fetches should pass `cache: "force-cache"` and `next: { tags: endpoint.tags }` explicitly — see [Your own GraphQL fetches](#your-own-graphql-fetches).
|
|
473
|
+
|
|
474
|
+
5. **Remove the `url` prop from `<FontdueProvider>` if you passed one.** It never configured server-side fetches (server components have no context); v3 resolves everything from `NEXT_PUBLIC_FONTDUE_URL`. The prop still works as a client-side runtime override, but with the env var set you don't need it.
|
|
475
|
+
|
|
476
|
+
6. **Rename `useFontStyle` to `useFont`** if you use it (the old name still works as an alias).
|
|
477
|
+
|
|
478
|
+
What you get for it: server components now render the embeds' full HTML on the server (v2 hydrated some of them empty and fetched client-side), every fontdue-js fetch is cached and purged per-site by the deploy hook, and the optional [Cloudflare image loader](#optional-image-optimization-on-cloudflare) can replace the in-process optimizer entirely.
|
|
479
|
+
|
|
480
|
+
If you're starting fresh instead of migrating, fork the example repo — it ships in this shape already.
|
|
481
|
+
|
|
482
|
+
## UI config
|
|
483
|
+
|
|
484
|
+
Most components accept a `config` object that controls UI behavior — type-tester options (`selectable`, `priceBar`, size ranges, OpenType-feature UI…), store-modal layout, form styling, analytics tracking, and more. See the [full config reference](https://docs.fontdue.com/fontduejs#b3dec49aa08240bba2b4c71a67c08333).
|
|
485
|
+
|
|
486
|
+
There are two places to set it.
|
|
487
|
+
|
|
488
|
+
**On the provider.** `<FontdueProvider config={…}>` configures every Fontdue component rendered _inside_ it. This is the normal way wherever your components are React descendants of the provider — Next.js, React Router 7, TanStack Start, Vike, Remix, and client-only setups.
|
|
489
|
+
|
|
490
|
+
```tsx
|
|
491
|
+
<FontdueProvider config={{ typeTester: { selectable: true } }}>
|
|
492
|
+
<TypeTester familyName="Example" styleName="Regular" />
|
|
493
|
+
</FontdueProvider>
|
|
494
|
+
```
|
|
495
|
+
|
|
496
|
+
**Per component.** Every component below also accepts an optional `config` prop with the same shape. It's the way to configure a component used as a standalone island (see Astro, below).
|
|
497
|
+
|
|
498
|
+
```tsx
|
|
499
|
+
<TypeTester preloadedQuery={preloaded} config={{ typeTester: { selectable: true } }} />
|
|
500
|
+
```
|
|
501
|
+
|
|
502
|
+
The config type is exported from the package root, so you can type a shared object: `import type { Config } from "fontdue-js"`.
|
|
503
|
+
|
|
504
|
+
How the two compose:
|
|
505
|
+
|
|
506
|
+
- **Standalone** — a component with no `<FontdueProvider>` ancestor uses its own `config` prop in full.
|
|
507
|
+
- **Inside a provider** — the component's `config` deep-merges onto the provider's: the component's keys win, everything else is inherited.
|
|
508
|
+
- **Next.js App Router is the exception.** There, components render through React Server Components and read config from the `<FontdueProvider>` only — a per-component `config` prop is ignored. Set config on the provider.
|
|
509
|
+
|
|
510
|
+
### Astro and other per-island frameworks: there is no global config
|
|
511
|
+
|
|
512
|
+
In Astro, Vike, and any framework that hydrates each `client:*` component as its own React island, `<FontdueProvider>` is a _sibling_ island, not a React ancestor of your page components. **Config set on the provider does not reach them**, and there is no global config to set.
|
|
513
|
+
|
|
514
|
+
Pass `config` to each island instead. Define it once and reuse it so every island agrees:
|
|
515
|
+
|
|
516
|
+
```astro
|
|
517
|
+
---
|
|
518
|
+
import type { Config } from "fontdue-js";
|
|
519
|
+
import TypeTester, { loadTypeTesterQuery } from "fontdue-js/TypeTester";
|
|
520
|
+
|
|
521
|
+
// One source of truth for this page's testers.
|
|
522
|
+
const fontdueConfig = { typeTester: { selectable: true } } satisfies Config;
|
|
523
|
+
|
|
524
|
+
const regular = await loadTypeTesterQuery({ familyName: "Example", styleName: "Regular" });
|
|
525
|
+
const italic = await loadTypeTesterQuery({ familyName: "Example", styleName: "Italic" });
|
|
526
|
+
---
|
|
527
|
+
|
|
528
|
+
<TypeTester client:load preloadedQuery={regular} config={fontdueConfig} />
|
|
529
|
+
<TypeTester client:load preloadedQuery={italic} config={fontdueConfig} />
|
|
530
|
+
```
|
|
531
|
+
|
|
532
|
+
`config` affects the server-rendered HTML, so keeping a single source of truth is also what keeps SSR and client hydration in agreement. To share config across many pages, export it from a module (e.g. `src/lib/fontdue.ts`) and import it wherever you mount a component.
|
|
533
|
+
|
|
534
|
+
## IDs
|
|
535
|
+
|
|
536
|
+
> Some components accept a `collectionId`. This is the `id` returned from the [GraphQL API](https://docs.fontdue.com/graphql-api). You can alternatively pass `collectionSlug`, which is useful when you aren't consuming the GraphQL API directly. Prefer `collectionId` when possible.
|
|
75
537
|
|
|
76
538
|
---
|
|
77
539
|
|
|
78
540
|
# Components
|
|
79
541
|
|
|
542
|
+
Every component below has a default export and (where applicable) a `load{Component}Query` named export for the SSR preload path. Both share a single entry point per component. Every component also accepts an optional `config` prop — see [UI config](#ui-config).
|
|
543
|
+
|
|
544
|
+
## Lazy vs. preloaded props
|
|
545
|
+
|
|
546
|
+
Most components accept their data in one of two shapes:
|
|
547
|
+
|
|
548
|
+
- **Lazy props** — the identifying inputs the component needs to look up its own data: `collectionId` / `collectionSlug` for collection-bound components, `familyName` + `styleName` for the standalone `<TypeTester>`, nothing at all for forms like `<NewsletterSignup>` or `<TestFontsForm>`. The component fetches on mount, on the client, and shows nothing in the meantime.
|
|
549
|
+
- **`preloadedQuery`** — the result of calling the corresponding `load{Component}Query(…)` helper on the server. The component skips its own fetch, renders synchronously from the payload, and hydrates on the client without a re-fetch.
|
|
550
|
+
|
|
551
|
+
Both shapes are mutually exclusive on each component. You can mix them across the page — e.g. preload a `<TypeTester>` on a font-detail route while using a lazy `<BuyButton>` on the same page — and you can mix them across pages, since the choice is per-render.
|
|
552
|
+
|
|
553
|
+
```tsx
|
|
554
|
+
// Lazy — fetches on the client.
|
|
555
|
+
<TypeTester familyName="Example" styleName="Regular" />
|
|
556
|
+
|
|
557
|
+
// Preloaded — server-rendered, hydrates without a fetch.
|
|
558
|
+
const preloadedQuery = await loadTypeTesterQuery({
|
|
559
|
+
familyName: "Example",
|
|
560
|
+
styleName: "Regular",
|
|
561
|
+
});
|
|
562
|
+
<TypeTester preloadedQuery={preloadedQuery} />
|
|
563
|
+
```
|
|
564
|
+
|
|
565
|
+
**Which to use?**
|
|
566
|
+
|
|
567
|
+
- If you're in Next.js's App Router, use the lazy props — React Server Components takes care of the preload internally for you.
|
|
568
|
+
- If you're in any other framework with SSR (Astro, RR7, TanStack, Vike, Remix), prefer `preloadedQuery`. Otherwise the page hydrates with a flash of empty content while each component fetches.
|
|
569
|
+
- If your site is client-only (no SSR), lazy props are the only option.
|
|
570
|
+
|
|
571
|
+
A few components don't accept `preloadedQuery`:
|
|
572
|
+
|
|
573
|
+
- **`StoreModal`** and **`CartButton`** still render server-side, but without a preloaded query — their fetch always happens on the client after hydration, and the SSR output is the empty Suspense fallback. The reason: their data is per-customer-session (cart contents, modal-open state) and a build-time / CDN-cached SSR call would just cache an empty cart and delay the real one. `<CartButton>` reflects the right count as soon as the post-hydration fetch resolves; `<StoreModal>` renders nothing visible until opened, so there's nothing to flash.
|
|
574
|
+
- **`CustomerLoginForm`** has no preload helper today — it's a thin form with no upfront data needs.
|
|
80
575
|
|
|
81
576
|
## `FontdueProvider`
|
|
82
577
|
|
|
83
|
-
|
|
578
|
+
Provides the Fontdue context (Relay environment, Redux store, config, components map) and renders auxiliary UI (theme, test-mode banner, consent banner, tracking). Render once at the layout level.
|
|
84
579
|
|
|
85
580
|
```tsx
|
|
86
|
-
import FontdueProvider from
|
|
581
|
+
import FontdueProvider, { loadFontdueProviderQuery } from "fontdue-js/FontdueProvider";
|
|
87
582
|
```
|
|
88
583
|
|
|
89
584
|
| Prop | Description |
|
|
90
585
|
| --- | --- |
|
|
91
|
-
| `
|
|
92
|
-
| `config` | `object`
|
|
93
|
-
| `components` | `object` Component view overrides. This API will likely change. |
|
|
586
|
+
| `preloadedQuery` | (Recommended) Result of `loadFontdueProviderQuery()`. Warms aux UI synchronously. |
|
|
587
|
+
| `config` | `object` UI config applied to everything in the provider's tree. See [UI config](#ui-config). |
|
|
94
588
|
|
|
95
589
|
## `StoreModal`
|
|
96
590
|
|
|
97
|
-
|
|
591
|
+
The cart and checkout UI, rendered as a modal. Mount once at the layout level. Opens when a `BuyButton` is clicked or when navigated to from another component.
|
|
98
592
|
|
|
99
593
|
```tsx
|
|
100
|
-
import StoreModal from
|
|
594
|
+
import StoreModal from "fontdue-js/StoreModal";
|
|
101
595
|
```
|
|
102
596
|
|
|
103
|
-
|
|
597
|
+
`StoreModal` doesn't accept `preloadedQuery` — its content is per-customer-session (cart contents, modal-open state), which isn't safe to resolve at SSR time. The component still renders server-side, but its data fetch always runs on the client after hydration. The modal is closed by default, so there's nothing visible to flash.
|
|
104
598
|
|
|
105
|
-
|
|
599
|
+
## `BuyButton`
|
|
106
600
|
|
|
107
|
-
|
|
601
|
+
A button that opens `StoreModal` to the relevant collection.
|
|
108
602
|
|
|
109
603
|
```tsx
|
|
110
|
-
import BuyButton from
|
|
604
|
+
import BuyButton, { loadBuyButtonQuery } from "fontdue-js/BuyButton";
|
|
111
605
|
```
|
|
112
606
|
|
|
113
607
|
| Prop | Description |
|
|
114
608
|
| --- | --- |
|
|
115
|
-
| `collectionId` or `collectionSlug` | (Required) `string` Collection identifier |
|
|
116
|
-
| `
|
|
117
|
-
| `
|
|
609
|
+
| `collectionId` or `collectionSlug` | (Required, lazy) `string` Collection identifier. Omit if passing `preloadedQuery`. |
|
|
610
|
+
| `preloadedQuery` | (Required, SSR) Result of `loadBuyButtonQuery({ collectionId })` or `loadBuyButtonQuery({ collectionSlug })`. |
|
|
611
|
+
| `collectionName` | (Optional) `string` Name to render in the default label: `Buy {collectionName}`. |
|
|
612
|
+
| `label` | (Optional) `string` Override the button label entirely. |
|
|
118
613
|
|
|
119
614
|
## `CartButton`
|
|
120
615
|
|
|
121
|
-
|
|
616
|
+
Opens `StoreModal`, jumping straight to the cart screen if there are items in it.
|
|
122
617
|
|
|
123
618
|
```tsx
|
|
124
|
-
import CartButton from
|
|
619
|
+
import CartButton from "fontdue-js/CartButton";
|
|
125
620
|
```
|
|
126
621
|
|
|
622
|
+
No `preloadedQuery` (same reason as `StoreModal`). Renders server-side with an empty Suspense fallback, then fetches the cart on the client after hydration and updates with the live count. Render anywhere; safe with or without an explicit `<FontdueProvider>` ancestor.
|
|
623
|
+
|
|
127
624
|
| Prop | Description |
|
|
128
625
|
| --- | --- |
|
|
129
|
-
| `buttonStyle` | (Optional) `
|
|
130
|
-
| `label` | (Optional) `string`
|
|
626
|
+
| `buttonStyle` | (Optional) `string` Pass `'icon'` to render the cart icon instead of a text label. The value is also surfaced as `data-button-style` on the rendered `<button>` so you can target other styles via CSS. |
|
|
627
|
+
| `label` | (Optional) `string` Text content. Defaults to `"Cart"`. Ignored when `buttonStyle="icon"`. |
|
|
628
|
+
| `suffix` | (Optional) `string` Template appended to the label. Substitutions: `{count}`, `{subtotal}`. Hidden when the cart is empty. |
|
|
629
|
+
| `children` | (Optional) `ReactNode` Custom button contents. Replaces the default label / icon entirely. |
|
|
131
630
|
|
|
132
631
|
## `CharacterViewer`
|
|
133
632
|
|
|
134
|
-
An interactive character/glyph explorer.
|
|
633
|
+
An interactive character / glyph explorer.
|
|
135
634
|
|
|
136
635
|
```tsx
|
|
137
|
-
import CharacterViewer from
|
|
636
|
+
import CharacterViewer, { loadCharacterViewerQuery } from "fontdue-js/CharacterViewer";
|
|
138
637
|
```
|
|
139
638
|
|
|
140
639
|
| Prop | Description |
|
|
141
640
|
| --- | --- |
|
|
142
|
-
| `collectionId` or `collectionSlug` | (Required) `string`
|
|
143
|
-
|
|
641
|
+
| `collectionId` or `collectionSlug` | (Required, lazy) `string` Collection identifier. |
|
|
642
|
+
| `preloadedQuery` | (Required, SSR) Result of `loadCharacterViewerQuery({ collectionId })` or `loadCharacterViewerQuery({ collectionSlug })`. |
|
|
144
643
|
|
|
145
644
|
## `CustomerLoginForm`
|
|
146
645
|
|
|
147
|
-
A form for customers to
|
|
148
|
-
their email address, they receive a link to a Fontdue-hosted page to view orders.
|
|
646
|
+
A form for customers to look up their order history. Submitting an email address sends a link to a Fontdue-hosted orders page.
|
|
149
647
|
|
|
150
648
|
```tsx
|
|
151
|
-
import CustomerLoginForm from
|
|
649
|
+
import CustomerLoginForm from "fontdue-js/CustomerLoginForm";
|
|
152
650
|
```
|
|
153
651
|
|
|
154
652
|
| Prop | Description |
|
|
155
653
|
| --- | --- |
|
|
156
|
-
| `submitLabel` | `string`
|
|
654
|
+
| `submitLabel` | (Optional) `string` Submit button label. Defaults to `"Submit"`. |
|
|
157
655
|
|
|
158
656
|
## `TypeTesters`
|
|
159
657
|
|
|
160
|
-
|
|
658
|
+
Group of type testers configured through the Fontdue dashboard.
|
|
161
659
|
|
|
162
660
|
```tsx
|
|
163
|
-
import TypeTesters from
|
|
661
|
+
import TypeTesters, { loadTypeTestersQuery } from "fontdue-js/TypeTesters";
|
|
164
662
|
```
|
|
165
663
|
|
|
166
664
|
| Prop | Description |
|
|
167
665
|
| --- | --- |
|
|
168
|
-
| `collectionId` or `collectionSlug` | (Required) `string`
|
|
169
|
-
| `
|
|
170
|
-
| `
|
|
171
|
-
| `
|
|
172
|
-
| `
|
|
173
|
-
| `
|
|
174
|
-
| `
|
|
175
|
-
| `
|
|
666
|
+
| `collectionId` or `collectionSlug` | (Required, lazy) `string` Collection identifier. |
|
|
667
|
+
| `preloadedQuery` | (Required, SSR) Result of `loadTypeTestersQuery({ collectionId, tags?, excludeTags? })` or `loadTypeTestersQuery({ collectionSlug, tags?, excludeTags? })`. |
|
|
668
|
+
| `defaultMode` | (Optional) `'group' \| 'local'` Whether the "Affect all styles" toggle starts on (`group`) or off (`local`). |
|
|
669
|
+
| `autofit` | (Optional) `boolean` Make sentences fit on one line, adjusting size as the container resizes. Disables when the user changes font size or content. |
|
|
670
|
+
| `tags` | (Optional) `string[]` Render only testers tagged with any of these. |
|
|
671
|
+
| `excludeTags` | (Optional) `string[]` Exclude testers tagged with any of these. |
|
|
672
|
+
| `features` | (Optional) `string[]` OpenType feature codes to expose to users across all testers in the group (e.g. `['ss01', 'ss02']`). |
|
|
673
|
+
| `onFocus` | (Optional) `() => void` Fired when any tester gains focus. |
|
|
674
|
+
| `onBlur` | (Optional) `() => void` Fired when any tester loses focus. |
|
|
675
|
+
| `onToolbarOpenClose` | (Optional) `(open: boolean) => void` Fired when the toolbar opens or closes. |
|
|
176
676
|
|
|
177
677
|
## `TypeTester` (standalone)
|
|
178
678
|
|
|
179
|
-
Standalone
|
|
679
|
+
Standalone tester driven by props rather than dashboard content. Doesn't support the "Affect all styles" toggle.
|
|
180
680
|
|
|
181
681
|
```tsx
|
|
182
|
-
import TypeTester from
|
|
682
|
+
import TypeTester, { loadTypeTesterQuery } from "fontdue-js/TypeTester";
|
|
183
683
|
```
|
|
184
684
|
|
|
185
685
|
| Prop | Description |
|
|
186
686
|
| --- | --- |
|
|
187
|
-
| `familyName` | (Required) `string`
|
|
188
|
-
| `
|
|
687
|
+
| `familyName` and `styleName` | (Required, lazy) `string` Identify the font style to render. The family/style must already be uploaded to your Fontdue admin. |
|
|
688
|
+
| `preloadedQuery` | (Required, SSR) Result of `loadTypeTesterQuery({ familyName, styleName })`. |
|
|
189
689
|
| `fontSize` | (Optional) `number` Initial font size in pixels. |
|
|
190
|
-
| `lineHeight` | (Optional) `number`
|
|
191
|
-
| `
|
|
192
|
-
| `
|
|
193
|
-
| `
|
|
194
|
-
| `
|
|
195
|
-
| `
|
|
196
|
-
| `
|
|
197
|
-
| `
|
|
198
|
-
| `
|
|
690
|
+
| `lineHeight` | (Optional) `number` Proportional line height (`1` == `fontSize`). |
|
|
691
|
+
| `letterSpacing` | (Optional) `number` Letter spacing. |
|
|
692
|
+
| `content` | (Optional) `string` Initial content. |
|
|
693
|
+
| `direction` | (Optional) `'ltr' \| 'rtl'` Writing direction. |
|
|
694
|
+
| `alignment` | (Optional) `'left' \| 'center' \| 'right'` Text alignment. |
|
|
695
|
+
| `features` | (Optional) `string[]` OpenType feature codes to expose to users (e.g. `['ss01', 'ss02']`). |
|
|
696
|
+
| `featuresSelected` | (Optional) `string[]` Subset of `features` to mark as initially selected. |
|
|
697
|
+
| `axes` | (Optional) `string[]` Variable axes to expose (e.g. `['wdth', 'ital']`). Pair with `variableSettings`. |
|
|
698
|
+
| `featureSettings` | (Optional) `{ feature: string, value: string }[]` Pre-selected features. Shape matches `TypeTester.featureSettings` in the GraphQL API. |
|
|
699
|
+
| `variableSettings` | (Optional) `{ axis: string, value: number }[]` Pre-selected axis values. Shape matches `TypeTester.variableSettings` in the GraphQL API. |
|
|
700
|
+
| `autofit` | (Optional) See `TypeTesters.autofit` above. |
|
|
701
|
+
| `onFocus` / `onBlur` | (Optional) `() => void` |
|
|
199
702
|
|
|
200
703
|
## `TestFontsForm`
|
|
201
704
|
|
|
202
|
-
|
|
705
|
+
A form that lets visitors download test fonts after entering their details. Requires [Test Fonts](https://docs.fontdue.com/test-fonts) to be configured.
|
|
203
706
|
|
|
204
707
|
```tsx
|
|
205
|
-
import TestFontsForm from
|
|
708
|
+
import TestFontsForm, { loadTestFontsFormQuery } from "fontdue-js/TestFontsForm";
|
|
206
709
|
```
|
|
207
710
|
|
|
208
711
|
| Prop | Description |
|
|
209
712
|
| --- | --- |
|
|
210
|
-
| `
|
|
211
|
-
| `
|
|
212
|
-
| `
|
|
713
|
+
| `preloadedQuery` | (Optional, SSR) Result of `loadTestFontsFormQuery()`. Lazy if omitted. |
|
|
714
|
+
| `agreementLabel` | (Optional) `string` Label for the required agreement checkbox. Defaults to the "EULA agreement text" field in your Fontdue Labels settings. |
|
|
715
|
+
| `downloadLabel` | (Optional) `string` Submit button label. Defaults to `"Download test fonts"`. |
|
|
716
|
+
| `newsletterCheckboxChecked` | (Optional) `boolean` Pre-check the newsletter opt-in. |
|
|
213
717
|
|
|
214
718
|
## `NewsletterSignup`
|
|
215
719
|
|
|
216
|
-
A
|
|
720
|
+
A signup form that adds the visitor as a Customer in Fontdue.
|
|
217
721
|
|
|
218
722
|
```tsx
|
|
219
|
-
import NewsletterSignup from
|
|
723
|
+
import NewsletterSignup, { loadNewsletterSignupQuery } from "fontdue-js/NewsletterSignup";
|
|
220
724
|
```
|
|
221
725
|
|
|
222
726
|
| Prop | Description |
|
|
223
727
|
| --- | --- |
|
|
224
|
-
| `
|
|
225
|
-
| `
|
|
226
|
-
| `
|
|
728
|
+
| `preloadedQuery` | (Optional, SSR) Result of `loadNewsletterSignupQuery()`. Lazy if omitted. |
|
|
729
|
+
| `title` | (Optional) `string` Heading rendered above the form. |
|
|
730
|
+
| `intro` | (Optional) `string` Paragraph rendered between the title and the form. |
|
|
731
|
+
| `optInLabel` | (Optional) `string` Label rendered next to the opt-in checkbox. Defaults to the "Newsletter opt-in label" field in your Fontdue Labels settings. |
|
|
732
|
+
| `buttonLabel` | (Optional) `string` Submit button label. Defaults to `"Subscribe"`. |
|
|
733
|
+
| `successLabel` | (Optional) `string` Message shown after a successful submission. Defaults to the "Newsletter success label" field in your Fontdue Labels settings. |
|
|
734
|
+
| `optInCheckboxChecked` | (Optional) `boolean` Pre-check the opt-in box. |
|
|
735
|
+
|
|
736
|
+
---
|
|
737
|
+
|
|
738
|
+
# Hooks
|
|
227
739
|
|
|
228
740
|
## `useFont`
|
|
229
741
|
|
|
230
|
-
|
|
742
|
+
Loads and renders a webfont. Pass `webfontSources` (available as `FontStyle.webfontSources` in the GraphQL API) to load via the FontFace API directly — no CSS `@font-face` needed.
|
|
231
743
|
|
|
232
744
|
```tsx
|
|
233
|
-
import useFont from
|
|
745
|
+
import useFont from "fontdue-js/useFont";
|
|
234
746
|
|
|
235
747
|
const FontStyle = ({ familyName, styleName, webfontSources }) => {
|
|
236
748
|
const { style, loaded } = useFont({
|
|
237
749
|
fontFamily: `${familyName} ${styleName}`,
|
|
238
750
|
webfontSources,
|
|
239
751
|
});
|
|
240
|
-
|
|
241
752
|
return <span style={style}>The quick brown fox</span>;
|
|
242
753
|
};
|
|
243
754
|
```
|
|
244
755
|
|
|
245
|
-
If `webfontSources` is omitted, the hook falls back to detecting fonts loaded by CSS `@font-face` rules.
|
|
756
|
+
If `webfontSources` is omitted, the hook falls back to detecting fonts loaded by your CSS `@font-face` rules.
|
|
757
|
+
|
|
758
|
+
Also available as `fontdue-js/useFontStyle` for backwards compatibility.
|
|
759
|
+
|
|
760
|
+
## `useConsent`
|
|
761
|
+
|
|
762
|
+
Returns `true` when the visitor has granted consent for a given category. Re-renders when the consent state changes (e.g. the visitor accepts the consent banner).
|
|
763
|
+
|
|
764
|
+
```tsx
|
|
765
|
+
import { useConsent } from "fontdue-js/useConsent";
|
|
766
|
+
|
|
767
|
+
const analyticsConsent = useConsent("analytics");
|
|
768
|
+
```
|
|
769
|
+
|
|
770
|
+
## `useAutofit`
|
|
771
|
+
|
|
772
|
+
Measures a string against a container and returns a font size that fits on one line. Used internally by `TypeTester`'s `autofit` prop; exported for custom layouts.
|
|
773
|
+
|
|
774
|
+
```tsx
|
|
775
|
+
import useAutofit from "fontdue-js/useAutofit";
|
|
776
|
+
|
|
777
|
+
const { ref, fontSize, ready } = useAutofit({
|
|
778
|
+
text: "The quick brown fox",
|
|
779
|
+
fontFamily: "Tonka Regular",
|
|
780
|
+
fontSize: 200,
|
|
781
|
+
});
|
|
782
|
+
```
|
|
783
|
+
|
|
784
|
+
---
|
|
785
|
+
|
|
786
|
+
# Examples
|
|
787
|
+
|
|
788
|
+
Working repos for each supported framework, all hitting the same `example.fontdue.xyz` store and exercising every preloadable component:
|
|
246
789
|
|
|
247
|
-
|
|
790
|
+
- Next.js — [`fontdue/fontdue-example-next`](https://github.com/fontdue/fontdue-example-next)
|
|
791
|
+
- Astro — [`fontdue/example-astro`](https://github.com/fontdue/example-astro)
|
|
792
|
+
- React Router 7 — [`fontdue/example-react-router`](https://github.com/fontdue/example-react-router)
|
|
793
|
+
- TanStack Start — [`fontdue/example-tanstack`](https://github.com/fontdue/example-tanstack)
|