Skip to content

StrapiClient Usage

The generated StrapiClient class provides typed methods for every collection in your Strapi instance. This page covers how to create a client, perform CRUD operations, handle authentication, and deal with errors.

Creating a Client

ts
import { StrapiClient } from './dist'

const strapi = new StrapiClient({
    baseURL: 'http://localhost:1337',
})

With Authentication

ts
const strapi = new StrapiClient({
    baseURL: 'http://localhost:1337',
    token: 'your-bearer-token',
})

With a Custom Fetch Function

The client uses the global fetch by default. You can provide a custom implementation for environments where global fetch is not available or when you need special behavior:

ts
import nodeFetch from 'node-fetch'

const strapi = new StrapiClient({
    baseURL: 'http://localhost:1337',
    fetch: nodeFetch as any,
})

Collection API Methods

Every collection type in your Strapi schema gets its own property on the client with the following methods:

MethodDescription
find(params?)Fetch a list of entries
findOne(documentId, params?)Fetch a single entry by document ID
create(data)Create a new entry
update(documentId, data)Update an existing entry
delete(documentId)Delete an entry

CRUD Operations

find()

Retrieve a list of entries with optional filtering, sorting, pagination, and population:

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 },
})

// result.data is Article[]
// result.meta contains pagination info

findOne()

Retrieve a single entry by its document ID:

ts
const result = await strapi.articles.findOne('abc123')

// With populate
const result = await strapi.articles.findOne('abc123', {
    populate: { category: true, author: true },
})

// result.data is Article

create()

Create a new entry. The data parameter uses the generated input type with all writable fields:

ts
const result = await strapi.articles.create({
    data: {
        title: 'My New Article',
        content: 'Article body text...',
        category: 1, // relation as ID
    },
})

// result.data is Article

update()

Update an existing entry. All fields are optional for partial updates:

ts
const result = await strapi.articles.update('abc123', {
    data: {
        title: 'Updated Title',
    },
})

// result.data is Article

delete()

Delete an entry by its document ID:

ts
const result = await strapi.articles.delete('abc123')

Response Format

Strapi wraps all responses in a standard envelope:

ts
// find() returns:
{
  data: Article[],
  meta: {
    pagination: {
      page: number,
      pageSize: number,
      pageCount: number,
      total: number,
    }
  }
}

// findOne(), create(), update() return:
{
  data: Article
}

The client preserves this structure so you always have access to both the data and metadata.

Authentication

Setting a Token at Creation

ts
const strapi = new StrapiClient({
    baseURL: 'http://localhost:1337',
    token: 'your-api-token',
})

Updating the Token at Runtime

Use setToken() to change the authorization token after the client has been created. This is useful for login flows:

ts
const strapi = new StrapiClient({
    baseURL: 'http://localhost:1337',
})

// After user logs in
strapi.setToken(jwt)

// All subsequent requests include the Authorization header
const profile = await strapi.users.findOne(userId)

TIP

The token is sent as a Bearer token in the Authorization header on every request.

Error Handling

The client throws two types of errors:

  • StrapiError — the server responded with a non-OK HTTP status (400, 401, 404, 500, etc.)
  • StrapiConnectionError — the request never reached the server (network down, DNS failure, timeout)
ts
import { StrapiError, StrapiConnectionError } from 'strapi-typed-client'

try {
    const result = await strapi.articles.findOne('nonexistent-id')
} catch (error) {
    if (error instanceof StrapiConnectionError) {
        // Network-level failure — server unreachable, DNS error, timeout
        console.error('Cannot reach Strapi:', error.message)
    } else if (error instanceof StrapiError) {
        // Server responded with an error
        console.error(`HTTP ${error.status}:`, error.userMessage)
    }
}

Error messages include contextual hints for common HTTP codes (401, 403, 404, 500), so even raw error.message is informative.

Request Timeout

Set the timeout option (in milliseconds) to abort requests that take too long:

ts
const strapi = new StrapiClient({
    baseURL: 'http://localhost:1337',
    timeout: 5000, // 5 seconds
})

When a request exceeds the timeout, a StrapiConnectionError is thrown with the message Request timed out after 5000ms.

Common Pattern

A helper that standardizes error handling across your application:

ts
async function safeFind<T>(fn: () => Promise<T>): Promise<T | null> {
    try {
        return await fn()
    } catch (error) {
        console.error('Strapi request failed:', error)
        return null
    }
}

const articles = await safeFind(() => strapi.articles.find())

WARNING

Always handle errors in production code. Network failures, authentication issues, and validation errors from Strapi will all result in thrown exceptions.

Single Types

Single types (like a homepage or global settings) are accessed the same way as collections, but you typically only use find() and update():

ts
// Fetch the homepage single type
const homepage = await strapi.homepage.find({
    populate: { hero: true, seo: true },
})

// Update it
await strapi.homepage.update('documentId', {
    data: { title: 'Welcome' },
})

Released under the MIT License.