Skip to content
Draft
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions docs/content/docs/8.advanced/5.hooks.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,21 @@ export default defineNuxtConfig({
})
```

## `content:manifest`{lang="ts"}

This hook is called after the manifest is generated.

```ts
export default defineNuxtConfig({
hooks: {
'content:manifest'(ctx) {
// ...
// ctx.collections.push(defineCollection())
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.
}
})
```

## Example Usage

```ts [nuxt.config.ts]
Expand Down
1 change: 1 addition & 0 deletions src/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ export default defineNuxtModule<ModuleOptions>({

const { collections } = await loadContentConfig(nuxt, options)
manifest.collections = collections
nuxt.callHook('content:manifest', manifest)
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated

nuxt.options.vite.optimizeDeps = defu(nuxt.options.vite.optimizeDeps, {
exclude: ['@sqlite.org/sqlite-wasm'],
Expand Down
2 changes: 2 additions & 0 deletions src/types/hooks.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type { ResolvedCollection } from './collection'
import type { ContentFile, ParsedContentFile } from './content'
import type { PathMetaOptions } from './path-meta'
import type { Manifest } from './manifest'

// Parser options interface
interface ParserOptions {
Expand Down Expand Up @@ -32,5 +33,6 @@ declare module '@nuxt/schema' {
interface NuxtHooks {
'content:file:beforeParse': (ctx: FileBeforeParseHook) => Promise<void> | void
'content:file:afterParse': (ctx: FileAfterParseHook) => Promise<void> | void
'content:manifest': (manifest: Manifest) => Promise<void> | void
}
}
37 changes: 37 additions & 0 deletions test/unit/hooks.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { resolveCollection } from '../../src/utils/collection'
import { parseContent } from '../utils/content'
import type { FileAfterParseHook, FileBeforeParseHook } from '../../src/types'
import { initiateValidatorsContext } from '../../src/utils/dependencies'
import type { Manifest } from '../../src/types/manifest'

describe('Hooks', async () => {
await initiateValidatorsContext()
Expand Down Expand Up @@ -57,4 +58,40 @@ foo: 'bar'
expect(parsed.foo).toEqual('bar')
expect(parsed.bar).toEqual('foo')
})

it('content:manifest mutations are reflected in manifest', async () => {
const extraCollection = resolveCollection('injected', defineCollection({
type: 'data',
source: 'extra/**',
schema: z.object({
body: z.any(),
}),
}))!

const manifest: Manifest = {
checksumStructure: {},
checksum: {},
dump: {},
components: [],
collections: [collection],
}

// Simulate the module calling the hook
const nuxtMock = {
callHook(hook: string, ctx: Manifest) {
if (hook === 'content:manifest') {
ctx.collections.push(extraCollection)
}
},
}

nuxtMock.callHook('content:manifest', manifest)

// must be visible on original manifest object
expect(manifest.collections).toHaveLength(2)
// new collection is visible
expect(manifest.collections.find(c => c.name === 'injected')).toBeDefined()
// original collection still exists
expect(manifest.collections.find(c => c.name === 'hookTest')).toBeDefined()
})
})
Loading