Strapi SDK Initialization and Architecture Guide#
1. Overview#
The Strapi Client SDK (@strapi/client) is the official JavaScript/TypeScript client library for interacting with Strapi's Content API. It provides a type-safe, promise-based interface for managing content, files, and authentication.
2. Initialization Process#
2.1 Main Entry Point#
The SDK uses a factory pattern with the strapi() function as the primary initialization method, which internally creates a StrapiClient instance.
TypeScript:
import { strapi } from '@strapi/client';
const client = strapi({
baseURL: 'http://localhost:1337/api',
auth: 'your-api-token-here',
headers: {
'X-Custom-Header': 'value'
}
});
JavaScript:
const { strapi } = require('@strapi/client');
const client = strapi({
baseURL: 'http://localhost:1337/api'
});
Browser (UMD):
<script src="https://cdn.jsdelivr.net/npm/@strapi/client"></script>
<script>
const client = strapi.strapi({ baseURL: 'http://localhost:1337/api' });
</script>
2.2 Advanced Initialization#
For advanced use cases, the StrapiClient class can be instantiated directly:
import { StrapiClient } from '@strapi/client';
const client = new StrapiClient({
baseURL: 'http://example.com/api',
auth: {
strategy: 'api-token',
options: { token: 'test_token' },
},
headers: {
'Accept-Language': 'en-US',
}
});
3. Configuration Options#
3.1 Simple Configuration Interface (Config)#
The strapi() function accepts a Config interface with the following options:
| Parameter | Type | Required | Description |
|---|---|---|---|
baseURL | string | Yes | The base URL of the Strapi Content API (must include protocol) |
auth | string | No | API token for authentication (automatically configured as Bearer token) |
headers | Record<string, string> | No | Custom headers included with every request |
3.2 Advanced Configuration Interface (StrapiClientConfig)#
The StrapiClient class uses a more detailed StrapiClientConfig interface:
interface StrapiClientConfig {
baseURL: string;
auth?: AuthConfig;
headers?: Record<string, string>;
}
interface AuthConfig<T = unknown> {
strategy: string;
options?: T;
}
3.3 Configuration Validation#
The SDK validates configuration during initialization using a dedicated StrapiConfigValidator:
- Base URL validation: Must be a valid HTTP/HTTPS URL
- Auth token validation: Must be a non-empty string when provided
- Headers validation: Must be an object with string values
Invalid configurations throw a StrapiInitializationError wrapping the underlying validation error.
4. Internal Architecture#
4.1 Component Overview#
The Strapi SDK architecture consists of three core components that work together:
- HttpClient - Handles HTTP request execution and interceptor management
- AuthManager - Manages authentication lifecycle and provider coordination
- AuthProviderFactory - Creates and registers authentication providers
4.2 HttpClient#
The HttpClient class is the core HTTP client that provides methods for making HTTP requests to Strapi's API.
Key Responsibilities:
- Manages base URL, timeout, and headers for HTTP requests
- Provides HTTP methods (GET, POST, PUT, DELETE) that delegate to the core
requestmethod - Implements request/response interceptor management through
InterceptorManagerMap - Handles request timeout using AbortController
- Applies request and response interceptors to transform requests/responses
- Maps HTTP status codes to specific error classes
Key Methods:
request(path, init): Core method that builds URLs, applies interceptors, handles timeouts, and executes fetchsetBaseURL(url): Updates the base URL with validationcreate(config, inheritInterceptors): Creates a new HttpClient instance, optionally inheriting interceptors
4.3 AuthManager#
The AuthManager class manages authentication by coordinating different authentication providers and strategies.
Key Responsibilities:
- Holds reference to AuthProviderFactory for creating providers
- Maintains current authentication provider and authentication state
- Registers default authentication providers (API Token, Users Permissions) during initialization
- Provides strategy selection and configuration
- Performs authentication via current provider
- Injects authentication headers into HTTP requests
- Handles unauthorized errors by resetting authentication state
Key Methods:
setStrategy(strategy, options): Creates and sets an auth provider using the factoryauthenticate(http): Creates an interceptor-free HTTP client and calls the provider's authenticate method, updating authentication state based on success/failureauthenticateRequest(request): Iterates through provider headers and sets them on the request
4.4 AuthProviderFactory#
The AuthProviderFactory class is a factory responsible for creating and managing authentication providers.
Key Responsibilities:
- Maintains a registry (Map) of strategy names to creator functions
- Allows registration of new authentication strategies with type-safe creator functions
- Creates AuthProvider instances based on strategy name and options
- Provides extensibility for custom authentication strategies
Key Methods:
register(strategy, creator): Stores the creator function in the registry with the strategy name as key, returns itself for chainingcreate(authStrategy, options): Looks up the creator function, throws error if not found, otherwise invokes it with options
4.5 Component Interaction Flow#
Initialization Flow:
- StrapiClient creates instances of AuthManager and HttpClient
- AuthManager creates an AuthProviderFactory and registers default providers
- If auth config is provided, AuthManager uses the factory to create a provider
Request Interception Flow:
- Auth interceptors are registered on HttpClient's request interceptors
ensurePreAuthenticationinterceptor checks if authentication is needed and calls AuthManager.authenticate()- AuthManager.authenticate() creates an interceptor-free HttpClient clone to avoid infinite loops
authenticateRequestsinterceptor calls AuthManager.authenticateRequest() which injects headers from the current provider
Response Interception Flow:
notifyOnUnauthorizedResponseinterceptor detects 401 errors- Calls AuthManager.handleUnauthorizedError() to reset authentication state
5. Authentication Strategies#
5.1 Supported Strategies#
The Strapi SDK supports two built-in authentication strategies:
API Token Authentication#
- Identifier:
api-token - Provider Class:
ApiTokenAuthProvider - Use Case: Server-side API authentication using Strapi API tokens
- Authentication Method: No authentication step required - token is used directly in headers
- Header Format:
Authorization: Bearer <token>
Users & Permissions Authentication#
- Identifier:
users-permissions - Provider Class:
UsersPermissionsAuthProvider - Use Case: User authentication through the Users & Permissions plugin
- Status: Experimental for MVP
- Authentication Method: POSTs credentials to
/auth/localendpoint to obtain JWT token - Header Format:
Authorization: Bearer <jwt>
5.2 Authentication Provider Interface#
All authentication providers implement the AuthProvider interface and extend AbstractAuthProvider:
interface AuthProvider {
name: string;
headers: Record<string, string>;
authenticate(httpClient: HttpClient): Promise<void>;
preflightValidation(): void;
}
5.3 Configuration Options#
API Token Strategy#
Configuration Interface: ApiTokenAuthProviderOptions
| Option | Type | Required | Description |
|---|---|---|---|
token | string | Yes | The Strapi API token (must be non-empty) |
Usage Example (TypeScript):
// Simplified API
const client = strapi({
baseURL: 'http://localhost:1337/api',
auth: 'your-api-token-here'
});
// Advanced API
const client = new StrapiClient({
baseURL: 'http://localhost:1337/api',
auth: {
strategy: 'api-token',
options: { token: 'your-api-token-here' }
}
});
Usage Example (JavaScript):
const client = strapi({
baseURL: 'http://localhost:1337/api',
auth: 'your-api-token-here'
});
Users & Permissions Strategy#
Configuration Interface: UsersPermissionsAuthProviderOptions
| Option | Type | Required | Description |
|---|---|---|---|
identifier | string | Yes | The unique user identifier (email or username) |
password | string | Yes | The user's password |
Usage Example (TypeScript):
const client = new StrapiClient({
baseURL: 'http://localhost:1337/api',
auth: {
strategy: 'users-permissions',
options: {
identifier: 'user@example.com',
password: 'password123'
}
}
});
// Make authenticated requests
const articles = await client.collection('articles').find();
Usage Example (JavaScript):
const client = new StrapiClient({
baseURL: 'http://localhost:1337/api',
auth: {
strategy: 'users-permissions',
options: {
identifier: 'user@example.com',
password: 'password123'
}
}
});
5.4 Default Provider Registration#
The AuthManager automatically registers both default providers during initialization:
this._authProviderFactory
.register(
ApiTokenAuthProvider.identifier,
(options: ApiTokenAuthProviderOptions) => new ApiTokenAuthProvider(options)
)
.register(
UsersPermissionsAuthProvider.identifier,
(options: UsersPermissionsAuthProviderOptions) => new UsersPermissionsAuthProvider(options)
);
6. Usage Examples#
6.1 Basic Initialization Examples#
TypeScript with API Token:
import { strapi } from '@strapi/client';
const client = strapi({
baseURL: 'http://localhost:1337/api',
auth: 'your-api-token-here'
});
// Fetch content
const articles = await client.collection('articles').find();
JavaScript with API Token:
const { strapi } = require('@strapi/client');
const client = strapi({
baseURL: 'http://localhost:1337/api',
auth: 'your-api-token-here'
});
client.collection('articles').find()
.then(articles => console.log(articles))
.catch(error => console.error(error));
TypeScript with Custom Headers:
const client = strapi({
baseURL: 'http://localhost:1337/api',
auth: 'your-api-token-here',
headers: {
'X-Custom-Header': 'value',
'Accept-Language': 'en-US',
},
});
6.2 Advanced Authentication Examples#
Users & Permissions Authentication:
import { StrapiClient } from '@strapi/client';
const client = new StrapiClient({
baseURL: 'http://localhost:1337/api',
auth: {
strategy: 'users-permissions',
options: {
identifier: 'user@example.com',
password: 'securePassword123'
}
}
});
// The client will automatically authenticate before the first request
const userProfile = await client.collection('users-permissions/users').findOne('me');
Manual JWT Token Usage:
// Obtain JWT token manually
const response = await fetch('http://localhost:1337/api/auth/local', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
identifier: 'user@example.com',
password: 'password123'
})
});
const { jwt } = await response.json();
// Use JWT token with client
const client = strapi({
baseURL: 'http://localhost:1337/api',
auth: jwt
});
6.3 Error Handling#
import { strapi } from '@strapi/client';
try {
const client = strapi({
baseURL: 'invalid-url', // Invalid URL format
auth: 'token'
});
} catch (error) {
if (error.name === 'StrapiInitializationError') {
console.error('Failed to initialize client:', error.message);
}
}
// Runtime error handling
try {
const articles = await client.collection('articles').findOne('invalid-id');
} catch (error) {
if (error.name === 'HTTPError') {
console.error('Request failed:', error.status, error.message);
}
}
7. Summary#
The Strapi SDK provides a robust initialization system with:
- Simple factory function (
strapi()) for basic use cases - Advanced configuration through direct
StrapiClientinstantiation - Flexible authentication with pluggable strategy system
- Type-safe configuration with TypeScript interfaces
- Comprehensive validation of initialization parameters
The internal architecture uses:
HttpClientfor HTTP request managementAuthManagerfor authentication lifecycle coordinationAuthProviderFactoryfor provider registration and creation
Supported authentication strategies include:
api-tokenfor server-side API accessusers-permissionsfor user credential authentication (experimental)