or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

configuration.mdcore-operations.mderror-handling.mdindex.mdinterceptors.mdutilities.md

configuration.mddocs/

0

# Configuration and Instance Management

1

2

Create customized fetch instances with default options, base URLs, platform-specific settings, and advanced configuration for different environments and use cases.

3

4

## Capabilities

5

6

### Fetch Instance Creation

7

8

Create customized fetch instances with default options that apply to all requests made with that instance.

9

10

```typescript { .api }

11

/**

12

* Create a customized fetch instance with default options

13

* @param defaults - Default fetch options to merge with each request

14

* @param globalOptions - Global configuration for fetch implementation

15

* @returns New $Fetch instance with configured defaults

16

*/

17

function create(

18

defaults?: FetchOptions,

19

globalOptions?: CreateFetchOptions

20

): $Fetch;

21

22

interface CreateFetchOptions {

23

defaults?: FetchOptions;

24

fetch?: Fetch;

25

Headers?: typeof Headers;

26

AbortController?: typeof AbortController;

27

}

28

```

29

30

**Usage Examples:**

31

32

```typescript

33

import { ofetch } from "ofetch";

34

35

// Basic API client with base URL

36

const api = ofetch.create({

37

baseURL: "https://api.example.com"

38

});

39

40

// Full configuration with authentication and timeouts

41

const authenticatedApi = ofetch.create({

42

baseURL: "https://api.example.com",

43

headers: {

44

"Authorization": "Bearer token123",

45

"Content-Type": "application/json",

46

"User-Agent": "MyApp/1.0"

47

},

48

timeout: 10000,

49

retry: 3,

50

retryDelay: 1000

51

});

52

53

// Environment-specific configuration

54

const api = ofetch.create({

55

baseURL: process.env.API_BASE_URL,

56

headers: {

57

"X-API-Key": process.env.API_KEY

58

}

59

});

60

```

61

62

### Factory Function

63

64

Lower-level factory function for creating fetch instances with custom fetch implementations and global options.

65

66

```typescript { .api }

67

/**

68

* Factory function to create fetch instances with custom implementations

69

* @param globalOptions - Global configuration including custom fetch implementation

70

* @returns New $Fetch instance with specified configuration

71

*/

72

function createFetch(globalOptions?: CreateFetchOptions): $Fetch;

73

```

74

75

**Usage Examples:**

76

77

```typescript

78

import { createFetch } from "ofetch";

79

80

// Custom fetch instance with specific global options

81

const customFetch = createFetch({

82

defaults: {

83

baseURL: "https://internal.api.com",

84

timeout: 5000

85

},

86

fetch: globalThis.fetch,

87

Headers: globalThis.Headers,

88

AbortController: globalThis.AbortController

89

});

90

91

// Use with custom fetch implementation

92

const proxyFetch = createFetch({

93

fetch: (input, init) => {

94

console.log("Proxying request:", input);

95

return globalThis.fetch(input, init);

96

}

97

});

98

```

99

100

### Node.js Specific Configuration

101

102

Node.js optimized fetch creation with keep-alive support and HTTP agent configuration. The main ofetch package automatically detects Node.js environment and uses optimizations, but explicit Node.js configuration is available.

103

104

```typescript { .api }

105

/**

106

* Creates Node.js-specific fetch with conditional keep-alive support

107

* Reads FETCH_KEEP_ALIVE environment variable to enable persistent connections

108

* @returns Fetch function with Node.js optimizations and optional keep-alive

109

*/

110

function createNodeFetch(): typeof globalThis.fetch;

111

```

112

113

**Keep-Alive Support:**

114

115

When `FETCH_KEEP_ALIVE` environment variable is set to `"true"`, Node.js HTTP and HTTPS agents are created with `keepAlive: true` to reuse connections across requests.

116

117

**Usage Examples:**

118

119

```typescript

120

import { createNodeFetch } from "ofetch/node";

121

122

// Enable keep-alive via environment variable

123

process.env.FETCH_KEEP_ALIVE = "true";

124

const fetch = createNodeFetch();

125

126

// Without keep-alive (default behavior)

127

process.env.FETCH_KEEP_ALIVE = "false";

128

const standardFetch = createNodeFetch();

129

130

// Use in custom instance

131

import { createFetch } from "ofetch";

132

const nodeFetch = createFetch({

133

fetch: createNodeFetch(),

134

defaults: { timeout: 10000 }

135

});

136

137

// Automatic Node.js detection (recommended)

138

import { ofetch } from "ofetch"; // Uses Node.js optimizations automatically in Node.js

139

const data = await ofetch("https://api.example.com/data");

140

```

141

142

### Request Options Configuration

143

144

Comprehensive options for configuring individual requests and default behaviors.

145

146

```typescript { .api }

147

interface FetchOptions<R extends ResponseType = ResponseType, T = any>

148

extends Omit<RequestInit, "body">, FetchHooks<T, R> {

149

// URL Configuration

150

baseURL?: string;

151

query?: Record<string, any>;

152

params?: Record<string, any>; // Alias for query

153

154

// Request Body

155

body?: RequestInit["body"] | Record<string, any>;

156

157

// Response Handling

158

responseType?: R;

159

parseResponse?: (responseText: string) => any;

160

ignoreResponseError?: boolean;

161

162

// Timeout and Retry

163

timeout?: number;

164

retry?: number | false;

165

retryDelay?: number | ((context: FetchContext<T, R>) => number);

166

retryStatusCodes?: number[];

167

168

// Streaming

169

duplex?: "half" | undefined;

170

171

// Node.js Specific (>= 18)

172

dispatcher?: InstanceType<typeof import("undici").Dispatcher>;

173

174

// Node.js Specific (< 18)

175

agent?: unknown;

176

}

177

```

178

179

**Usage Examples:**

180

181

```typescript

182

import { ofetch } from "ofetch";

183

184

// URL and query configuration

185

const data = await ofetch("https://api.example.com/search", {

186

baseURL: "https://api.example.com", // Would result in https://api.example.com/search

187

query: { q: "typescript", limit: 10 }

188

});

189

190

// Response configuration

191

const text = await ofetch("https://api.example.com/document", {

192

responseType: "text",

193

parseResponse: (text) => text.toUpperCase()

194

});

195

196

// Timeout and retry configuration

197

const data = await ofetch("https://unreliable-api.com/data", {

198

timeout: 5000,

199

retry: 3,

200

retryDelay: (context) => Math.min(1000 * Math.pow(2, context.options.retry || 0), 10000),

201

retryStatusCodes: [408, 429, 500, 502, 503, 504]

202

});

203

204

// Error handling configuration

205

const response = await ofetch("https://api.example.com/might-fail", {

206

ignoreResponseError: true // Won't throw on 4xx/5xx status codes

207

});

208

```

209

210

### Headers Configuration

211

212

Configure request headers with proper merging and override behavior.

213

214

```typescript { .api }

215

interface ResolvedFetchOptions<R extends ResponseType = ResponseType, T = any>

216

extends FetchOptions<R, T> {

217

headers: Headers;

218

}

219

```

220

221

**Usage Examples:**

222

223

```typescript

224

import { ofetch } from "ofetch";

225

226

// Static headers

227

const api = ofetch.create({

228

headers: {

229

"Authorization": "Bearer token",

230

"Content-Type": "application/json"

231

}

232

});

233

234

// Dynamic headers

235

const api = ofetch.create({

236

async onRequest({ options }) {

237

const token = await getAuthToken();

238

options.headers.set("Authorization", `Bearer ${token}`);

239

}

240

});

241

242

// Per-request header override

243

const data = await api("/admin/users", {

244

headers: {

245

"X-Admin": "true" // Adds to existing headers

246

}

247

});

248

```

249

250

### Conditional Exports and Environment Detection

251

252

ofetch uses conditional exports to automatically provide the best implementation for each environment:

253

254

- **Browser/Universal**: Uses `globalThis.fetch` with polyfill fallback

255

- **Node.js**: Automatically uses `node-fetch-native` with conditional keep-alive support

256

- **Edge Runtime/Workers**: Uses native `globalThis.fetch`

257

258

**Package Exports Structure:**

259

260

```json

261

{

262

"exports": {

263

".": {

264

"node": "./dist/node.mjs",

265

"import": "./dist/index.mjs",

266

"require": "./dist/node.cjs"

267

},

268

"./node": {

269

"import": "./dist/node.mjs",

270

"require": "./dist/node.cjs"

271

}

272

}

273

}

274

```

275

276

### Advanced Node.js Configuration

277

278

Advanced Node.js specific configuration including HTTP agents, proxies, and custom dispatchers.

279

280

**Usage Examples:**

281

282

```typescript

283

// HTTP Agent configuration (Node.js < 18)

284

import { HttpsProxyAgent } from "https-proxy-agent";

285

import { ofetch } from "ofetch";

286

287

const data = await ofetch("https://api.example.com/data", {

288

agent: new HttpsProxyAgent("http://proxy.example.com:8080")

289

});

290

291

// Undici Dispatcher (Node.js >= 18)

292

import { ProxyAgent } from "undici";

293

import { ofetch } from "ofetch";

294

295

const proxyAgent = new ProxyAgent("http://proxy.example.com:8080");

296

const data = await ofetch("https://api.example.com/data", {

297

dispatcher: proxyAgent

298

});

299

300

// Keep-alive configuration

301

process.env.FETCH_KEEP_ALIVE = "true";

302

import { ofetch } from "ofetch/node";

303

// All requests will use keep-alive connections

304

```

305

306

## Global Configuration Types

307

308

```typescript { .api }

309

interface CreateFetchOptions {

310

defaults?: FetchOptions;

311

fetch?: Fetch;

312

Headers?: typeof Headers;

313

AbortController?: typeof AbortController;

314

}

315

316

type GlobalOptions = Pick<FetchOptions, "timeout" | "retry" | "retryDelay">;

317

```