> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/unjs/ofetch/llms.txt
> Use this file to discover all available pages before exploring further.

# ofetch.create()

> Create custom fetch instances with shared configuration and default options

## Overview

`ofetch.create()` allows you to create new fetch instances with pre-configured options that are shared across all requests. This is useful for setting up API clients with common settings like base URLs, headers, and interceptors.

## Basic Usage

```typescript theme={null}
const apiFetch = ofetch.create({ baseURL: '/api' })

apiFetch('/test') // Same as ofetch('/test', { baseURL: '/api' })
```

## Common Use Cases

### API Client with Base URL

Create a dedicated fetch instance for your API:

```typescript theme={null}
const apiFetch = ofetch.create({
  baseURL: 'https://api.example.com',
  headers: {
    'Authorization': 'Bearer token123',
    'Content-Type': 'application/json'
  }
})

// All requests use the base URL and headers
const users = await apiFetch('/users')
const posts = await apiFetch('/posts')
```

### Authenticated Requests

Set up authentication headers globally:

```typescript theme={null}
const authenticatedFetch = ofetch.create({
  baseURL: '/api',
  async onRequest({ options }) {
    const token = await getAuthToken()
    options.headers.set('Authorization', `Bearer ${token}`)
  }
})

await authenticatedFetch('/protected/resource')
```

### Multiple API Clients

Create separate instances for different services:

```typescript theme={null}
const githubAPI = ofetch.create({
  baseURL: 'https://api.github.com',
  headers: {
    'Accept': 'application/vnd.github.v3+json'
  }
})

const internalAPI = ofetch.create({
  baseURL: 'https://internal.company.com/api',
  retry: 3,
  timeout: 5000
})

const repos = await githubAPI('/users/unjs/repos')
const data = await internalAPI('/internal/data')
```

## How It Works

From `src/fetch.ts:268-277`:

```typescript theme={null}
$fetch.create = (defaultOptions = {}, customGlobalOptions = {}) =>
  createFetch({
    ...globalOptions,
    ...customGlobalOptions,
    defaults: {
      ...globalOptions.defaults,
      ...customGlobalOptions.defaults,
      ...defaultOptions,
    },
  });
```

The `create` method:

1. Merges global options with custom global options
2. Combines all default options into a single defaults object
3. Returns a new `$Fetch` instance with the merged configuration

## Options Inheritance

<Note>
  Defaults will be cloned at one level and inherited. Be careful about nested options like `headers`.
</Note>

Options are merged shallowly. For nested options like headers, the entire object is replaced:

```typescript theme={null}
const base = ofetch.create({
  headers: { 'X-Custom': 'base' }
})

// This replaces headers entirely, not merges
const response = await base('/endpoint', {
  headers: { 'Authorization': 'Bearer token' }
})
// Only Authorization header is sent, X-Custom is lost
```

To preserve base headers, use interceptors:

```typescript theme={null}
const base = ofetch.create({
  headers: { 'X-Custom': 'base' },
  async onRequest({ options }) {
    // Add additional headers without replacing
    options.headers.set('Authorization', 'Bearer token')
  }
})
```

## Advanced Example: Retry Configuration

```typescript theme={null}
const resilientFetch = ofetch.create({
  retry: 3,
  retryDelay: 1000,
  retryStatusCodes: [408, 429, 500, 502, 503, 504],
  async onRequestError({ error }) {
    console.error('Request failed:', error)
  },
  async onResponseError({ response }) {
    console.error('Response error:', response.status)
  }
})

await resilientFetch('/flaky-endpoint')
```

## Custom Global Options

You can pass custom global options as the second parameter:

```typescript theme={null}
const customFetch = ofetch.create(
  { baseURL: '/api' },
  { fetch: customFetchImplementation }
)
```

This allows you to:

* Provide a custom fetch implementation
* Override the global fetch function
* Configure fetch-level defaults

## TypeScript Support

The created instance maintains full type safety:

```typescript theme={null}
interface User {
  id: number
  name: string
}

const api = ofetch.create({ baseURL: '/api' })

const user = await api<User>('/users/1')
// user is typed as User
console.log(user.name)
```
