or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

collections.mdconfiguration.mdindex.mdnavigation-utilities.mdnavigation.mdpreview.mdquerying.mdrendering.mdruntime-utilities.md

collections.mddocs/

0

# Collections

1

2

Type-safe collection definition system with schema validation, custom sources, and flexible content organization. Collections define how content is structured, validated, and accessed.

3

4

## Capabilities

5

6

### Define Collection

7

8

Creates a type-safe collection definition with schema validation and configuration.

9

10

```typescript { .api }

11

/**

12

* Type-safe collection definition helper

13

* @param collection - Collection configuration object

14

* @returns Defined collection with type safety

15

*/

16

function defineCollection<T>(collection: Collection<T>): DefinedCollection<T>;

17

18

interface Collection<T> {

19

/** Collection type - 'page' for routable content, 'data' for structured data */

20

type: 'page' | 'data';

21

/** Source directory or custom source configuration */

22

source?: string | CustomCollectionSource;

23

/** Zod schema for content validation */

24

schema?: ZodSchema<T>;

25

/** Field definitions for content structure */

26

fields?: CollectionFields<T>;

27

}

28

29

interface DefinedCollection<T> {

30

name: string;

31

type: CollectionType;

32

source: ResolvedSource;

33

schema: ZodSchema<T>;

34

fields: ResolvedFields<T>;

35

}

36

```

37

38

**Usage Examples:**

39

40

```typescript

41

// content.config.ts

42

import { defineCollection, z } from '@nuxt/content/utils';

43

44

export const collections = {

45

// Page collection with routing

46

blog: defineCollection({

47

type: 'page',

48

source: 'content/blog/**/*.md',

49

schema: z.object({

50

title: z.string(),

51

description: z.string(),

52

publishedAt: z.date(),

53

author: z.object({

54

name: z.string(),

55

email: z.string().email(),

56

avatar: z.string().url().optional()

57

}),

58

tags: z.array(z.string()).default([]),

59

featured: z.boolean().default(false),

60

draft: z.boolean().default(false)

61

})

62

}),

63

64

// Data collection without routing

65

authors: defineCollection({

66

type: 'data',

67

source: 'content/data/authors.json',

68

schema: z.object({

69

id: z.string(),

70

name: z.string(),

71

bio: z.string(),

72

social: z.object({

73

twitter: z.string().optional(),

74

github: z.string().optional(),

75

website: z.string().url().optional()

76

}).optional()

77

})

78

}),

79

80

// Collection with custom source

81

products: defineCollection({

82

type: 'data',

83

source: {

84

driver: 'http',

85

url: 'https://api.example.com/products',

86

headers: {

87

'Authorization': 'Bearer ${PRODUCTS_API_TOKEN}'

88

}

89

},

90

schema: z.object({

91

id: z.number(),

92

name: z.string(),

93

price: z.number(),

94

category: z.string(),

95

inStock: z.boolean()

96

})

97

})

98

};

99

```

100

101

### Define Collection Source

102

103

Creates custom collection source configurations for external data.

104

105

```typescript { .api }

106

/**

107

* Custom collection source definition

108

* @param source - Custom source configuration

109

* @returns Resolved custom collection source

110

*/

111

function defineCollectionSource(

112

source: CustomCollectionSource

113

): ResolvedCustomCollectionSource;

114

115

interface CustomCollectionSource {

116

/** Source driver type */

117

driver: 'http' | 'database' | 'custom';

118

/** Source-specific configuration */

119

[key: string]: unknown;

120

}

121

122

interface HttpCollectionSource extends CustomCollectionSource {

123

driver: 'http';

124

/** API endpoint URL */

125

url: string;

126

/** HTTP headers for requests */

127

headers?: Record<string, string>;

128

/** Request method */

129

method?: 'GET' | 'POST';

130

/** Request body for POST requests */

131

body?: unknown;

132

/** Response transformation function */

133

transform?: (data: unknown) => unknown[];

134

}

135

136

interface DatabaseCollectionSource extends CustomCollectionSource {

137

driver: 'database';

138

/** Database connection string */

139

connectionString: string;

140

/** SQL query to fetch data */

141

query: string;

142

/** Query parameters */

143

params?: Record<string, unknown>;

144

}

145

```

146

147

**Usage Examples:**

148

149

```typescript

150

// HTTP API source

151

const apiSource = defineCollectionSource({

152

driver: 'http',

153

url: 'https://jsonplaceholder.typicode.com/posts',

154

headers: {

155

'User-Agent': 'Nuxt Content Bot'

156

},

157

transform: (data) => {

158

// Transform API response to match schema

159

return data.map(post => ({

160

id: post.id,

161

title: post.title,

162

content: post.body,

163

userId: post.userId

164

}));

165

}

166

});

167

168

// Database source

169

const dbSource = defineCollectionSource({

170

driver: 'database',

171

connectionString: process.env.DATABASE_URL,

172

query: 'SELECT * FROM articles WHERE published = true ORDER BY created_at DESC',

173

params: {}

174

});

175

```

176

177

### Content Configuration

178

179

Defines the complete content configuration with collections and global settings.

180

181

```typescript { .api }

182

/**

183

* Type-safe content configuration definition

184

* @param config - Content configuration object

185

* @returns Validated content configuration

186

*/

187

function defineContentConfig(config: ContentConfig): ContentConfig;

188

189

interface ContentConfig {

190

/** Collection definitions */

191

collections: Record<string, Collection<any>>;

192

/** Global content settings */

193

settings?: ContentSettings;

194

/** Custom transformers */

195

transformers?: ContentTransformer[];

196

}

197

198

interface ContentSettings {

199

/** Default markdown options */

200

markdown?: MarkdownOptions;

201

/** Global field defaults */

202

defaults?: Record<string, unknown>;

203

/** Content validation strictness */

204

strict?: boolean;

205

}

206

```

207

208

**Usage Examples:**

209

210

```typescript

211

// content.config.ts

212

export default defineContentConfig({

213

collections: {

214

blog: defineCollection({

215

type: 'page',

216

schema: z.object({

217

title: z.string(),

218

date: z.date(),

219

content: z.string()

220

})

221

}),

222

223

pages: defineCollection({

224

type: 'page',

225

source: 'content/pages/**/*.md'

226

})

227

},

228

229

settings: {

230

markdown: {

231

anchorLinks: true,

232

codeHighlight: true,

233

toc: { depth: 3 }

234

},

235

defaults: {

236

author: 'Site Admin',

237

publishedAt: new Date()

238

},

239

strict: true

240

},

241

242

transformers: [

243

// Custom content transformer

244

{

245

name: 'reading-time',

246

transform: (content) => {

247

const wordCount = content.body.split(/\s+/).length;

248

const readingTime = Math.ceil(wordCount / 200);

249

return {

250

...content,

251

readingTime: `${readingTime} min read`

252

};

253

}

254

}

255

]

256

});

257

```

258

259

### Load Content Configuration

260

261

Build-time utility for loading and resolving content configuration.

262

263

```typescript { .api }

264

/**

265

* Loads and resolves content configuration at build time

266

* @param nuxt - Nuxt instance

267

* @returns Promise resolving to loaded configuration

268

*/

269

function loadContentConfig(nuxt: Nuxt): Promise<LoadedContentConfig>;

270

271

interface LoadedContentConfig {

272

/** Resolved collection definitions */

273

collections: ResolvedCollection[];

274

/** Resolved global settings */

275

settings: ResolvedContentSettings;

276

/** Loaded transformers */

277

transformers: ContentTransformer[];

278

}

279

280

interface ResolvedCollection {

281

/** Collection name */

282

name: string;

283

/** Collection type */

284

type: CollectionType;

285

/** Resolved source configuration */

286

source: ResolvedSource;

287

/** Compiled schema */

288

schema: CompiledSchema;

289

/** Database table name */

290

table: string;

291

}

292

```

293

294

### Database Table Names

295

296

Utility for generating consistent database table names from collection names.

297

298

```typescript { .api }

299

/**

300

* Generates database table name from collection name

301

* @param name - Collection name

302

* @returns Database table name

303

*/

304

function getTableName(name: string): string;

305

```

306

307

**Usage Examples:**

308

309

```typescript

310

// Generate table names

311

const blogTable = getTableName('blog'); // 'content_blog'

312

const userProfilesTable = getTableName('userProfiles'); // 'content_user_profiles'

313

const apiDataTable = getTableName('api-data'); // 'content_api_data'

314

```

315

316

## Schema Validation

317

318

### Built-in Schemas

319

320

Pre-defined schemas for common content types and metadata.

321

322

```typescript { .api }

323

/** Pre-defined schema for content metadata */

324

const metaSchema: ZodSchema<ContentMeta>;

325

326

/** Pre-defined schema for page-type content */

327

const pageSchema: ZodSchema<PageContent>;

328

329

interface ContentMeta {

330

title?: string;

331

description?: string;

332

image?: string;

333

keywords?: string[];

334

author?: string;

335

publishedAt?: Date;

336

updatedAt?: Date;

337

}

338

339

interface PageContent extends ContentMeta {

340

slug: string;

341

path: string;

342

draft?: boolean;

343

layout?: string;

344

}

345

```

346

347

**Usage Examples:**

348

349

```typescript

350

import { metaSchema, pageSchema, z } from '@nuxt/content/utils';

351

352

// Extend built-in schemas

353

const blogSchema = pageSchema.extend({

354

category: z.string(),

355

tags: z.array(z.string()).default([]),

356

featured: z.boolean().default(false),

357

excerpt: z.string().optional()

358

});

359

360

// Use meta schema for data collections

361

const authorSchema = metaSchema.extend({

362

id: z.string(),

363

bio: z.string(),

364

social: z.object({

365

twitter: z.string().optional(),

366

github: z.string().optional()

367

}).optional()

368

});

369

```

370

371

### Content Transformers

372

373

Define custom content transformers for processing content files during build time.

374

375

```typescript { .api }

376

/**

377

* Defines a custom content transformer

378

* @param transformer - Content transformer configuration

379

* @returns Content transformer for use in collections

380

*/

381

function defineTransformer(transformer: ContentTransformer): ContentTransformer;

382

```

383

384

**Usage Examples:**

385

386

```typescript

387

import { defineTransformer } from '@nuxt/content/utils';

388

389

// Define a custom transformer for processing YAML frontmatter

390

const yamlTransformer = defineTransformer({

391

name: 'yaml-processor',

392

extensions: ['.md', '.mdx'],

393

parse: async (file) => {

394

// Custom parsing logic

395

const processed = await processYamlFrontmatter(file.body);

396

return {

397

...file,

398

body: processed.content,

399

meta: processed.frontmatter

400

};

401

}

402

});

403

404

// Define a transformer that only transforms existing content

405

const linkTransformer = defineTransformer({

406

name: 'link-processor',

407

extensions: ['.md'],

408

transform: async (content) => {

409

// Transform internal links

410

const processedBody = content.body.replace(

411

/\[([^\]]+)\]\(\.\/([^)]+)\)/g,

412

'[$1](/docs/$2)'

413

);

414

return { ...content, body: processedBody };

415

}

416

});

417

```

418

419

## Types

420

421

```typescript { .api }

422

type CollectionType = 'page' | 'data';

423

424

interface PageCollection<T> {

425

type: 'page';

426

schema: ZodSchema<T>;

427

source: string | CustomCollectionSource;

428

routing?: RoutingConfig;

429

}

430

431

interface DataCollection<T> {

432

type: 'data';

433

schema: ZodSchema<T>;

434

source: string | CustomCollectionSource;

435

}

436

437

interface CollectionFields<T> {

438

[K in keyof T]?: FieldDefinition<T[K]>;

439

}

440

441

interface FieldDefinition<T> {

442

type?: string;

443

required?: boolean;

444

default?: T;

445

validate?: (value: T) => boolean | string;

446

}

447

448

interface ContentTransformer {

449

/** Transformer name */

450

name: string;

451

/** File extensions this transformer handles */

452

extensions: string[];

453

/** Parse function for handling file content */

454

parse?(file: ContentFile, options: Record<string, unknown>): Promise<TransformedContent> | TransformedContent;

455

/** Transform function for processing parsed content */

456

transform?(content: TransformedContent, options: Record<string, unknown>): Promise<TransformedContent> | TransformedContent;

457

}

458

459

interface RoutingConfig {

460

/** Dynamic route pattern */

461

pattern?: string;

462

/** Route parameters */

463

params?: Record<string, string>;

464

/** Route middleware */

465

middleware?: string[];

466

}

467

```