# Data Fetching Learn how to fetch data from the Finqu Storefront API using the `@finqu/storefront-sdk`. ## Server Components Use the Finqu SDK in Server Components for direct API access: ```tsx // app/my-component.tsx (Server Component) import { storefrontClient, cachePresets } from '@/lib/storefront'; import { getProduct, getCatalogProducts } from '@finqu/storefront-sdk/server'; export default async function ServerComponent() { // Using SDK helper const { product } = await getProduct(storefrontClient, { handle: 'my-product-slug', }); // Direct query const result = await getCatalogProducts(storefrontClient, { first: 10, query: 'search term', }); const products = result.catalog.products.nodes; const totalCount = result.catalog.products.totalCount; return
{product?.title}
; } ``` ## Client Components Use React hooks for client-side data fetching: ```tsx 'use client'; import { useProduct, useCatalogProducts } from '@finqu/storefront-sdk/react'; export function ClientComponent() { const { product, isLoading } = useProduct({ id: 123, }); const { products } = useCatalogProducts({ first: 20, query: 'shirts', }); return
{isLoading ?
Loading...
:
{product?.title}
}
; } ``` ## Caching Strategy The SDK provides cache presets for different data types: ```tsx import { storefrontClient, cachePresets, withLocale } from '@/lib/storefront'; // Long-lived data (1 hour) const menus = await storefrontClient.query(MENU_QUERY, {}, withLocale('en', cachePresets.static)); // Product data (1 minute) const products = await storefrontClient.query(PRODUCTS_QUERY, {}, cachePresets.products); // Dynamic data (no cache) const cart = await storefrontClient.query(CART_QUERY, {}, cachePresets.dynamic); ``` ### Cache Presets | Preset | Duration | Use Case | | ----------- | -------- | --------------------------- | | `static` | 1 hour | Menus, navigation, settings | | `products` | 1 minute | Product listings, details | | `dynamic` | No cache | Cart, user-specific data | ## Using Locale Always pass the locale when fetching data: ```tsx import { getLocale } from '@/lib/locale'; import { storefrontClient, withLocale } from '@/lib/storefront'; export default async function ServerComponent() { const locale = await getLocale(); const result = await storefrontClient.query( PRODUCTS_QUERY, {}, withLocale(locale, cachePresets.products) ); return
{/* ... */}
; } ``` ## Error Handling Handle API errors gracefully: ```tsx import { storefrontClient } from '@/lib/storefront'; export default async function ServerComponent() { try { const { product } = await getProduct(storefrontClient, { handle: 'my-product', }); if (!product) { return
Product not found
; } return
{product.title}
; } catch (error) { console.error('Failed to fetch product:', error); return
Error loading product
; } } ``` ## Common Patterns ### Fetching Products ```tsx import { getCatalogProducts } from '@finqu/storefront-sdk/server'; import { storefrontClient, cachePresets } from '@/lib/storefront'; const result = await getCatalogProducts(storefrontClient, { first: 20, query: 'shirts', sortBy: 'PRICE_ASC', }); const products = result.catalog.products.nodes; ``` ### Fetching a Single Product ```tsx import { getProduct } from '@finqu/storefront-sdk/server'; import { storefrontClient } from '@/lib/storefront'; const { product } = await getProduct(storefrontClient, { id: 123, // or handle: 'product-slug', }); ``` ### Fetching Categories ```tsx import { getProductGroups } from '@finqu/storefront-sdk/server'; import { storefrontClient, cachePresets } from '@/lib/storefront'; const result = await getProductGroups(storefrontClient, { first: 10, }); const categories = result.catalog.productGroups.nodes; ``` ## Next Steps - [Storefront SDK Documentation](./../storefront-sdk/overview) - Full SDK reference - [Multi-Locale Support](./multi-locale) - Handle multiple locales - [Blocks](./blocks) - Fetch data in blocks