# Client SDK Usage Guide This project uses an auto-generated SDK powered by `@hey-api/openapi-ts` to interact with the PayloadCMS multi-tenant backend. ## SDK Structure - **Core Methods**: `src/clientsdk/sdk.gen.ts` (Contains classes like `Posts`, `Categories`, `Pages`, `Media`) - **Type Definitions**: `src/clientsdk/types.gen.ts` (Contains interfaces like `Post`, `Category`, `Media`) - **Query Serializer**: `src/clientsdk/querySerializer.ts` (Handles nested object serialization for PayloadCMS queries) - **Client Factory**: `src/clientsdk/client/index.ts` (Use `createClient` to initialize a client instance) ## 1. Initialization You must initialize the client with the correct `baseUrl`, `querySerializer`, and tenant headers. ```typescript import { createClient } from '../clientsdk/client'; import { customQuerySerializer } from '../clientsdk/querySerializer'; import { TENANT_SLUG, TENANT_API_KEY, API_URL } from '../config'; const client = createClient({ baseUrl: API_URL, querySerializer: customQuerySerializer, // CRITICAL: Required for nested where queries headers: { 'X-Tenant-Slug': TENANT_SLUG, 'X-API-Key': TENANT_API_KEY, }, }); ``` ## 2. Common Operations ### Fetching a List (with Sorting & Limits) ```typescript import { Posts } from '../clientsdk/sdk.gen'; const response = await Posts.listPosts({ client, query: { limit: 10, sort: '-createdAt', // Prefix with '-' for descending }, }); // Access the data const posts = response.data?.docs || []; ``` ### Fetching a Single Document by Slug (Filtering) PayloadCMS uses a specific `where` query syntax. The `customQuerySerializer` handles the translation to `where[slug][equals]=my-slug`. ```typescript const response = await Posts.listPosts({ client, query: { where: { slug: { equals: 'my-article-slug', }, }, limit: 1, }, }); const post = response.data?.docs?.[0]; ``` ### Filtering by Category Slug ```typescript const response = await Posts.listPosts({ client, query: { where: { 'categories.slug': { equals: 'news', }, }, }, }); ``` ## 3. Data Patterns ### Relationships - **Categories**: In this project, categories are a **many-to-many** relationship. Always treat `post.categories` as an array. - Correct: `post.categories?.[0]?.title` - Incorrect: `post.category.title` - **Media**: Images (like `heroImage`) are objects containing `url`, `alt`, and `sizes`. - Example: `{post.heroImage?.alt}` ### Rich Text (Lexical) PayloadCMS provides Lexical rich text. We typically use `post.content_html` which is pre-rendered to HTML on the server. - **React**: `
` - **Vue**: `
` - **Astro**: `
` ## 4. TypeScript Usage Always use the generated types for better DX and safety. ```typescript import type { Post, Category, Media } from '../clientsdk/types.gen'; function formatPost(post: Post) { return { title: post.title, date: new Date(post.createdAt).toLocaleDateString() }; } ``` ## 5. Troubleshooting - **CORS Issues**: Ensure `API_URL` in `config.ts` matches the backend port (default 3000). - **Empty Results**: Check if the `X-Tenant-Slug` header matches the slug assigned to your content in the CMS admin panel. - **Nested Query Error**: If you see "Deeply-nested arrays/objects aren’t supported", verify that you are passing the `customQuerySerializer` to the `createClient` options.