or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

configuration.mdindex.mdlink-scanning.md
tile.json

configuration.mddocs/

0

# Configuration

1

2

Configuration system supporting both programmatic options and file-based configuration with CLI flag precedence. Enables flexible setup for various scanning scenarios from simple one-off checks to complex CI/CD integrations.

3

4

## Capabilities

5

6

### Configuration Loading

7

8

Load and merge configuration from files with CLI flag override capabilities.

9

10

```typescript { .api }

11

/**

12

* Load configuration from files and merge with CLI flags

13

* @param flags - CLI flags and options to merge with file-based config

14

* @returns Promise resolving to merged configuration

15

*/

16

function getConfig(flags: Flags): Promise<Flags>;

17

```

18

19

**Usage Examples:**

20

21

```typescript

22

import { getConfig } from "linkinator";

23

24

// Load config with CLI flags taking precedence

25

const config = await getConfig({

26

concurrency: 50,

27

retry: true,

28

config: "./custom-linkinator.config.js"

29

});

30

31

// Use in scanning

32

const result = await check({

33

path: "https://example.com",

34

...config

35

});

36

```

37

38

### Check Options

39

40

Comprehensive configuration interface for controlling all aspects of link checking behavior.

41

42

```typescript { .api }

43

interface CheckOptions {

44

/** Number of simultaneous connections (default: 100) */

45

concurrency?: number;

46

/** Port for local server when scanning files */

47

port?: number;

48

/** URLs or file paths to check */

49

path: string | string[];

50

/** Recursively follow links on same root domain */

51

recurse?: boolean;

52

/** Request timeout in milliseconds */

53

timeout?: number;

54

/** Automatically parse and scan markdown files */

55

markdown?: boolean;

56

/** Links to skip - regex patterns or function */

57

linksToSkip?: string[] | ((link: string) => Promise<boolean>);

58

/** Root directory for local static server */

59

serverRoot?: string;

60

/** Enable directory index when linking to directories */

61

directoryListing?: boolean;

62

/** Automatically retry HTTP 429 responses with retry-after header */

63

retry?: boolean;

64

/** Automatically retry 5xx and network errors */

65

retryErrors?: boolean;

66

/** Maximum retry attempts for errors (default: 5) */

67

retryErrorsCount?: number;

68

/** Random jitter applied to error retry in milliseconds (default: 3000) */

69

retryErrorsJitter?: number;

70

/** URL rewrite patterns for transforming URLs before checking */

71

urlRewriteExpressions?: UrlRewriteExpression[];

72

/** Custom user agent string for HTTP requests (defaults to DEFAULT_USER_AGENT) */

73

userAgent?: string;

74

}

75

```

76

77

**Usage Examples:**

78

79

```typescript

80

import { check } from "linkinator";

81

82

// Basic local file scanning

83

const basicConfig = {

84

path: "./docs/",

85

markdown: true,

86

recurse: true,

87

};

88

89

// Advanced configuration with retries and filtering

90

const advancedConfig = {

91

path: ["https://example.com", "https://api.example.com"],

92

concurrency: 25,

93

timeout: 15000,

94

retry: true,

95

retryErrors: true,

96

retryErrorsCount: 3,

97

retryErrorsJitter: 5000,

98

linksToSkip: [

99

"mailto:.*",

100

"tel:.*",

101

".*\\.pdf$"

102

],

103

userAgent: "Custom Bot 1.0" // or use DEFAULT_USER_AGENT

104

};

105

106

// URL rewriting for development/staging environments

107

const rewriteConfig = {

108

path: "https://example.com",

109

urlRewriteExpressions: [

110

{

111

pattern: /https:\/\/production\.example\.com/g,

112

replacement: "https://staging.example.com"

113

}

114

]

115

};

116

117

const result = await check(advancedConfig);

118

```

119

120

### CLI Configuration Flags

121

122

Configuration flags available for command-line usage and config files.

123

124

```typescript { .api }

125

interface Flags {

126

/** Number of simultaneous connections */

127

concurrency?: number;

128

/** Path to configuration file */

129

config?: string;

130

/** Enable recursive crawling */

131

recurse?: boolean;

132

/** Links to skip (regex patterns) */

133

skip?: string | string[];

134

/** Output format (JSON, CSV, TEXT) */

135

format?: string;

136

/** Silent mode - suppress output */

137

silent?: boolean;

138

/** Log verbosity level (debug, info, warning, error, none) */

139

verbosity?: string;

140

/** Request timeout in milliseconds */

141

timeout?: number;

142

/** Enable markdown parsing */

143

markdown?: boolean;

144

/** Static server root directory */

145

serverRoot?: string;

146

/** Enable directory listings */

147

directoryListing?: boolean;

148

/** Enable retry on HTTP 429 */

149

retry?: boolean;

150

/** Enable retry on errors */

151

retryErrors?: boolean;

152

/** Maximum retry count */

153

retryErrorsCount?: number;

154

/** Retry jitter in milliseconds */

155

retryErrorsJitter?: number;

156

/** URL rewrite search pattern */

157

urlRewriteSearch?: string;

158

/** URL rewrite replacement string */

159

urlRewriteReplace?: string;

160

}

161

```

162

163

### URL Rewriting

164

165

Transform URLs before checking them, useful for testing staging environments or handling redirects.

166

167

```typescript { .api }

168

interface UrlRewriteExpression {

169

/** Regular expression pattern to match in URLs */

170

pattern: RegExp;

171

/** Replacement string for matched patterns */

172

replacement: string;

173

}

174

```

175

176

**Usage Examples:**

177

178

```typescript

179

import { check } from "linkinator";

180

181

// Rewrite production URLs to staging for testing

182

const result = await check({

183

path: "https://example.com/docs/",

184

recurse: true,

185

urlRewriteExpressions: [

186

{

187

pattern: /https:\/\/cdn\.example\.com/g,

188

replacement: "https://staging-cdn.example.com"

189

},

190

{

191

pattern: /https:\/\/api\.example\.com/g,

192

replacement: "https://staging-api.example.com"

193

}

194

]

195

});

196

```

197

198

### Link Filtering

199

200

Control which links are checked using regex patterns or custom functions.

201

202

**Usage Examples:**

203

204

```typescript

205

import { check } from "linkinator";

206

207

// Skip common non-checkable links using regex patterns

208

const regexSkipResult = await check({

209

path: "https://example.com",

210

linksToSkip: [

211

"mailto:.*", // Skip email links

212

"tel:.*", // Skip phone links

213

".*\\.pdf$", // Skip PDF files

214

".*linkedin\\.com.*", // Skip LinkedIn

215

"#.*" // Skip fragment-only links

216

]

217

});

218

219

// Custom function-based filtering

220

const customSkipResult = await check({

221

path: "https://example.com",

222

linksToSkip: async (url) => {

223

// Skip URLs containing sensitive paths

224

if (url.includes('/admin') || url.includes('/private')) {

225

return true;

226

}

227

// Skip external URLs in test environment

228

if (process.env.NODE_ENV === 'test' && !url.includes('example.com')) {

229

return true;

230

}

231

return false;

232

}

233

});

234

```

235

236

## Configuration Files

237

238

Linkinator supports multiple configuration file formats that can be automatically discovered or explicitly specified:

239

240

**JSON Configuration (`linkinator.config.json`):**

241

242

```json

243

{

244

"concurrency": 50,

245

"recurse": true,

246

"retry": true,

247

"retryErrors": true,

248

"retryErrorsCount": 3,

249

"timeout": 10000,

250

"skip": ["mailto:.*", "tel:.*"],

251

"verbosity": "warning"

252

}

253

```

254

255

**JavaScript Configuration (`linkinator.config.js`):**

256

257

```javascript

258

module.exports = {

259

concurrency: 50,

260

recurse: true,

261

retry: true,

262

linksToSkip: async (url) => {

263

return url.includes('private') || url.includes('admin');

264

},

265

timeout: 10000

266

};

267

```

268

269

**ES Module Configuration (`linkinator.config.mjs`):**

270

271

```javascript

272

export default {

273

concurrency: 50,

274

recurse: true,

275

retry: true,

276

timeout: 10000,

277

urlRewriteSearch: "https://production.example.com",

278

urlRewriteReplace: "https://staging.example.com"

279

};

280

```

281

282

## Internal Types

283

284

### Logging and Output

285

286

```typescript { .api }

287

enum LogLevel {

288

DEBUG = 0,

289

INFO = 1,

290

WARNING = 2,

291

ERROR = 3,

292

NONE = 4,

293

}

294

295

enum Format {

296

TEXT = 0,

297

JSON = 1,

298

CSV = 2,

299

}

300

301

class Logger {

302

constructor(level: LogLevel, format: Format);

303

debug(message?: string): void;

304

info(message?: string): void;

305

warn(message?: string): void;

306

error(message?: string): void;

307

}

308

```

309

310

### Queue and Processing

311

312

```typescript { .api }

313

interface QueueOptions {

314

/** Number of simultaneous operations to allow */

315

concurrency: number;

316

}

317

318

interface QueueItemOptions {

319

/** Delay in milliseconds before executing the queued item */

320

delay?: number;

321

}

322

323

type AsyncFunction = () => Promise<void>;

324

325

class Queue extends EventEmitter {

326

constructor(options: QueueOptions);

327

add(fn: AsyncFunction, options?: QueueItemOptions): void;

328

onIdle(): Promise<void>;

329

on(event: 'done', listener: () => void): this;

330

}

331

```

332

333

### Static Web Server

334

335

```typescript { .api }

336

interface WebServerOptions {

337

/** Local path to mount as static web server root */

338

root: string;

339

/** Port for the local web server */

340

port?: number;

341

/** Whether to automatically compile and serve markdown */

342

markdown?: boolean;

343

/** Whether directories should automatically serve index pages */

344

directoryListing?: boolean;

345

}

346

```