Nuxt types and default configuration providing comprehensive TypeScript types, schema definitions, and configuration system for the Nuxt framework.
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
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.
Represents a registered component with its metadata and configuration.
interface Component {
pascalName: string
kebabName: string
export: string
filePath: string
shortPath: string
chunkName: string
prefetch: boolean
preload: boolean
global?: boolean | 'sync'
island?: boolean
meta?: ComponentMeta
mode?: 'client' | 'server' | 'all'
priority?: number
/** @internal Allow bypassing transforms */
_raw?: boolean
}Extensible metadata for components.
interface ComponentMeta {
[key: string]: unknown
}Configuration for component directory scanning.
interface ScanDir {
/** Path to directory containing components */
path: string
/** Pattern to match component files */
pattern?: string | string[]
/** Patterns to ignore */
ignore?: string[]
/** Prefix for matched components */
prefix?: string
/** Global registration mode */
global?: boolean | 'sync'
/** Island component support */
island?: boolean
/** Component loading mode */
mode?: 'client' | 'server' | 'all'
/** Priority for component resolution */
priority?: number
/** Whether to watch for changes */
watch?: boolean
/** Extensions to scan */
extensions?: string[]
/** Path prefix for component names */
pathPrefix?: boolean
}Extended component directory configuration.
interface ComponentsDir extends ScanDir {
/** Whether this directory is enabled */
enabled?: boolean
/** Component prefix to apply */
prefix?: string
/** Override global setting */
global?: boolean | 'sync'
}Complete components system configuration.
interface ComponentsOptions {
/** Component directories to scan */
dirs: (string | ComponentsDir)[]
/** Global components loader */
loader?: boolean
/** Transform options */
transform?: {
/** Include patterns */
include?: RegExp[]
/** Exclude patterns */
exclude?: RegExp[]
}
/** Whether to generate types */
types?: boolean
}// nuxt.config.ts
export default defineNuxtConfig({
components: {
dirs: [
// Default components directory
'~/components',
// Additional directory with prefix
{
path: '~/components/ui',
prefix: 'UI'
},
// Global components
{
path: '~/components/global',
global: true
}
]
}
});import type { ComponentsOptions } from '@nuxt/schema';
const componentsConfig: ComponentsOptions = {
dirs: [
{
path: '~/components/base',
prefix: 'Base',
global: false,
watch: true,
extensions: ['vue', 'tsx'],
pattern: '**/*.{vue,tsx}',
ignore: ['**/*.stories.{js,ts}']
},
{
path: '~/components/islands',
island: true,
mode: 'server',
priority: 10
},
{
path: '~/components/client',
mode: 'client',
prefix: 'Client',
pathPrefix: false
}
],
loader: true,
types: true,
transform: {
include: [/\.vue$/, /\.tsx?$/],
exclude: [/\.test\./]
}
};import type { Component } from '@nuxt/schema';
// In a Nuxt module
export default defineNuxtModule({
setup(options, nuxt) {
// Register components programmatically
nuxt.hook('components:extend', (components: Component[]) => {
components.push({
pascalName: 'MyCustomButton',
kebabName: 'my-custom-button',
export: 'default',
filePath: path.resolve(__dirname, './runtime/components/MyButton.vue'),
shortPath: 'runtime/components/MyButton.vue',
chunkName: 'components/my-custom-button',
prefetch: false,
preload: false,
global: true,
mode: 'all',
priority: 0
});
// Register component with metadata
components.push({
pascalName: 'IconButton',
kebabName: 'icon-button',
export: 'default',
filePath: './components/IconButton.vue',
shortPath: 'components/IconButton.vue',
chunkName: 'components/icon-button',
prefetch: true,
preload: true,
meta: {
category: 'ui',
version: '1.0.0',
props: ['icon', 'size', 'variant']
}
});
});
}
});// In a Nuxt module or plugin
export default defineNuxtModule({
setup(options, nuxt) {
// Add component directories
nuxt.hook('components:dirs', (dirs) => {
dirs.push({
path: path.resolve(__dirname, './components'),
prefix: options.prefix || 'Module',
global: options.global || false,
watch: nuxt.options.dev,
extensions: ['vue', 'ts', 'tsx'],
pattern: '**/*.{vue,ts,tsx}',
ignore: ['**/*.story.*', '**/*.test.*']
});
});
}
});// Types are automatically generated for registered components
declare module '@vue/runtime-core' {
export interface GlobalComponents {
// Auto-registered components
MyCustomButton: typeof import('~/components/MyCustomButton.vue')['default']
UICard: typeof import('~/components/ui/Card.vue')['default']
// Island components
ServerOnlyChart: typeof import('~/components/islands/Chart.vue')['default']
}
}// In a module setup
addTypeTemplate({
filename: 'components.d.ts',
getContents: ({ nuxt }) => {
const components = nuxt.apps.default?.components || [];
return `
declare module '@vue/runtime-core' {
export interface GlobalComponents {
${components.map(c =>
`${c.pascalName}: typeof import('${c.filePath}')['${c.export}']`
).join('\n ')}
}
}
declare module '#components' {
${components.map(c =>
`export const ${c.pascalName}: typeof import('${c.filePath}')['${c.export}']`
).join('\n ')}
}
`;
}
});const clientComponent: Component = {
pascalName: 'ClientOnlyWidget',
kebabName: 'client-only-widget',
export: 'default',
filePath: '~/components/ClientWidget.vue',
shortPath: 'components/ClientWidget.vue',
chunkName: 'components/client-widget',
mode: 'client', // Only loaded on client
prefetch: false,
preload: false
};const serverComponent: Component = {
pascalName: 'ServerChart',
kebabName: 'server-chart',
export: 'default',
filePath: '~/components/islands/Chart.vue',
shortPath: 'components/islands/Chart.vue',
chunkName: 'components/server-chart',
mode: 'server', // Server-side only
island: true, // Island component
prefetch: false,
preload: false
};// Enable island components in config
export default defineNuxtConfig({
experimental: {
componentIslands: true
},
components: {
dirs: [
{
path: '~/components/islands',
island: true,
mode: 'server'
}
]
}
});
// Usage in templates
// <ServerChart :data="chartData" />// Higher priority components override lower priority ones
const highPriorityComponent: Component = {
pascalName: 'Button',
// ... other properties
priority: 10 // Higher number = higher priority
};
const defaultComponent: Component = {
pascalName: 'Button',
// ... other properties
priority: 0 // Default priority
};const optimizedComponent: Component = {
pascalName: 'HeavyChart',
kebabName: 'heavy-chart',
export: 'default',
filePath: '~/components/charts/HeavyChart.vue',
shortPath: 'components/charts/HeavyChart.vue',
chunkName: 'components/heavy-chart',
prefetch: true, // Prefetch when likely to be used
preload: false, // Don't preload immediately
global: false // Only load when imported
};// In a Nuxt module
nuxt.hook('components:extend', (components) => {
components.forEach(component => {
if (component.meta?.category === 'ui') {
// Apply UI-specific transformations
component.chunkName = `ui/${component.chunkName}`;
component.prefetch = true;
}
if (component.meta?.version) {
// Version-based handling
console.log(`Component ${component.pascalName} v${component.meta.version}`);
}
});
});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.
Install with Tessl CLI
npx tessl i tessl/npm-nuxt--schema