or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

configuration-utilities.mddevelopment-tools.mdindex.mdmodule-configuration.mdmodule-hooks.mdruntime-configuration.md

module-hooks.mddocs/

0

# Module Hooks

1

2

Extensibility hooks for other Nuxt modules to modify Tailwind configuration and behavior during the build process.

3

4

## Capabilities

5

6

### Module Hooks Interface

7

8

Hook definitions for extending and customizing Tailwind CSS integration.

9

10

```typescript { .api }

11

interface ModuleHooks {

12

/**

13

* Called for each Tailwind configuration before merging layers

14

* @param tailwindConfig - Configuration from current layer/path

15

*/

16

'tailwindcss:config': (tailwindConfig: Partial<TWConfig>) => void;

17

18

/**

19

* Called for each resolved configuration from layers and paths

20

* @param tailwindConfig - Resolved configuration or undefined if failed

21

* @param configPath - Path to the configuration file

22

* @param index - Index in the configuration array

23

* @param configPaths - Array of all configuration paths

24

*/

25

'tailwindcss:loadConfig': (

26

tailwindConfig: Partial<TWConfig> | undefined,

27

configPath: string,

28

index: number,

29

configPaths: string[]

30

) => void;

31

32

/**

33

* Called with the final resolved configuration including all defaults

34

* @param tailwindConfig - Complete resolved configuration

35

* @param oldTailwindConfig - Previous configuration for comparison

36

*/

37

'tailwindcss:resolvedConfig': (

38

tailwindConfig: ReturnType<typeof import('tailwindcss/resolveConfig')>,

39

oldTailwindConfig: TWConfig | undefined

40

) => void;

41

}

42

```

43

44

### Configuration Hook

45

46

Modify individual Tailwind configurations before they are merged together.

47

48

```typescript { .api }

49

/**

50

* Hook called for each configuration before merging

51

* Use this to modify configurations from specific layers or paths

52

*/

53

nuxt.hook('tailwindcss:config', (tailwindConfig) => {

54

// Modify the configuration

55

});

56

```

57

58

**Usage Examples:**

59

60

```typescript

61

// modules/tailwind-extensions.ts

62

export default defineNuxtModule({

63

setup(options, nuxt) {

64

// Add custom colors to all configurations

65

nuxt.hook('tailwindcss:config', (config) => {

66

config.theme = config.theme || {};

67

config.theme.extend = config.theme.extend || {};

68

config.theme.extend.colors = {

69

...config.theme.extend.colors,

70

brand: {

71

primary: '#3b82f6',

72

secondary: '#1e40af',

73

}

74

};

75

});

76

77

// Add custom content paths

78

nuxt.hook('tailwindcss:config', (config) => {

79

if (Array.isArray(config.content)) {

80

config.content.push('./modules/**/*.vue');

81

} else if (config.content && typeof config.content === 'object') {

82

config.content.files = [

83

...(config.content.files || []),

84

'./modules/**/*.vue'

85

];

86

}

87

});

88

}

89

});

90

```

91

92

### Load Configuration Hook

93

94

Monitor and modify configurations as they are loaded from files and inline sources.

95

96

```typescript { .api }

97

/**

98

* Hook called for each loaded configuration

99

* Provides access to the configuration path and loading context

100

*/

101

nuxt.hook('tailwindcss:loadConfig', (config, configPath, index, allPaths) => {

102

// Process loaded configuration

103

});

104

```

105

106

**Usage Examples:**

107

108

```typescript

109

// modules/config-validator.ts

110

export default defineNuxtModule({

111

setup(options, nuxt) {

112

// Validate configurations as they load

113

nuxt.hook('tailwindcss:loadConfig', (config, configPath, index, allPaths) => {

114

if (!config) {

115

console.warn(`Failed to load Tailwind config from ${configPath}`);

116

return;

117

}

118

119

// Validate required theme properties

120

if (!config.theme?.colors) {

121

console.warn(`No colors defined in ${configPath}`);

122

}

123

124

// Log loading progress

125

console.info(`Loaded Tailwind config ${index + 1}/${allPaths.length}: ${configPath}`);

126

});

127

128

// Track configuration sources

129

nuxt.hook('tailwindcss:loadConfig', (config, configPath) => {

130

if (configPath.includes('node_modules')) {

131

console.info(`Using third-party Tailwind config: ${configPath}`);

132

}

133

});

134

}

135

});

136

```

137

138

### Resolved Configuration Hook

139

140

Access the final, complete Tailwind configuration with all defaults applied.

141

142

```typescript { .api }

143

/**

144

* Hook called with the final resolved configuration

145

* This includes all Tailwind defaults and computed values

146

*/

147

nuxt.hook('tailwindcss:resolvedConfig', (resolvedConfig, previousConfig) => {

148

// Access complete configuration

149

});

150

```

151

152

**Usage Examples:**

153

154

```typescript

155

// modules/config-analyzer.ts

156

export default defineNuxtModule({

157

setup(options, nuxt) {

158

// Analyze final configuration

159

nuxt.hook('tailwindcss:resolvedConfig', (config, oldConfig) => {

160

// Generate color palette report

161

const colors = Object.keys(config.theme.colors);

162

console.info(`Available colors: ${colors.length}`);

163

164

// Check for breaking changes

165

if (oldConfig && oldConfig.theme.colors !== config.theme.colors) {

166

console.warn('Color palette changed - check for breaking changes');

167

}

168

169

// Validate required utilities

170

const requiredUtilities = ['flex', 'grid', 'text-center'];

171

const availableUtilities = config.corePlugins;

172

173

// Export configuration for external tools

174

if (nuxt.options.dev) {

175

await writeFile(

176

'tailwind.resolved.json',

177

JSON.stringify(config, null, 2)

178

);

179

}

180

});

181

}

182

});

183

```

184

185

### Internal Regeneration Hook

186

187

Internal hook for template regeneration (primarily for internal use).

188

189

```typescript { .api }

190

/**

191

* Internal hook for template regeneration

192

* Called when configuration templates need to be updated

193

*/

194

nuxt.hook('tailwindcss:internal:regenerateTemplates', (data) => {

195

// Handle template regeneration

196

});

197

```

198

199

## Hook Integration Patterns

200

201

### Configuration Extension Module

202

203

```typescript

204

// modules/tailwind-theme.ts

205

export default defineNuxtModule({

206

meta: {

207

name: 'tailwind-theme',

208

configKey: 'tailwindTheme'

209

},

210

setup(options, nuxt) {

211

// Extend configurations with theme presets

212

nuxt.hook('tailwindcss:config', (config) => {

213

if (options.preset === 'corporate') {

214

config.theme = {

215

...config.theme,

216

extend: {

217

...config.theme?.extend,

218

colors: {

219

...config.theme?.extend?.colors,

220

corporate: {

221

blue: '#1e3a8a',

222

gray: '#374151',

223

green: '#059669'

224

}

225

},

226

fontFamily: {

227

sans: ['Inter', 'system-ui', 'sans-serif']

228

}

229

}

230

};

231

}

232

});

233

}

234

});

235

```

236

237

### Configuration Validation Module

238

239

```typescript

240

// modules/tailwind-validator.ts

241

export default defineNuxtModule({

242

setup(options, nuxt) {

243

const validationRules = options.rules || [];

244

245

nuxt.hook('tailwindcss:resolvedConfig', (config) => {

246

for (const rule of validationRules) {

247

try {

248

rule.validate(config);

249

} catch (error) {

250

if (rule.level === 'error') {

251

throw new Error(`Tailwind validation failed: ${error.message}`);

252

} else {

253

console.warn(`Tailwind validation warning: ${error.message}`);

254

}

255

}

256

}

257

});

258

}

259

});

260

```

261

262

### Development Tools Module

263

264

```typescript

265

// modules/tailwind-devtools.ts

266

export default defineNuxtModule({

267

setup(options, nuxt) {

268

if (!nuxt.options.dev) return;

269

270

// Track configuration changes

271

let configHash = '';

272

273

nuxt.hook('tailwindcss:resolvedConfig', (config) => {

274

const newHash = JSON.stringify(config);

275

276

if (configHash && configHash !== newHash) {

277

console.info('🎨 Tailwind configuration updated');

278

279

// Notify development tools

280

nuxt.callHook('dev:tailwind:updated', {

281

timestamp: Date.now(),

282

changes: detectChanges(configHash, newHash)

283

});

284

}

285

286

configHash = newHash;

287

});

288

}

289

});

290

```

291

292

## Best Practices

293

294

1. **Hook Order**: Hooks are called in the order modules are registered

295

2. **Immutability**: Don't mutate shared objects - create new objects when needed

296

3. **Error Handling**: Wrap hook logic in try-catch to prevent breaking the build

297

4. **Performance**: Keep hook logic lightweight to avoid slowing the build

298

5. **Validation**: Validate configurations to prevent runtime errors

299

6. **Documentation**: Document hook usage for other developers

300

301

## Type Extensions

302

303

Extend Nuxt's hook types for better TypeScript support:

304

305

```typescript

306

// types/nuxt.d.ts

307

declare module 'nuxt/schema' {

308

interface NuxtHooks {

309

'custom:tailwind:validated': (config: TWConfig) => void;

310

}

311

}

312

313

declare module '@nuxt/schema' {

314

interface NuxtHooks {

315

'custom:tailwind:validated': (config: TWConfig) => void;

316

}

317

}

318

```