or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

compatibility.mdcomponents.mdconfiguration-types.mdcore-types.mdhooks.mdindex.mdmodules.mdruntime-config.mdschema-validation.md

components.mddocs/

0

# Component System

1

2

The component system in @nuxt/schema provides type definitions for Nuxt's component auto-registration and management system, enabling type-safe component discovery, registration, and configuration.

3

4

## Core Component Types

5

6

### Component Interface

7

8

Represents a registered component with its metadata and configuration.

9

10

```typescript { .api }

11

interface Component {

12

pascalName: string

13

kebabName: string

14

export: string

15

filePath: string

16

shortPath: string

17

chunkName: string

18

prefetch: boolean

19

preload: boolean

20

global?: boolean | 'sync'

21

island?: boolean

22

meta?: ComponentMeta

23

mode?: 'client' | 'server' | 'all'

24

priority?: number

25

/** @internal Allow bypassing transforms */

26

_raw?: boolean

27

}

28

```

29

30

### ComponentMeta Interface

31

32

Extensible metadata for components.

33

34

```typescript { .api }

35

interface ComponentMeta {

36

[key: string]: unknown

37

}

38

```

39

40

## Component Directory Configuration

41

42

### ScanDir Interface

43

44

Configuration for component directory scanning.

45

46

```typescript { .api }

47

interface ScanDir {

48

/** Path to directory containing components */

49

path: string

50

/** Pattern to match component files */

51

pattern?: string | string[]

52

/** Patterns to ignore */

53

ignore?: string[]

54

/** Prefix for matched components */

55

prefix?: string

56

/** Global registration mode */

57

global?: boolean | 'sync'

58

/** Island component support */

59

island?: boolean

60

/** Component loading mode */

61

mode?: 'client' | 'server' | 'all'

62

/** Priority for component resolution */

63

priority?: number

64

/** Whether to watch for changes */

65

watch?: boolean

66

/** Extensions to scan */

67

extensions?: string[]

68

/** Path prefix for component names */

69

pathPrefix?: boolean

70

}

71

```

72

73

### ComponentsDir Interface

74

75

Extended component directory configuration.

76

77

```typescript { .api }

78

interface ComponentsDir extends ScanDir {

79

/** Whether this directory is enabled */

80

enabled?: boolean

81

/** Component prefix to apply */

82

prefix?: string

83

/** Override global setting */

84

global?: boolean | 'sync'

85

}

86

```

87

88

### ComponentsOptions Interface

89

90

Complete components system configuration.

91

92

```typescript { .api }

93

interface ComponentsOptions {

94

/** Component directories to scan */

95

dirs: (string | ComponentsDir)[]

96

/** Global components loader */

97

loader?: boolean

98

/** Transform options */

99

transform?: {

100

/** Include patterns */

101

include?: RegExp[]

102

/** Exclude patterns */

103

exclude?: RegExp[]

104

}

105

/** Whether to generate types */

106

types?: boolean

107

}

108

```

109

110

## Component Registration Patterns

111

112

### Basic Component Registration

113

114

```typescript

115

// nuxt.config.ts

116

export default defineNuxtConfig({

117

components: {

118

dirs: [

119

// Default components directory

120

'~/components',

121

122

// Additional directory with prefix

123

{

124

path: '~/components/ui',

125

prefix: 'UI'

126

},

127

128

// Global components

129

{

130

path: '~/components/global',

131

global: true

132

}

133

]

134

}

135

});

136

```

137

138

### Advanced Component Configuration

139

140

```typescript

141

import type { ComponentsOptions } from '@nuxt/schema';

142

143

const componentsConfig: ComponentsOptions = {

144

dirs: [

145

{

146

path: '~/components/base',

147

prefix: 'Base',

148

global: false,

149

watch: true,

150

extensions: ['vue', 'tsx'],

151

pattern: '**/*.{vue,tsx}',

152

ignore: ['**/*.stories.{js,ts}']

153

},

154

155

{

156

path: '~/components/islands',

157

island: true,

158

mode: 'server',

159

priority: 10

160

},

161

162

{

163

path: '~/components/client',

164

mode: 'client',

165

prefix: 'Client',

166

pathPrefix: false

167

}

168

],

169

170

loader: true,

171

types: true,

172

173

transform: {

174

include: [/\.vue$/, /\.tsx?$/],

175

exclude: [/\.test\./]

176

}

177

};

178

```

179

180

## Component Discovery and Registration

181

182

### Programmatic Component Registration

183

184

```typescript

185

import type { Component } from '@nuxt/schema';

186

187

// In a Nuxt module

188

export default defineNuxtModule({

189

setup(options, nuxt) {

190

// Register components programmatically

191

nuxt.hook('components:extend', (components: Component[]) => {

192

components.push({

193

pascalName: 'MyCustomButton',

194

kebabName: 'my-custom-button',

195

export: 'default',

196

filePath: path.resolve(__dirname, './runtime/components/MyButton.vue'),

197

shortPath: 'runtime/components/MyButton.vue',

198

chunkName: 'components/my-custom-button',

199

prefetch: false,

200

preload: false,

201

global: true,

202

mode: 'all',

203

priority: 0

204

});

205

206

// Register component with metadata

207

components.push({

208

pascalName: 'IconButton',

209

kebabName: 'icon-button',

210

export: 'default',

211

filePath: './components/IconButton.vue',

212

shortPath: 'components/IconButton.vue',

213

chunkName: 'components/icon-button',

214

prefetch: true,

215

preload: true,

216

meta: {

217

category: 'ui',

218

version: '1.0.0',

219

props: ['icon', 'size', 'variant']

220

}

221

});

222

});

223

}

224

});

225

```

226

227

### Component Directory Registration

228

229

```typescript

230

// In a Nuxt module or plugin

231

export default defineNuxtModule({

232

setup(options, nuxt) {

233

// Add component directories

234

nuxt.hook('components:dirs', (dirs) => {

235

dirs.push({

236

path: path.resolve(__dirname, './components'),

237

prefix: options.prefix || 'Module',

238

global: options.global || false,

239

watch: nuxt.options.dev,

240

extensions: ['vue', 'ts', 'tsx'],

241

pattern: '**/*.{vue,ts,tsx}',

242

ignore: ['**/*.story.*', '**/*.test.*']

243

});

244

});

245

}

246

});

247

```

248

249

## Component Type Generation

250

251

### Automatic Type Generation

252

253

```typescript

254

// Types are automatically generated for registered components

255

declare module '@vue/runtime-core' {

256

export interface GlobalComponents {

257

// Auto-registered components

258

MyCustomButton: typeof import('~/components/MyCustomButton.vue')['default']

259

UICard: typeof import('~/components/ui/Card.vue')['default']

260

261

// Island components

262

ServerOnlyChart: typeof import('~/components/islands/Chart.vue')['default']

263

}

264

}

265

```

266

267

### Custom Component Types

268

269

```typescript

270

// In a module setup

271

addTypeTemplate({

272

filename: 'components.d.ts',

273

getContents: ({ nuxt }) => {

274

const components = nuxt.apps.default?.components || [];

275

276

return `

277

declare module '@vue/runtime-core' {

278

export interface GlobalComponents {

279

${components.map(c =>

280

`${c.pascalName}: typeof import('${c.filePath}')['${c.export}']`

281

).join('\n ')}

282

}

283

}

284

285

declare module '#components' {

286

${components.map(c =>

287

`export const ${c.pascalName}: typeof import('${c.filePath}')['${c.export}']`

288

).join('\n ')}

289

}

290

`;

291

}

292

});

293

```

294

295

## Component Loading Modes

296

297

### Client-Side Components

298

299

```typescript

300

const clientComponent: Component = {

301

pascalName: 'ClientOnlyWidget',

302

kebabName: 'client-only-widget',

303

export: 'default',

304

filePath: '~/components/ClientWidget.vue',

305

shortPath: 'components/ClientWidget.vue',

306

chunkName: 'components/client-widget',

307

mode: 'client', // Only loaded on client

308

prefetch: false,

309

preload: false

310

};

311

```

312

313

### Server Components

314

315

```typescript

316

const serverComponent: Component = {

317

pascalName: 'ServerChart',

318

kebabName: 'server-chart',

319

export: 'default',

320

filePath: '~/components/islands/Chart.vue',

321

shortPath: 'components/islands/Chart.vue',

322

chunkName: 'components/server-chart',

323

mode: 'server', // Server-side only

324

island: true, // Island component

325

prefetch: false,

326

preload: false

327

};

328

```

329

330

### Island Components

331

332

```typescript

333

// Enable island components in config

334

export default defineNuxtConfig({

335

experimental: {

336

componentIslands: true

337

},

338

339

components: {

340

dirs: [

341

{

342

path: '~/components/islands',

343

island: true,

344

mode: 'server'

345

}

346

]

347

}

348

});

349

350

// Usage in templates

351

// <ServerChart :data="chartData" />

352

```

353

354

## Component Utilities

355

356

### Component Priority and Resolution

357

358

```typescript

359

// Higher priority components override lower priority ones

360

const highPriorityComponent: Component = {

361

pascalName: 'Button',

362

// ... other properties

363

priority: 10 // Higher number = higher priority

364

};

365

366

const defaultComponent: Component = {

367

pascalName: 'Button',

368

// ... other properties

369

priority: 0 // Default priority

370

};

371

```

372

373

### Component Chunking and Performance

374

375

```typescript

376

const optimizedComponent: Component = {

377

pascalName: 'HeavyChart',

378

kebabName: 'heavy-chart',

379

export: 'default',

380

filePath: '~/components/charts/HeavyChart.vue',

381

shortPath: 'components/charts/HeavyChart.vue',

382

chunkName: 'components/heavy-chart',

383

prefetch: true, // Prefetch when likely to be used

384

preload: false, // Don't preload immediately

385

global: false // Only load when imported

386

};

387

```

388

389

### Component Metadata Usage

390

391

```typescript

392

// In a Nuxt module

393

nuxt.hook('components:extend', (components) => {

394

components.forEach(component => {

395

if (component.meta?.category === 'ui') {

396

// Apply UI-specific transformations

397

component.chunkName = `ui/${component.chunkName}`;

398

component.prefetch = true;

399

}

400

401

if (component.meta?.version) {

402

// Version-based handling

403

console.log(`Component ${component.pascalName} v${component.meta.version}`);

404

}

405

});

406

});

407

```

408

409

The component system provides a flexible and type-safe way to manage component registration, loading, and optimization in Nuxt applications, with full support for different rendering modes and performance optimizations.