Skip to content

Commit 2baf5ea

Browse files
committed
Add comprehensive @example tags to all hooks
1 parent 6056e92 commit 2baf5ea

14 files changed

Lines changed: 658 additions & 2 deletions

src/hooks/useDeepCompareEffect.ts

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,47 @@
11
import { useEffect, useRef, useMemo, type EffectCallback, type DependencyList } from "react"
22
import { deepCompare } from "../utils/compare"
33

4+
/**
5+
* Similar to useEffect but performs deep comparison of dependencies instead of shallow comparison.
6+
* Useful when dependencies are objects or arrays that may be recreated on each render.
7+
*
8+
* @example
9+
* ```tsx
10+
* import { useDeepCompareEffect } from '@nosto/nosto-react'
11+
*
12+
* function MyComponent({ user }: { user: { id: string, preferences: string[] } }) {
13+
* useDeepCompareEffect(() => {
14+
* console.log('User preferences changed:', user.preferences)
15+
* // This will only run when user object actually changes,
16+
* // not when it's recreated with same values
17+
* }, [user])
18+
*
19+
* return <div>User: {user.id}</div>
20+
* }
21+
* ```
22+
*
23+
* @example Comparing arrays and objects
24+
* ```tsx
25+
* import { useDeepCompareEffect } from '@nosto/nosto-react'
26+
*
27+
* function ProductList({ filters, sortOptions }: {
28+
* filters: { category: string, price: { min: number, max: number } }
29+
* sortOptions: string[]
30+
* }) {
31+
* useDeepCompareEffect(() => {
32+
* // This effect will only run when filters or sortOptions actually change
33+
* fetchProducts(filters, sortOptions)
34+
* }, [filters, sortOptions])
35+
*
36+
* return <div>Product list</div>
37+
* }
38+
* ```
39+
*
40+
* @param callback The effect callback function
41+
* @param dependencies Array of dependencies to deep compare
42+
*
43+
* @group Utilities
44+
*/
445
export function useDeepCompareEffect(callback: EffectCallback, dependencies: DependencyList) {
546
return useEffect(callback, useDeepCompareMemoize(dependencies))
647
}

src/hooks/useLoadClientScript.ts

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,59 @@ type NostoScriptProps = Pick<NostoProviderProps, "account" | "host" | "shopifyMa
77

88
const defaultAttributes = { "nosto-client-script": "" }
99

10+
/**
11+
* Hook for loading the Nosto client script and managing its load state.
12+
*
13+
* @example
14+
* ```tsx
15+
* import { useLoadClientScript } from '@nosto/nosto-react'
16+
*
17+
* function MyNostoProvider() {
18+
* const { clientScriptLoaded } = useLoadClientScript({
19+
* account: 'shopify-123456',
20+
* loadScript: true,
21+
* shopifyMarkets: {
22+
* marketId: 'US',
23+
* language: 'en'
24+
* }
25+
* })
26+
*
27+
* return (
28+
* <div>
29+
* {clientScriptLoaded ? (
30+
* <p>Nosto script loaded successfully</p>
31+
* ) : (
32+
* <p>Loading Nosto script...</p>
33+
* )}
34+
* </div>
35+
* )
36+
* }
37+
* ```
38+
*
39+
* @example Custom script loader
40+
* ```tsx
41+
* import { useLoadClientScript } from '@nosto/nosto-react'
42+
*
43+
* function CustomNostoProvider() {
44+
* const customScriptLoader = (url: string) => {
45+
* const script = document.createElement('script')
46+
* script.src = url
47+
* script.async = true
48+
* document.head.appendChild(script)
49+
* return script
50+
* }
51+
*
52+
* const { clientScriptLoaded } = useLoadClientScript({
53+
* account: 'my-nosto-account',
54+
* scriptLoader: customScriptLoader
55+
* })
56+
*
57+
* return <div>Script loaded: {String(clientScriptLoaded)}</div>
58+
* }
59+
* ```
60+
*
61+
* @group Essential Functions
62+
*/
1063
export function useLoadClientScript(props: NostoScriptProps) {
1164
const {
1265
scriptLoader = scriptLoaderFn,

src/hooks/useNosto404.tsx

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,43 @@ import { useRenderCampaigns } from "./useRenderCampaigns"
77
export type Nosto404Props = { placements?: string[] }
88

99
/**
10-
* You can personalise your cart and checkout pages by using the `useNosto404` hook.
10+
* You can personalise your 404 error pages by using the `useNosto404` hook.
11+
*
12+
* @example Basic 404 page usage
13+
* ```tsx
14+
* import { useNosto404 } from '@nosto/nosto-react'
15+
*
16+
* function NotFoundPage() {
17+
* useNosto404({
18+
* placements: ['notfound-nosto-1', 'notfound-popular-products']
19+
* })
20+
*
21+
* return (
22+
* <div>
23+
* <h1>Page Not Found</h1>
24+
* <p>Sorry, the page you're looking for doesn't exist.</p>
25+
* <div id="notfound-popular-products" />
26+
* <div id="notfound-nosto-1" />
27+
* </div>
28+
* )
29+
* }
30+
* ```
31+
*
32+
* @example 404 page with default placements
33+
* ```tsx
34+
* import { useNosto404 } from '@nosto/nosto-react'
35+
*
36+
* function Simple404Page() {
37+
* useNosto404() // Uses all available placements
38+
*
39+
* return (
40+
* <div>
41+
* <h1>Oops! Page not found</h1>
42+
* <p>Let us help you find what you're looking for:</p>
43+
* </div>
44+
* )
45+
* }
46+
* ```
1147
*
1248
* @group Hooks
1349
*/

src/hooks/useNostoApi.ts

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,51 @@ import { useDeepCompareEffect } from "./useDeepCompareEffect"
44
import { nostojs } from "@nosto/nosto-js"
55
import { API } from "@nosto/nosto-js/client"
66

7+
/**
8+
* Hook for executing code that requires access to the Nosto API.
9+
* Waits for the client script to load before executing the callback.
10+
*
11+
* @example
12+
* ```tsx
13+
* import { useNostoApi } from '@nosto/nosto-react'
14+
*
15+
* function ProductRecommendations({ productId }: { productId: string }) {
16+
* useNostoApi(async (api) => {
17+
* const data = await api
18+
* .defaultSession()
19+
* .viewProduct(productId)
20+
* .setPlacements(['productpage-nosto-1', 'productpage-nosto-2'])
21+
* .load()
22+
*
23+
* console.log('Recommendations loaded:', data)
24+
* }, [productId])
25+
*
26+
* return <div>Product recommendations will appear here</div>
27+
* }
28+
* ```
29+
*
30+
* @example Using deep comparison for complex dependencies
31+
* ```tsx
32+
* import { useNostoApi } from '@nosto/nosto-react'
33+
*
34+
* function OrderThankYou({ order }: { order: Order }) {
35+
* useNostoApi(async (api) => {
36+
* await api
37+
* .defaultSession()
38+
* .addOrder(order)
39+
* .load()
40+
* }, [order], { deep: true })
41+
*
42+
* return <div>Thank you for your order!</div>
43+
* }
44+
* ```
45+
*
46+
* @param cb Callback function that receives the Nosto API instance
47+
* @param deps Optional dependency list for useEffect
48+
* @param flags Optional flags, including `deep` for deep comparison of dependencies
49+
*
50+
* @group Essential Functions
51+
*/
752
export function useNostoApi(cb: (api: API) => void, deps?: DependencyList, flags?: { deep?: boolean }): void {
853
const { clientScriptLoaded } = useNostoContext()
954
const useEffectFn = flags?.deep ? useDeepCompareEffect : useEffect

src/hooks/useNostoCategory.tsx

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,47 @@ export type NostoCategoryProps = {
1212
/**
1313
* You can personalise your category and collection pages by using the useNostoCategory hook.
1414
*
15+
* @example Basic category page usage
16+
* ```tsx
17+
* import { useNostoCategory } from '@nosto/nosto-react'
18+
*
19+
* function CategoryPage({ categoryName }: { categoryName: string }) {
20+
* useNostoCategory({
21+
* category: categoryName,
22+
* placements: ['categorypage-nosto-1', 'categorypage-nosto-2']
23+
* })
24+
*
25+
* return (
26+
* <div>
27+
* <h1>Category: {categoryName}</h1>
28+
* <div id="categorypage-nosto-1" />
29+
* <div id="categorypage-nosto-2" />
30+
* </div>
31+
* )
32+
* }
33+
* ```
34+
*
35+
* @example Collection page with custom placements
36+
* ```tsx
37+
* import { useNostoCategory } from '@nosto/nosto-react'
38+
*
39+
* function CollectionPage({ collection }: { collection: { name: string, id: string } }) {
40+
* useNostoCategory({
41+
* category: `collection-${collection.id}`,
42+
* placements: ['collection-banner', 'collection-recommendations']
43+
* })
44+
*
45+
* return (
46+
* <div>
47+
* <h1>{collection.name} Collection</h1>
48+
* <div id="collection-banner" />
49+
* {/\* Product grid here *\/}
50+
* <div id="collection-recommendations" />
51+
* </div>
52+
* )
53+
* }
54+
* ```
55+
*
1556
* @group Hooks
1657
*/
1758
export function useNostoCategory({ category, placements }: NostoCategoryProps) {

src/hooks/useNostoCheckout.tsx

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,46 @@ export type NostoCheckoutProps = { placements?: string[] }
99
/**
1010
* You can personalise your cart and checkout pages by using the useNostoCheckout hook.
1111
*
12+
* @example Basic cart page usage
13+
* ```tsx
14+
* import { useNostoCheckout } from '@nosto/nosto-react'
15+
*
16+
* function CartPage() {
17+
* useNostoCheckout({
18+
* placements: ['cartpage-nosto-1', 'cartpage-cross-sell']
19+
* })
20+
*
21+
* return (
22+
* <div>
23+
* <h1>Your Cart</h1>
24+
* {/\* Cart items here *\/}
25+
* <div id="cartpage-cross-sell" />
26+
* <div id="cartpage-nosto-1" />
27+
* </div>
28+
* )
29+
* }
30+
* ```
31+
*
32+
* @example Checkout page with recommendations
33+
* ```tsx
34+
* import { useNostoCheckout } from '@nosto/nosto-react'
35+
*
36+
* function CheckoutPage() {
37+
* useNostoCheckout({
38+
* placements: ['checkout-upsell', 'checkout-last-chance']
39+
* })
40+
*
41+
* return (
42+
* <div>
43+
* <h1>Checkout</h1>
44+
* <div id="checkout-upsell" />
45+
* {/\* Checkout form here *\/}
46+
* <div id="checkout-last-chance" />
47+
* </div>
48+
* )
49+
* }
50+
* ```
51+
*
1252
* @group Hooks
1353
*/
1454
export function useNostoCheckout(props?: NostoCheckoutProps) {

src/hooks/useNostoContext.ts

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,44 @@ import { NostoContext, NostoContextType } from "../context"
44
/**
55
* A hook that allows you to access the NostoContext and retrieve Nosto-related data from it in React components.
66
*
7+
* @example
8+
* ```tsx
9+
* import { useNostoContext } from '@nosto/nosto-react'
10+
*
11+
* function NostoStatus() {
12+
* const { clientScriptLoaded, account, responseMode } = useNostoContext()
13+
*
14+
* return (
15+
* <div>
16+
* <p>Account: {account}</p>
17+
* <p>Script loaded: {String(clientScriptLoaded)}</p>
18+
* <p>Response mode: {responseMode}</p>
19+
* </div>
20+
* )
21+
* }
22+
* ```
23+
*
24+
* @example Using context for conditional rendering
25+
* ```tsx
26+
* import { useNostoContext } from '@nosto/nosto-react'
27+
*
28+
* function ConditionalRecommendations() {
29+
* const { clientScriptLoaded, recommendationComponent } = useNostoContext()
30+
*
31+
* if (!clientScriptLoaded) {
32+
* return <div>Loading recommendations...</div>
33+
* }
34+
*
35+
* return (
36+
* <div>
37+
* {recommendationComponent && (
38+
* <div id="nosto-recommendation-placeholder" />
39+
* )}
40+
* </div>
41+
* )
42+
* }
43+
* ```
44+
*
745
* @group Essential Functions
846
*/
947
export function useNostoContext(): NostoContextType {

src/hooks/useNostoHome.tsx

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,43 @@ export type NostoHomeProps = { placements?: string[] }
99
/**
1010
* You can personalise your home page by using the useNostoHome hook.
1111
*
12+
* @example Basic home page usage
13+
* ```tsx
14+
* import { useNostoHome } from '@nosto/nosto-react'
15+
*
16+
* function HomePage() {
17+
* useNostoHome({
18+
* placements: ['frontpage-nosto-1', 'frontpage-nosto-2', 'frontpage-hero']
19+
* })
20+
*
21+
* return (
22+
* <div>
23+
* <div id="frontpage-hero" />
24+
* <h1>Welcome to our store</h1>
25+
* <div id="frontpage-nosto-1" />
26+
* <div id="frontpage-nosto-2" />
27+
* </div>
28+
* )
29+
* }
30+
* ```
31+
*
32+
* @example Home page with default placements
33+
* ```tsx
34+
* import { useNostoHome } from '@nosto/nosto-react'
35+
*
36+
* function SimpleHomePage() {
37+
* // Uses all available placements configured in Nosto admin
38+
* useNostoHome()
39+
*
40+
* return (
41+
* <div>
42+
* <h1>Home Page</h1>
43+
* {/\* Nosto will inject content into configured placements *\/}
44+
* </div>
45+
* )
46+
* }
47+
* ```
48+
*
1249
* @group Hooks
1350
*/
1451
export function useNostoHome(props?: NostoHomeProps) {

0 commit comments

Comments
 (0)