### Install strapi-typed-client with pnpm Source: https://github.com/boxlab-ltd/strapi-typed-client/blob/main/docs/guide/getting-started.md Install the package using pnpm. ```bash pnpm add strapi-typed-client ``` -------------------------------- ### Install strapi-typed-client Source: https://github.com/boxlab-ltd/strapi-typed-client/blob/main/README.md Install the strapi-typed-client package using npm. ```bash npm install strapi-typed-client ``` -------------------------------- ### Install strapi-typed-client with yarn Source: https://github.com/boxlab-ltd/strapi-typed-client/blob/main/docs/guide/getting-started.md Install the package using yarn. ```bash yarn add strapi-typed-client ``` -------------------------------- ### Example .env.local for Strapi Configuration Source: https://github.com/boxlab-ltd/strapi-typed-client/blob/main/docs/advanced/authentication.md An example of how to configure environment variables in a .env.local file for Strapi URL and API token. ```bash NEXT_PUBLIC_STRAPI_URL=http://localhost:1337 STRAPI_TOKEN=your-strapi-api-token-here ``` -------------------------------- ### Full CLI Example with and without Authentication Source: https://github.com/boxlab-ltd/strapi-typed-client/blob/main/docs/advanced/authentication.md Demonstrates how to run the `strapi-types generate` command, showing examples for both unauthenticated access (default) and authenticated access using a token flag or environment variable. ```bash # Without auth (requireAuth: false, the default) npx strapi-types generate --url http://localhost:1337 # With auth (requireAuth: true) npx strapi-types generate --url http://localhost:1337 --token your-api-token # Using environment variable STRAPI_TOKEN=your-api-token npx strapi-types generate --url http://localhost:1337 ``` -------------------------------- ### Full Example of Creating an Article Source: https://github.com/boxlab-ltd/strapi-typed-client/blob/main/docs/guide/input-types.md Provides a comprehensive example of creating an article, showcasing the usage of scalar fields, relations (as IDs), media (as ID), components, and repeatable components. ```typescript const result = await strapi.articles.create({ // Scalar fields title: 'Getting Started with Strapi v5', slug: 'getting-started-strapi-v5', content: 'Full article content here...', views: 0, featured: true, publishedAt: '2025-01-15T10:00:00.000Z', // Relations (as IDs) category: 3, tags: [1, 5, 12], author: 7, // Media (as ID) coverImage: 42, // Component seo: { metaTitle: 'Getting Started with Strapi v5', metaDescription: 'Learn how to use Strapi v5 with TypeScript.', }, // Repeatable component sections: [ { heading: 'Introduction', body: 'Welcome...' }, { heading: 'Setup', body: 'First, install...' }, ], }) ``` -------------------------------- ### Full Next.js Landing Page Example Source: https://github.com/boxlab-ltd/strapi-typed-client/blob/main/docs/advanced/single-types.md A complete example demonstrating how to fetch and render a landing page in a Next.js application using the StrapiClient. It includes detailed population of related fields and basic JSX rendering. ```typescript import { StrapiClient } from '@/strapi' const strapi = new StrapiClient({ baseURL: process.env.NEXT_PUBLIC_STRAPI_URL ?? 'http://localhost:1337', token: process.env.STRAPI_TOKEN, }) export default async function LandingPage() { const landing = await strapi.landing.find({ populate: { hero: { populate: { backgroundImage: true, }, }, features: { populate: { icon: true, }, }, seo: true, }, }); return (

{landing.title}

{landing.hero && (

{landing.hero.heading}

{landing.hero.subheading}

)}
{landing.features?.map((feature, i) => (

{feature.title}

{feature.description}

))}
); } ``` -------------------------------- ### Install Strapi Blocks React Renderer Source: https://github.com/boxlab-ltd/strapi-typed-client/blob/main/docs/reference/media-file.md Installs the official Strapi Blocks React Renderer package using npm. ```bash npm install @strapi/blocks-react-renderer ``` -------------------------------- ### Initialize StrapiClient with Full Configuration Source: https://github.com/boxlab-ltd/strapi-typed-client/blob/main/docs/reference/api.md This example shows how to configure StrapiClient with all available options, including baseURL, token, debug, credentials, and validateSchema. ```typescript // Full configuration const strapi = new StrapiClient({ baseURL: 'https://api.example.com', token: 'your-api-token', debug: process.env.NODE_ENV === 'development', credentials: 'include', validateSchema: process.env.NODE_ENV === 'development', }) ``` -------------------------------- ### Query Endpoint Example Source: https://github.com/boxlab-ltd/strapi-typed-client/blob/main/docs/advanced/custom-endpoints.md This example demonstrates a 'query' endpoint with a request body, a response structure, and an optional filter parameter. The generated client will provide a typed method for this endpoint. ```APIDOC ## POST /query ### Description Executes a search query with specified terms and optional filters. ### Method POST ### Endpoint /query ### Parameters #### Request Body - **term** (string) - Required - The search term to query. - **filters** (object) - Optional - Filtering options for the search. - **type** (string) - Optional - The type of search result to filter by (e.g., 'article', 'page', 'product'). ### Request Example { "term": "example search", "filters": { "type": "article" } } ### Response #### Success Response (200) - **data** (array) - An array of search results. - **id** (number) - The unique identifier of the search hit. - **title** (string) - The title of the search hit. - **type** (string) - The type of the search hit ('article', 'page', or 'product'). - **score** (number) - The relevance score of the search hit. ### Response Example { "data": [ { "id": 1, "title": "Example Article", "type": "article", "score": 0.95 } ] } ``` -------------------------------- ### Seeding a Create Form with Defaults Source: https://github.com/boxlab-ltd/strapi-typed-client/blob/main/docs/guide/input-types.md Example of seeding a form and creating an article using the generated defaults. ```typescript import { ArticleDefaults } from './strapi/types' // Seed a create form straight from the schema const [form, setForm] = useState({ ...ArticleDefaults }) await strapi.articles.create({ ...ArticleDefaults, title: 'New Article' }) ``` -------------------------------- ### Conventional Commits Examples Source: https://github.com/boxlab-ltd/strapi-typed-client/blob/main/CONTRIBUTING.md Examples of commit messages following the Conventional Commits specification. Use these prefixes to categorize your commits. ```text feat(scope): add new feature ``` ```text fix(scope): fix a bug ``` ```text refactor(scope): restructure without behavior change ``` ```text chore(scope): maintenance, deps, configs ``` ```text docs(scope): documentation only ``` ```text test(scope): adding or updating tests ``` -------------------------------- ### Fetch Strapi Schema using cURL Source: https://github.com/boxlab-ltd/strapi-typed-client/blob/main/docs/advanced/plugin-config.md Examples of how to fetch the complete Strapi schema using cURL, with and without authentication. ```bash # Without auth curl http://localhost:1337/api/strapi-typed-client/schema # With auth curl -H "Authorization: Bearer YOUR_TOKEN" \ http://localhost:1337/api/strapi-typed-client/schema ``` -------------------------------- ### Basic Populate Example Source: https://github.com/boxlab-ltd/strapi-typed-client/blob/main/docs/guide/populate.md Demonstrates how to populate a relation in a find query. TypeScript infers the return type, allowing direct access to fields of the populated relation. ```typescript const result = await strapi.articles.find({ populate: { category: true }, }) ``` -------------------------------- ### Custom API Endpoint Example Source: https://github.com/boxlab-ltd/strapi-typed-client/blob/main/docs/advanced/custom-endpoints.md Demonstrates how to define a custom API endpoint in Strapi and how to call it using the generated client. ```APIDOC ## POST /contact/submit ### Description This endpoint allows submitting contact form data. ### Method POST ### Endpoint /contact/submit ### Parameters #### Request Body - **name** (string) - Required - The name of the sender. - **email** (string) - Required - The email address of the sender. - **message** (string) - Required - The message content. ### Request Example ```json { "name": "Jane", "email": "jane@example.com", "message": "Hi" } ``` ### Response #### Success Response (200) (Response structure depends on the handler implementation, not explicitly defined in source) #### Response Example (No specific success response example provided in source) ``` -------------------------------- ### Strapi Handler Format Examples Source: https://github.com/boxlab-ltd/strapi-typed-client/blob/main/docs/advanced/custom-endpoints.md Illustrates the different formats supported for specifying controller handlers in Strapi routes, including short, full Strapi UID, and plugin formats. ```typescript // Short format handler: 'article.publish' // Full format (api:: prefix) handler: 'api::article.article.publish' // Plugin format handler: 'plugin::my-plugin.controller.action' ``` -------------------------------- ### Next.js Server Component Example with StrapiClient Source: https://github.com/boxlab-ltd/strapi-typed-client/blob/main/docs/guide/nextjs.md Shows how to instantiate and use StrapiClient within a Next.js App Router Server Component to fetch and display articles. Includes configuration for caching and revalidation. ```tsx // app/articles/page.tsx import { StrapiClient } from '@/strapi' const strapi = new StrapiClient({ baseURL: process.env.NEXT_PUBLIC_STRAPI_URL ?? 'http://localhost:1337', token: process.env.STRAPI_TOKEN, }) export default async function ArticlesPage() { const articles = await strapi.articles.find( { filters: { status: { $eq: 'published' } }, sort: ['publishedAt:desc'], populate: { category: true, coverImage: true }, }, { revalidate: 60, tags: ['articles'] }, ) return ( ) } ``` -------------------------------- ### Populating Media Fields Source: https://github.com/boxlab-ltd/strapi-typed-client/blob/main/docs/guide/populate.md Use the `populate` option to include media fields in your query results. The example shows how to populate the `coverImage` field for articles. ```typescript const result = await strapi.articles.find({ populate: { coverImage: true, }, }) // result[0].coverImage is: // { // id: number // name: string // url: string // width: number | null // height: number | null // formats: Record | null // ... // } | null ``` -------------------------------- ### Fetch Strapi Schema Hash using cURL Source: https://github.com/boxlab-ltd/strapi-typed-client/blob/main/docs/advanced/plugin-config.md Example of how to fetch only the Strapi schema hash using cURL. ```bash curl http://localhost:1337/api/strapi-typed-client/schema-hash ``` -------------------------------- ### Populating Specific Relations Source: https://github.com/boxlab-ltd/strapi-typed-client/blob/main/docs/reference/api.md Example of populating specific relations for articles, such as 'category' and 'cover', to include related data in the response. ```typescript { populate: { category: true, cover: true } } ``` -------------------------------- ### Populating Component Fields Source: https://github.com/boxlab-ltd/strapi-typed-client/blob/main/docs/guide/populate.md Component fields can also be populated using the `populate` option. This example demonstrates populating the `seo` component for articles. ```typescript const result = await strapi.articles.find({ populate: { seo: true, // component field }, }) // result[0].seo is the full component type // { metaTitle: string, metaDescription: string, ... } ``` -------------------------------- ### Offset-Based Pagination for Articles Source: https://github.com/boxlab-ltd/strapi-typed-client/blob/main/docs/reference/api.md Demonstrates fetching articles using offset-based pagination, specifying the starting offset and the limit of items to retrieve. ```typescript // Offset-based pagination await strapi.articles.find({ pagination: { start: 50, limit: 25 }, }) ``` -------------------------------- ### Page-Based Pagination for Articles Source: https://github.com/boxlab-ltd/strapi-typed-client/blob/main/docs/reference/api.md Example of fetching articles using page-based pagination, specifying the desired page number and the number of items per page. ```typescript // Page-based pagination await strapi.articles.find({ pagination: { page: 2, pageSize: 25 }, }) ``` -------------------------------- ### find() Source: https://github.com/boxlab-ltd/strapi-typed-client/blob/main/docs/guide/client.md Retrieve a list of entries with optional filtering, sorting, pagination, and population. Use findWithMeta() to get pagination metadata. ```APIDOC ## find() ### Description Retrieve a list of entries with optional filtering, sorting, pagination, and population. ### Method `strapi.articles.find(options?: { filters?: object, sort?: string[], pagination?: { page: number, pageSize: number }, populate?: object })` ### Parameters #### Query Parameters - **filters** (object) - Optional - Filtering criteria. - **sort** (string[]) - Optional - Sorting order (e.g., `['createdAt:desc']`). - **pagination** (object) - Optional - Pagination settings (e.g., `{ page: 1, pageSize: 25 }`). - **populate** (object) - Optional - Specifies which relations to populate (e.g., `{ category: true }`). ### Response #### Success Response - **data** (Array
) - An array of Article objects. ### Request Example ```ts // All articles const result = await strapi.articles.find() // With parameters const result = await strapi.articles.find({ filters: { published: { $eq: true } }, sort: ['createdAt:desc'], pagination: { page: 1, pageSize: 25 }, populate: { category: true }, }) ``` ### Response Example ```json // result is Article[] [ { "id": 1, "title": "Example Article", "content": "This is the content.", "publishedAt": "2023-01-01T12:00:00Z", "createdAt": "2023-01-01T10:00:00Z", "updatedAt": "2023-01-01T11:00:00Z" } ] ``` ``` -------------------------------- ### Call Custom API Endpoint Source: https://github.com/boxlab-ltd/strapi-typed-client/blob/main/docs/advanced/custom-endpoints.md Example of calling the custom '/contact/submit' API endpoint using the generated client. ```typescript // Generated client usage await strapi.contact.submit({ name: 'Jane', email: 'jane@example.com', message: 'Hi', }) ``` -------------------------------- ### Create StrapiClient with Custom Fetch Source: https://github.com/boxlab-ltd/strapi-typed-client/blob/main/docs/guide/client.md Provide a custom fetch implementation to the StrapiClient, useful in environments without global fetch or for custom request handling. The example uses 'node-fetch'. ```typescript import nodeFetch from 'node-fetch' const strapi = new StrapiClient({ baseURL: 'http://localhost:1337', fetch: nodeFetch as any, }) ``` -------------------------------- ### Combine All Query Parameters Source: https://github.com/boxlab-ltd/strapi-typed-client/blob/main/docs/guide/filtering.md Combine filters, sorting, pagination, population, and field selection for complex data retrieval. This example filters by status and category, sorts by publication date, paginates, populates related data, and selects specific fields. ```typescript const result = await strapi.articles.find({ filters: { status: { $eq: 'published' }, category: { slug: { $in: ['tech', 'science'] }, }, }, sort: ['publishedAt:desc'], pagination: { page: 1, pageSize: 12, }, populate: { category: true, author: true, }, fields: ['title', 'slug', 'excerpt', 'publishedAt'], }) ``` -------------------------------- ### List Uploaded Files with Pagination and Filters Source: https://github.com/boxlab-ltd/strapi-typed-client/blob/main/docs/reference/media-file.md Use the find method with UploadQueryParams to list files. Note that the upload plugin uses flat 'start' and 'limit' for pagination, not the 'pagination' object. Filters can be applied to mime types, among others. ```typescript const files = await client.upload.find({ sort: 'createdAt:desc', limit: 20, start: 0, filters: { mime: { $contains: 'image/' } }, }) ``` -------------------------------- ### Strapi Article Input Type Example Source: https://github.com/boxlab-ltd/strapi-typed-client/blob/main/docs/reference/type-mapping.md Demonstrates the structure of an input type for a Strapi article, where all fields are optional for partial updates. Scalar fields can be nullified, and relation/media/component fields use specific input types. ```typescript interface ArticleInput { title?: string | null body?: string | null category?: RelationInput // relation (id, documentId, array, or operations) cover?: MediaInput // media by id seo?: SeoComponentInput | null // component as object tags?: RelationInput // relation (any cardinality) } ``` -------------------------------- ### Populating Media Fields for Articles Source: https://github.com/boxlab-ltd/strapi-typed-client/blob/main/docs/reference/media-file.md To include media fields like 'cover' in your response, you must use the 'populate' option. Without it, media fields are absent from the returned type. This example shows fetching an article with its cover image fully populated. ```typescript const article = await strapi.articles.findOne('abc123', { populate: { cover: true }, }) // article.cover?.url <-- fully typed as MediaFile | null ``` -------------------------------- ### Deeply Nested Populate Example Source: https://github.com/boxlab-ltd/strapi-typed-client/blob/main/docs/guide/populate.md Demonstrates deeply nested population for multiple relations, including an author's avatar and organization's logo, allowing for comprehensive data retrieval. ```typescript const result = await strapi.articles.find({ populate: { author: { populate: { avatar: true, organization: { populate: { logo: true, }, }, }, }, }, }) ``` -------------------------------- ### Selecting Specific Fields for Articles Source: https://github.com/boxlab-ltd/strapi-typed-client/blob/main/docs/reference/api.md Example of using the 'fields' option to retrieve only specific fields ('title', 'slug', 'createdAt') for articles, reducing payload size. ```typescript await strapi.articles.find({ fields: ['title', 'slug', 'createdAt'], }) ``` -------------------------------- ### Using NextOptions for API Calls Source: https://github.com/boxlab-ltd/strapi-typed-client/blob/main/docs/reference/api.md Demonstrates various ways to utilize NextOptions for controlling cache behavior in API requests. These examples cover ISR revalidation, tag-based revalidation, disabling cache, and adding custom headers. Options can also be combined for more complex caching strategies. ```typescript // ISR: revalidate every hour await strapi.articles.find({}, { revalidate: 3600 }) ``` ```typescript // Tag-based revalidation await strapi.articles.find({}, { tags: ['articles'] }) ``` ```typescript // No caching await strapi.articles.find({}, { cache: 'no-store' }) ``` ```typescript // Custom headers (e.g. pass Referer for server-side requests) await strapi.articles.find({}, { headers: { Referer: 'https://myapp.com' } }) ``` ```typescript // Combine options await strapi.articles.find( { filters: { status: 'published' } }, { revalidate: 300, tags: ['articles', 'published'] }, ) ``` -------------------------------- ### Generated Component and Dynamic Zone Types Source: https://github.com/boxlab-ltd/strapi-typed-client/blob/main/docs/advanced/dynamic-zones.md Example of generated TypeScript interfaces for components and their corresponding Dynamic Zone aliases. The `*Dz` aliases include the `__component` literal required by Strapi for Dynamic Zones. ```typescript export interface HeroBlock { id: number heading: string subheading: string | null } export interface TextBlock { id: number body: string alignment: 'left' | 'center' | 'right' } export interface GalleryBlock { id: number title: string | null } export type HeroBlockDz = HeroBlock & { __component: 'landing.hero-block' } export type TextBlockDz = TextBlock & { __component: 'landing.text-block' } export type GalleryBlockDz = GalleryBlock & { __component: 'landing.gallery-block' } export interface Landing { id: number documentId: string title: string createdAt: string updatedAt: string } ``` -------------------------------- ### Initialize StrapiClient with Minimal Configuration Source: https://github.com/boxlab-ltd/strapi-typed-client/blob/main/docs/reference/api.md Use this snippet to create a StrapiClient instance with only the required baseURL. ```typescript import { StrapiClient } from '@/strapi' const strapi = new StrapiClient(config: StrapiClientConfig) // Minimal configuration const strapi = new StrapiClient({ baseURL: 'http://localhost:1337', }) ``` -------------------------------- ### Create Article with Media Source: https://github.com/boxlab-ltd/strapi-typed-client/blob/main/docs/guide/input-types.md Demonstrates how to assign single and multiple media files to an article during creation using their IDs. ```typescript await strapi.articles.create({ title: 'New Article', coverImage: 12, // single media — file id 12 gallery: [12, 15, 20], // multi media — array of file ids }) ``` -------------------------------- ### Filtering Draft Articles Source: https://github.com/boxlab-ltd/strapi-typed-client/blob/main/docs/reference/api.md Example of fetching only draft entries for articles by setting the 'status' parameter to 'draft'. ```typescript // Fetch only draft entries await strapi.articles.find({ status: 'draft', }) ``` -------------------------------- ### Enable Strapi Typed Client Plugin Source: https://github.com/boxlab-ltd/strapi-typed-client/blob/main/docs/advanced/plugin-config.md Enable the plugin by adding it to your `config/plugins.ts` file. No import or resolve is needed. ```typescript // config/plugins.ts export default { 'strapi-typed-client': { enabled: true, }, } ``` -------------------------------- ### Strapi Schema Hash Response Example Source: https://github.com/boxlab-ltd/strapi-typed-client/blob/main/docs/advanced/plugin-config.md This JSON structure represents only the schema hash, as returned by the /api/strapi-typed-client/schema-hash endpoint. ```json { "hash": "a1b2c3d4e5f6..." } ``` -------------------------------- ### Initialize Strapi Client Source: https://github.com/boxlab-ltd/strapi-typed-client/blob/main/docs/advanced/single-types.md Instantiate the StrapiClient with the base URL of your Strapi instance. ```typescript const strapi = new StrapiClient({ baseURL: 'http://localhost:1337' }) ``` -------------------------------- ### GET /api/strapi-typed-client/schema-hash Source: https://github.com/boxlab-ltd/strapi-typed-client/blob/main/docs/advanced/plugin-config.md Retrieves only the schema hash. This is efficient for quick checks or integration into CI pipelines where only the hash is needed. ```APIDOC ## GET /api/strapi-typed-client/schema-hash ### Description Returns only the schema hash. Useful for one-off checks or CI pipelines. ### Method GET ### Endpoint /api/strapi-typed-client/schema-hash ### Response #### Success Response (200) - **hash** (string) - A hash representing the current schema. ### Response Example ```json { "hash": "a1b2c3d4e5f6..." } ``` ``` -------------------------------- ### Instantiate and Use Strapi Typed Client Source: https://github.com/boxlab-ltd/strapi-typed-client/blob/main/docs/guide/getting-started.md Create a client instance and make a typed API call to fetch articles with filters, sort, and pagination. The client uses the global fetch by default. ```typescript import { StrapiClient } from '@/strapi' const strapi = new StrapiClient({ baseURL: 'http://localhost:1337', }) // Fully typed — autocomplete for filters, sort, populate const articles = await strapi.articles.find({ filters: { title: { $contains: 'hello' } }, sort: ['createdAt:desc'], pagination: { page: 1, pageSize: 10 }, }) console.log(articles) // Article[] ``` -------------------------------- ### Call API with Path Parameter (Slug) Source: https://github.com/boxlab-ltd/strapi-typed-client/blob/main/docs/advanced/custom-endpoints.md Example of calling an API endpoint that uses a path parameter for a category slug. ```typescript // Route: { path: '/categories/:slug/featured', handler: 'category.featured' } // Generated method: await strapi.categories.featured('technology') ``` -------------------------------- ### Listing Files Source: https://github.com/boxlab-ltd/strapi-typed-client/blob/main/docs/reference/media-file.md Explains how to list uploaded files using the `find` method with query parameters for filtering, sorting, and pagination. ```APIDOC ## Listing Files The `find()` method accepts an `UploadQueryParams` object for filtering, sorting, and pagination. ```ts const files = await client.upload.find({ sort: 'createdAt:desc', limit: 20, start: 0, filters: { mime: { $contains: 'image/' } }, }) ``` **Note on Pagination**: The upload plugin uses flat `start`/`limit` parameters instead of Strapi v5's standard `pagination[page]`/`pagination[pageSize]`. **Note on Response Shape**: The upload plugin returns a flat array of `MediaFile` objects, without the `{ data, meta }` envelope. ``` -------------------------------- ### Call API with Path Parameter (ID) Source: https://github.com/boxlab-ltd/strapi-typed-client/blob/main/docs/advanced/custom-endpoints.md Example of calling an API endpoint that uses a path parameter for an article ID. ```typescript // Route: { path: '/articles/:id/publish', handler: 'article.publish' } // Generated method: await strapi.articles.publish('article-id-here', { notifySubscribers: true }) ``` -------------------------------- ### Call API with JSON Body Source: https://github.com/boxlab-ltd/strapi-typed-client/blob/main/docs/advanced/custom-endpoints.md Example of calling a custom API endpoint with a JSON body, distinct from FormData usage. ```typescript // JSON body await strapi.articles.publish('article-id', { notifySubscribers: true, }) ``` -------------------------------- ### Initialize StrapiClient with Custom Fetch Source: https://github.com/boxlab-ltd/strapi-typed-client/blob/main/docs/reference/api.md Configure StrapiClient to use a custom fetch implementation, useful for Node.js environments or testing. ```typescript // With custom fetch (e.g., for Node.js or testing) import fetch from 'node-fetch' const strapi = new StrapiClient({ baseURL: 'http://localhost:1337', fetch: fetch as any, }) ``` -------------------------------- ### Strapi Schema Response Example Source: https://github.com/boxlab-ltd/strapi-typed-client/blob/main/docs/advanced/plugin-config.md This JSON structure represents the complete content type schema and its hash, as returned by the /api/strapi-typed-client/schema endpoint. ```json { "hash": "a1b2c3d4e5f6...", "schema": { "contentTypes": { "api::post.post": { "kind": "collectionType", "singularName": "post", "pluralName": "posts", "attributes": { "title": { "type": "string", "required": true }, "content": { "type": "richtext" }, "author": { "type": "relation", "relation": "manyToOne", "target": "plugin::users-permissions.user" } } } }, "components": { "landing.hero-block": { "attributes": { "heading": { "type": "string" }, "backgroundImage": { "type": "media" } } } } } } ``` -------------------------------- ### Populating All Relations Source: https://github.com/boxlab-ltd/strapi-typed-client/blob/main/docs/reference/api.md Shows how to populate all relations for articles, one level deep, by using the wildcard '*' in the populate option. ```typescript { populate: '*' } ``` -------------------------------- ### Create Strapi Client with Token Source: https://github.com/boxlab-ltd/strapi-typed-client/blob/main/docs/guide/client.md Instantiate the StrapiClient with a base URL and an API token for authentication. ```typescript const strapi = new StrapiClient({ baseURL: 'http://localhost:1337', token: 'your-api-token', }) ``` -------------------------------- ### Populate Single Type Relations Source: https://github.com/boxlab-ltd/strapi-typed-client/blob/main/docs/advanced/single-types.md Demonstrates how to populate relations, components, media fields, and dynamic zones for single types, similar to collection types. ```typescript // Boolean populate for a specific field const landing = await strapi.landing.find({ populate: { hero: true, }, }) ``` ```typescript // Deep populate for nested relations const landing = await strapi.landing.find({ populate: { hero: { populate: { backgroundImage: true, }, }, features: { populate: { icon: true, }, }, seo: true, }, }) ``` -------------------------------- ### Integrate Strapi-Typed-Client into package.json Scripts Source: https://github.com/boxlab-ltd/strapi-typed-client/blob/main/docs/guide/cli.md Add scripts to your package.json for generating, checking, watching, and building types. The build script includes type generation with --force before the Next.js build. ```json { "scripts": { "generate-types": "strapi-types generate --output ./src/strapi", "check-strapi": "strapi-types check --output ./src/strapi", "dev": "strapi-types watch --output ./src/strapi & next dev", "build": "strapi-types generate --output ./src/strapi --force && next build" } } ``` -------------------------------- ### Creating an Article with Nullable Fields Source: https://github.com/boxlab-ltd/strapi-typed-client/blob/main/docs/guide/input-types.md Demonstrates how to create an article entry, specifying which optional fields can be set to null. This includes simple optional fields, relations, and media fields. ```typescript await strapi.articles.create({ title: 'Article', // required — cannot be null subtitle: null, // optional — can be null category: null, // relation — can be null coverImage: null, // media — can be null }) ``` -------------------------------- ### create() Source: https://github.com/boxlab-ltd/strapi-typed-client/blob/main/docs/guide/client.md Create a new entry. The data parameter uses the generated input type with all writable fields. ```APIDOC ## create() ### Description Create a new entry. The data parameter uses the generated input type with all writable fields. ### Method `strapi.articles.create(data: object)` ### Parameters #### Request Body - **data** (object) - Required - The data for the new entry. Fields include `title`, `content`, `category` (as ID), etc. ### Response #### Success Response - **data** (Article) - The newly created Article object. ### Request Example ```ts const result = await strapi.articles.create({ title: 'My New Article', content: 'Article body text...', category: 1, // relation as ID }) ``` ### Response Example ```json { "id": 2, "title": "My New Article", "content": "Article body text...", "publishedAt": null, "createdAt": "2023-01-02T10:00:00Z", "updatedAt": "2023-01-02T10:00:00Z", "category": { "id": 1, "name": "Technology" } } ``` ``` -------------------------------- ### StrapiClient Constructor Source: https://github.com/boxlab-ltd/strapi-typed-client/blob/main/docs/reference/api.md Initializes a new instance of the StrapiClient. Requires at least a baseURL and optionally accepts a token, custom fetch function, debug flag, credentials mode, timeout, and schema validation flag. ```APIDOC ## StrapiClient Constructor ### Description Initializes a new instance of the StrapiClient. Requires at least a baseURL and optionally accepts a token, custom fetch function, debug flag, credentials mode, timeout, and schema validation flag. ### Parameters #### Request Body - **baseURL** (string) - Required - Strapi server URL (e.g., `http://localhost:1337`) - **token** (string) - Optional - Bearer token for authenticated requests - **fetch** (typeof fetch) - Optional - Custom fetch function (defaults to `globalThis.fetch`) - **debug** (boolean) - Optional - Log all requests to console - **credentials** (RequestCredentials) - Optional - Credentials mode for fetch (`include`, `same-origin`, `omit`) - **timeout** (number) - Optional - Request timeout in milliseconds. Aborts request if exceeded - **validateSchema** (boolean) - Optional - Check schema hash on init and warn if types are outdated ### Request Example ```ts // Minimal configuration const strapi = new StrapiClient({ baseURL: 'http://localhost:1337', }) // Full configuration const strapi = new StrapiClient({ baseURL: 'https://api.example.com', token: 'your-api-token', debug: process.env.NODE_ENV === 'development', credentials: 'include', validateSchema: process.env.NODE_ENV === 'development', }) // With custom fetch (e.g., for Node.js or testing) import fetch from 'node-fetch' const strapi = new StrapiClient({ baseURL: 'http://localhost:1337', fetch: fetch as any, }) ``` ``` -------------------------------- ### TypeScript Type Error Example Source: https://github.com/boxlab-ltd/strapi-typed-client/blob/main/docs/advanced/extending-payloads.md Demonstrates a TypeScript error when attempting to cast a payload to a type that doesn't sufficiently overlap due to omitted and redefined fields. ```typescript type Share = Omit< ProjectGetPayload<{ populate: { config: true } }>, 'config' > & { config: ProjectShareConfig[] watermark: boolean authorUsername: string } const data = (await strapi.projects.findOne(documentId, { populate: { config: true }, })) as Share // TS2352: neither type sufficiently overlaps with the other. ``` -------------------------------- ### Handle Upload API Errors Source: https://github.com/boxlab-ltd/strapi-typed-client/blob/main/docs/reference/media-file.md Upload methods throw StrapiError or StrapiConnectionError. This example shows how to catch a 403 error, indicating a lack of permission to delete uploads. ```typescript try { await client.upload.delete(42) } catch (err) { if (err instanceof StrapiError && err.status === 403) { // missing permission to delete uploads } throw err } ``` -------------------------------- ### Check Strapi Types Source: https://github.com/boxlab-ltd/strapi-typed-client/blob/main/docs/guide/cli.md Compares the schema hash baked into your generated client against the live Strapi schema to ensure types are up to date. Useful in CI. The `--output` option is required. ```bash npx strapi-types check --url http://localhost:1337 --output ./src/strapi ``` -------------------------------- ### Generate Types in CI/CD with Token Source: https://github.com/boxlab-ltd/strapi-typed-client/blob/main/docs/advanced/authentication.md Use the `--token` flag with your stored secret token when generating types in a CI/CD pipeline, shown here with a GitHub Actions example. ```yaml # GitHub Actions example - name: Generate Strapi types run: npx strapi-types generate --url ${{ secrets.STRAPI_URL }} --token ${{ secrets.STRAPI_TOKEN }} ``` -------------------------------- ### Uploading Files Source: https://github.com/boxlab-ltd/strapi-typed-client/blob/main/docs/reference/media-file.md Demonstrates how to construct FormData to upload files, including attaching them to existing entries. ```APIDOC ## Uploading Files ### Basic File Upload Construct a `FormData` object with the field name `files` and append files to it. ```ts // Web const input = document.querySelector('#picker')! const formData = new FormData() for (const file of input.files ?? []) { formData.append('files', file) } const uploaded = await client.upload.upload(formData) // uploaded is MediaFile[] ``` ```ts // React Native const formData = new FormData() formData.append('files', { uri: localUri, name: 'photo.jpg', type: 'image/jpeg', } as any) const [file] = await client.upload.upload(formData) ``` ### Attaching Files to Existing Entries To attach uploaded files to an existing entry, add `ref`, `refId`, and `field` to the `FormData`. ```ts formData.append('ref', 'api::article.article') formData.append('refId', String(articleId)) formData.append('field', 'cover') await client.upload.upload(formData) ``` ``` -------------------------------- ### GET /api/strapi-typed-client/schema Source: https://github.com/boxlab-ltd/strapi-typed-client/blob/main/docs/advanced/plugin-config.md Retrieves the complete content type schema and its hash. This endpoint is useful for obtaining the full schema definition for use in client-side code generation or analysis. ```APIDOC ## GET /api/strapi-typed-client/schema ### Description Returns the complete content type schema as JSON, along with a hash of the schema. ### Method GET ### Endpoint /api/strapi-typed-client/schema ### Response #### Success Response (200) - **hash** (string) - A hash representing the current schema. - **schema** (object) - An object containing the content types and components definitions. ### Response Example ```json { "hash": "a1b2c3d4e5f6...", "schema": { "contentTypes": { "api::post.post": { "kind": "collectionType", "singularName": "post", "pluralName": "posts", "attributes": { "title": { "type": "string", "required": true }, "content": { "type": "richtext" }, "author": { "type": "relation", "relation": "manyToOne", "target": "plugin::users-permissions.user" } } } }, "components": { "landing.hero-block": { "attributes": { "heading": { "type": "string" }, "backgroundImage": { "type": "media" } } } } } } ``` ``` -------------------------------- ### Forwarding Cache Options to Fetch in Next.js Source: https://github.com/boxlab-ltd/strapi-typed-client/blob/main/docs/guide/nextjs.md Demonstrates how cache options are passed to the global fetch function within a Next.js environment. This is how Next.js optimizations are applied. ```typescript fetch(url, { next: { revalidate: options.revalidate, tags: options.tags, }, cache: options.cache, }) ``` -------------------------------- ### Generated Typed Client Methods Source: https://github.com/boxlab-ltd/strapi-typed-client/blob/main/docs/advanced/custom-endpoints.md Example of how the generated client provides typed methods for custom endpoints, offering full autocomplete and type safety for request parameters and response data. ```typescript // Generated — you get full autocomplete const result = await strapi.articles.publish('article-id', { notifySubscribers: true, }) result.publishedAt // string result.url // string const trending = await strapi.articles.trending() trending[0].title // string trending[0].views // number ``` -------------------------------- ### GET /api/strapi-typed-client/schema-watch Source: https://github.com/boxlab-ltd/strapi-typed-client/blob/main/docs/advanced/plugin-config.md Provides a Server-Sent Events (SSE) stream for watch mode. It immediately sends the current schema hash upon connection and automatically reconnects if the Strapi server restarts. ```APIDOC ## GET /api/strapi-typed-client/schema-watch ### Description SSE (Server-Sent Events) stream for watch mode. On connect, immediately sends the current schema hash. When the Strapi server restarts, the connection drops and the client reconnects automatically. ### Method GET ### Endpoint /api/strapi-typed-client/schema-watch ### Response #### Event Stream - **event: connected** - Indicates a successful connection. - **data: {"hash":"a1b2c3d4e5f6..."}** - The current schema hash. ### Event Format Example ``` event: connected data: {"hash":"a1b2c3d4e5f6..."} ``` ``` -------------------------------- ### Enable and Configure Strapi Typed Client Plugin Source: https://github.com/boxlab-ltd/strapi-typed-client/blob/main/docs/advanced/plugin-config.md This snippet shows how to enable the `strapi-typed-client` plugin and configure its `requireAuth` option based on the environment. It's recommended to keep `requireAuth` enabled in production environments. ```typescript export default ({ env }) => ({ // strapi-typed-client plugin — auto-discovered, just enable + configure 'strapi-typed-client': { enabled: true, config: { requireAuth: env('NODE_ENV') === 'production', }, }, // Other plugins upload: { config: { provider: 'aws-s3', }, }, email: { config: { provider: 'sendgrid', }, }, }) ``` -------------------------------- ### Configure Strapi Client with Environment Variables Source: https://github.com/boxlab-ltd/strapi-typed-client/blob/main/docs/advanced/authentication.md Read the Strapi URL and API token from environment variables for secure and flexible configuration. Ensure secret tokens are not exposed client-side. ```typescript const strapi = new StrapiClient({ baseURL: process.env.NEXT_PUBLIC_STRAPI_URL!, token: process.env.STRAPI_TOKEN, }) ``` -------------------------------- ### Generate Strapi Types Source: https://github.com/boxlab-ltd/strapi-typed-client/blob/main/docs/guide/cli.md Connects to your Strapi instance, fetches the schema, and generates TypeScript output files. The `--output` option is required and must point to a directory within your source tree. ```bash npx strapi-types generate --url http://localhost:1337 ``` ```bash npx strapi-types generate --url http://localhost:1337 --output ./src/strapi ``` ```bash npx strapi-types generate --url http://localhost:1337 --token abc123 --output ./src/strapi ``` ```bash npx strapi-types generate --url http://localhost:1337 --output ./src/strapi --force ``` ```bash npx strapi-types generate --output ./src/strapi --format ts ``` -------------------------------- ### Strapi Payload Type (GetPayload) Example Source: https://github.com/boxlab-ltd/strapi-typed-client/blob/main/docs/reference/generated-types.md Utilizes TypeScript generics to resolve the return type based on the populate parameter, enabling type-safe populate inference. Handles wildcard, array, and object populate styles for nested data resolution. ```typescript export type ArticleGetPayload

= Article & (P extends { populate: infer Pop } ? Pop extends '*' | true ? { category?: Category | null cover?: MediaFile tags?: Tag[] blocks?: (Hero | Cta)[] } : Pop extends readonly (infer _)[] ? { category?: 'category' extends Pop[number] ? Category | null : never cover?: 'cover' extends Pop[number] ? MediaFile : never // ... } : { category?: 'category' extends keyof Pop ? /* nested resolve */ Category | null : never // ... } : {}) ``` -------------------------------- ### Wrap Next.js Config with withStrapiTypes Source: https://github.com/boxlab-ltd/strapi-typed-client/blob/main/docs/guide/nextjs.md Wrap your Next.js config with `withStrapiTypes` to enable automatic schema watching and type generation. Configure Strapi URL, token, and output directory. ```typescript import { withStrapiTypes } from 'strapi-typed-client/next' const nextConfig = { // your existing Next.js config } export default withStrapiTypes({ strapiUrl: process.env.NEXT_PUBLIC_STRAPI_URL ?? 'http://localhost:1337', token: process.env.STRAPI_TOKEN, output: './src/strapi', })(nextConfig) ``` -------------------------------- ### Generate Strapi Types with Schema Hashing Source: https://github.com/boxlab-ltd/strapi-typed-client/blob/main/docs/guide/cli.md Run the generate command to fetch the schema hash and regenerate types if the schema has changed. Use the --force flag to regenerate regardless of the hash. ```bash # First run — generates types npx strapi-types generate --url http://localhost:1337 --output ./src/strapi ``` ```bash # Second run — skipped, schema unchanged npx strapi-types generate --url http://localhost:1337 --output ./src/strapi ``` ```bash # Force regeneration regardless of hash npx strapi-types generate --url http://localhost:1337 --output ./src/strapi --force ``` -------------------------------- ### Generate Types with API Token Source: https://github.com/boxlab-ltd/strapi-typed-client/blob/main/docs/guide/getting-started.md Generate types using the CLI, providing the Strapi URL and an API token. Ensure the token is created with 'Read-only' permissions. ```bash npx strapi-types generate --url http://localhost:1337 --token YOUR_TOKEN ``` -------------------------------- ### Configure Environment Variables for CLI Source: https://github.com/boxlab-ltd/strapi-typed-client/blob/main/docs/guide/cli.md Set environment variables like STRAPI_URL and STRAPI_TOKEN to avoid passing flags on every invocation. CLI flags take precedence over environment variables. ```bash # .env STRAPI_URL=http://localhost:1337 STRAPI_TOKEN=your-api-token-here ``` ```bash # Now you can run without flags npx strapi-types generate ``` -------------------------------- ### Enable Strapi Plugin Source: https://github.com/boxlab-ltd/strapi-typed-client/blob/main/README.md Enable the strapi-typed-client plugin in your Strapi project configuration. ```typescript export default { 'strapi-typed-client': { enabled: true, }, } ``` -------------------------------- ### create Source: https://github.com/boxlab-ltd/strapi-typed-client/blob/main/docs/reference/api.md Creates a new entry in a collection. Supports creating with typed input or FormData for file uploads. ```APIDOC ## create ### Description Creates a new entry in a collection. Supports creating with typed input or FormData for file uploads, and Next.js cache options. ### Method ```ts create(data, nextOptions?): Promise ``` ### Parameters #### Request Body - **data** (`TInput | FormData`) - Required - The entry data (typed input or FormData for file uploads) - **nextOptions** (`NextOptions`) - Optional - Next.js cache options ### Returns `Promise` -- the created entry. ### Examples ```ts // Create with typed input const article = await strapi.articles.create({ title: 'New Article', slug: 'new-article', body: 'Article content here.', status: 'draft', category: 5, // relation by ID cover: 12, // media by ID tags: [1, 2, 3], // many relation by IDs }) // Create with FormData (for file uploads in the same request) const formData = new FormData() formData.append('data', JSON.stringify({ title: 'With File' })) formData.append('files.cover', fileBlob, 'cover.jpg') const article = await strapi.articles.create(formData) ``` ``` -------------------------------- ### Initialize and Use StrapiClient Source: https://github.com/boxlab-ltd/strapi-typed-client/blob/main/README.md Initialize the StrapiClient with your Strapi instance's base URL and use it to perform CRUD operations with full TypeScript support. ```typescript import { StrapiClient } from '@/strapi' const strapi = new StrapiClient({ baseURL: 'http://localhost:1337', }) const articles = await strapi.articles.find({ filters: { title: { $contains: 'hello' } }, populate: { category: true, cover: true }, }) articles[0].category.name // fully typed ``` -------------------------------- ### Populate Variable with Client Method Source: https://github.com/boxlab-ltd/strapi-typed-client/blob/main/docs/guide/populate.md Demonstrates how to correctly use a populate object defined with `as const` when passing it to a client method like `strapi.articles.find()`. This ensures type inference works as expected. ```typescript const POPULATE = { category: true, author: true } as const // Type inference works correctly const result = await strapi.articles.find({ populate: POPULATE }) result[0].category.name // ✅ fully typed ``` -------------------------------- ### Fetching Localizations for Articles Source: https://github.com/boxlab-ltd/strapi-typed-client/blob/main/docs/reference/api.md Demonstrates fetching articles in a specific locale ('en') and populating their localizations, selecting only the 'locale' and 'slug' fields for the localizations. ```typescript // Combine with populate to get localizations await strapi.articles.find({ locale: 'en', populate: { localizations: { fields: ['locale', 'slug'] }, }, }) ``` -------------------------------- ### Select Specific Fields Source: https://github.com/boxlab-ltd/strapi-typed-client/blob/main/docs/guide/filtering.md Reduce response size by selecting only the fields you need, such as 'title', 'slug', and 'createdAt'. ```typescript const result = await strapi.articles.find({ fields: ['title', 'slug', 'createdAt'], }) ``` -------------------------------- ### Configure tsconfig.json for Path Aliases Source: https://github.com/boxlab-ltd/strapi-typed-client/blob/main/docs/guide/getting-started.md Add a path alias in your `tsconfig.json` file to easily import generated Strapi types and client from anywhere in your project. ```json // tsconfig.json { "compilerOptions": { "paths": { "@/*": ["./src/*"] } } } ``` -------------------------------- ### Import StrapiClient Source: https://github.com/boxlab-ltd/strapi-typed-client/blob/main/docs/guide/getting-started.md Import the generated `StrapiClient` class into your TypeScript files using the configured path alias. ```typescript import { StrapiClient } from '@/strapi' ``` -------------------------------- ### Create New Article with create() Source: https://github.com/boxlab-ltd/strapi-typed-client/blob/main/docs/guide/client.md Use `create()` to add a new article. The data parameter should conform to the generated input type for writable fields. The method returns the newly created Article object. ```typescript const result = await strapi.articles.create({ title: 'My New Article', content: 'Article body text...', category: 1, // relation as ID }) ```