### 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 (
{articles.map(article => (
-
{article.title}
{article.category.name}
))}
)
}
```
--------------------------------
### 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
})
```