> ## 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.

# Base URL

> Configure a base URL for all requests with smart trailing/leading slash handling

The `baseURL` option allows you to set a base path for all requests, making it easy to work with APIs without repeating the full URL.

## Basic Usage

<CodeGroup>
  ```typescript With baseURL theme={null}
  import { ofetch } from 'ofetch'

  const data = await ofetch('/users', {
    baseURL: 'https://api.example.com'
  })
  // Request: https://api.example.com/users
  ```

  ```typescript Before (native fetch) theme={null}
  // Without baseURL
  const API_BASE = 'https://api.example.com'
  const data = await fetch(`${API_BASE}/users`)
  ```
</CodeGroup>

## Smart Slash Handling

ofetch intelligently handles trailing and leading slashes, so you don't have to worry about double slashes or missing separators:

```typescript theme={null}
// All of these work correctly
await ofetch('/users', { baseURL: 'https://api.example.com' })
await ofetch('/users', { baseURL: 'https://api.example.com/' })
await ofetch('users', { baseURL: 'https://api.example.com' })
await ofetch('users', { baseURL: 'https://api.example.com/' })

// All result in: https://api.example.com/users
```

## Creating a Configured Instance

The most common pattern is to create a configured instance with `$fetch.create()`:

```typescript theme={null}
import { ofetch } from 'ofetch'

const api = ofetch.create({
  baseURL: 'https://api.example.com',
  headers: {
    'Authorization': 'Bearer token123'
  }
})

// Now all requests use the baseURL
await api('/users')          // https://api.example.com/users
await api('/posts')          // https://api.example.com/posts
await api('/comments/123')   // https://api.example.com/comments/123
```

## Nested Paths

baseURL works with nested API paths:

```typescript theme={null}
const api = ofetch.create({
  baseURL: 'https://api.example.com/v2'
})

await api('/users/123/posts')
// Request: https://api.example.com/v2/users/123/posts
```

## With Query Parameters

baseURL combines seamlessly with query parameters:

```typescript theme={null}
await ofetch('/search', {
  baseURL: 'https://api.example.com',
  query: { q: 'ofetch', page: 1 }
})
// Request: https://api.example.com/search?q=ofetch&page=1
```

## Overriding baseURL

You can override the baseURL for specific requests by providing a full URL:

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

// This uses the baseURL
await api('/users')
// Request: https://api.example.com/users

// This overrides it (full URL provided)
await api('https://other-api.com/data')
// Request: https://other-api.com/data
```

## Environment-Based Configuration

Common pattern for different environments:

```typescript theme={null}
const api = ofetch.create({
  baseURL: process.env.API_BASE_URL || 'http://localhost:3000'
})

// Development: http://localhost:3000/users
// Production: https://api.example.com/users
```

## Multiple API Clients

Create different clients for different services:

```typescript theme={null}
const usersAPI = ofetch.create({
  baseURL: 'https://users.example.com'
})

const paymentsAPI = ofetch.create({
  baseURL: 'https://payments.example.com'
})

await usersAPI('/profile')      // https://users.example.com/profile
await paymentsAPI('/checkout')  // https://payments.example.com/checkout
```

## Type Definition

From `src/types.ts:25`:

```typescript theme={null}
baseURL?: string
```

## Implementation Details

The baseURL logic is handled at `src/fetch.ts:114-117` using the `withBase` function from `src/utils.url.ts:40-51`:

* If the request already starts with the baseURL, it's returned as-is
* Trailing slashes on baseURL are removed
* The request path is joined with proper slash handling

This prevents issues like:

* Double slashes: `https://api.example.com//users`
* Missing slashes: `https://api.example.comusers`
