Packages
ash_typescript
0.13.2
0.17.3
0.17.2
0.17.1
0.17.0
0.16.0
0.15.3
0.15.2
retired
0.15.1
retired
0.15.0
0.14.4
0.14.3
0.14.2
0.14.1
0.14.0
retired
0.13.2
0.13.1
0.13.0
0.12.1
0.12.0
0.11.6
0.11.5
0.11.4
0.11.3
0.11.2
0.11.1
0.11.0
0.10.2
0.10.1
0.10.0
0.9.1
0.9.0
0.8.4
0.8.3
0.8.2
0.8.1
0.8.0
0.7.1
0.7.0
0.6.4
0.6.3
0.6.2
0.6.1
0.6.0
0.5.0
0.4.0
0.3.3
0.3.2
0.3.1
0.2.0
0.1.2
0.1.0
Generate type-safe TypeScript clients directly from your Ash resources and actions, ensuring end-to-end type safety between your backend and frontend.
Current section
Files
Jump to
Current section
Files
documentation/advanced/custom-fetch.md
<!--
SPDX-FileCopyrightText: 2025 Torkild G. Kjevik
SPDX-FileCopyrightText: 2025 ash_typescript contributors <https://github.com/ash-project/ash_typescript/graphs/contributors>
SPDX-License-Identifier: MIT
-->
# Custom Fetch Functions
AshTypescript uses the standard Fetch API by default. You can customize requests using `fetchOptions` or replace the fetch implementation entirely with `customFetch`.
## Using fetchOptions
For simple customization like timeouts or cache control, use the `fetchOptions` parameter:
```typescript
import { listTodos } from './ash_rpc';
// Add timeout and cache control
const todos = await listTodos({
fields: ["id", "title"],
fetchOptions: {
signal: AbortSignal.timeout(5000),
cache: 'no-cache',
credentials: 'include'
}
});
// Cancellable request
const controller = new AbortController();
const todosPromise = listTodos({
fields: ["id", "title"],
fetchOptions: {
signal: controller.signal
}
});
controller.abort(); // Cancel the request
```
See the [MDN Fetch API documentation](https://developer.mozilla.org/en-US/docs/Web/API/fetch#options) for all available options.
## Custom Fetch Functions
Use `customFetch` when:
- Your JS framework provides a custom fetch function you need to use
- You want to use axios or another HTTP client instead of fetch
### Framework-Provided Fetch
Some frameworks provide their own fetch function with built-in features. Pass it directly:
```typescript
import { frameworkFetch } from 'your-framework';
import { listTodos } from './ash_rpc';
const todos = await listTodos({
fields: ["id", "title"],
customFetch: frameworkFetch
});
```
### Using Axios
Create an adapter that wraps axios to match the fetch interface:
```typescript
import axios from 'axios';
import { listTodos } from './ash_rpc';
const axiosAdapter = async (input: RequestInfo | URL, init?: RequestInit): Promise<Response> => {
const url = typeof input === 'string' ? input : input.toString();
try {
const response = await axios({
url,
method: init?.method || 'GET',
headers: init?.headers as Record<string, string>,
data: init?.body,
validateStatus: () => true
});
return new Response(JSON.stringify(response.data), {
status: response.status,
statusText: response.statusText,
headers: new Headers(response.headers as Record<string, string>)
});
} catch (error: any) {
if (error.response) {
return new Response(JSON.stringify(error.response.data), {
status: error.response.status,
statusText: error.response.statusText
});
}
throw error;
}
};
const todos = await listTodos({
fields: ["id", "title"],
customFetch: axiosAdapter
});
```
## Global Configuration
For settings that apply to all requests (authentication, logging, etc.), use [Lifecycle Hooks](../features/lifecycle-hooks.md) instead of passing `customFetch` to every call.
## Next Steps
- [Lifecycle Hooks](../features/lifecycle-hooks.md) - Global request/response handling
- [Error Handling](../guides/error-handling.md) - Handle errors from RPC calls