Skip to content

Commit e9cded0

Browse files
authored
feat(content): add defineOgImageSchema() composable (#520)
1 parent 6e8f49e commit e9cded0

File tree

3 files changed

+66
-24
lines changed

3 files changed

+66
-24
lines changed

docs/content/4.integrations/1.content.md

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,21 +11,22 @@ You can see a demo of this integration in the [Nuxt OG Image & Nuxt Content Play
1111

1212
## Setup Nuxt Content v3
1313

14-
In Nuxt Content v3 we need to use the `asOgImageCollection()`{lang="ts"} function to augment any collections
15-
to be able to use the `ogImage` frontmatter key.
14+
Add `defineOgImageSchema()`{lang="ts"} to your collection's schema to enable the `ogImage` frontmatter key.
1615

1716
```ts [content.config.ts]
1817
import { defineCollection, defineContentConfig } from '@nuxt/content'
19-
import { asOgImageCollection } from 'nuxt-og-image/content'
18+
import { defineOgImageSchema } from 'nuxt-og-image/content'
19+
import { z } from 'zod'
2020

2121
export default defineContentConfig({
2222
collections: {
23-
content: defineCollection(
24-
asOgImageCollection({
25-
type: 'page',
26-
source: '**/*.md',
23+
content: defineCollection({
24+
type: 'page',
25+
source: '**/*.md',
26+
schema: z.object({
27+
ogImage: defineOgImageSchema(),
2728
}),
28-
),
29+
}),
2930
},
3031
})
3132
```

playground/content.config.ts

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
1-
import { defineCollection, defineContentConfig, z } from '@nuxt/content'
2-
import { asOgImageCollection } from '../src/content'
1+
import { defineCollection, defineContentConfig } from '@nuxt/content'
2+
import { z } from 'zod'
3+
import { defineOgImageSchema } from '../src/content'
34

45
export default defineContentConfig({
56
collections: {
6-
content: defineCollection(
7-
asOgImageCollection({
8-
type: 'page',
9-
source: '**/*.md',
10-
schema: z.object({
11-
date: z.string().optional(),
12-
}),
7+
content: defineCollection({
8+
type: 'page',
9+
source: '**/*.md',
10+
schema: z.object({
11+
date: z.string().optional(),
12+
ogImage: defineOgImageSchema(),
1313
}),
14-
),
14+
}),
1515
},
1616
})

src/content.ts

Lines changed: 47 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,58 @@
11
import type { Collection } from '@nuxt/content'
22
import { z } from 'zod'
33

4-
export const ogImageSchema = z.object({
5-
url: z.string().optional(),
6-
component: z.string().optional(),
7-
props: z.record(z.string(), z.any()),
8-
}).optional()
4+
function buildOgImageObjectSchema(_z: typeof z) {
5+
return _z.object({
6+
url: _z.string().optional(),
7+
component: _z.string().optional(),
8+
props: _z.record(_z.string(), _z.any()),
9+
}).optional()
10+
}
11+
12+
const ogImageObjectSchema = buildOgImageObjectSchema(z)
13+
14+
function withEditorHidden<T extends z.ZodTypeAny>(s: T): T {
15+
// .editor() is patched onto ZodType by @nuxt/content at runtime
16+
if (typeof (s as any).editor === 'function')
17+
return (s as any).editor({ hidden: true })
18+
return s
19+
}
20+
21+
export interface DefineOgImageSchemaOptions {
22+
/**
23+
* Pass the `z` instance from `@nuxt/content` to ensure `.editor({ hidden: true })` works
24+
* across Zod versions. When omitted, the bundled `z` is used (`.editor()` applied if available).
25+
*/
26+
z?: typeof z
27+
}
28+
29+
/**
30+
* Define the ogImage schema field for a Nuxt Content collection.
31+
*
32+
* @example
33+
* defineCollection({
34+
* type: 'page',
35+
* source: '**',
36+
* schema: z.object({
37+
* ogImage: defineOgImageSchema()
38+
* })
39+
* })
40+
*/
41+
export function defineOgImageSchema(options?: DefineOgImageSchemaOptions) {
42+
const s = options?.z ? buildOgImageObjectSchema(options.z) : ogImageObjectSchema
43+
return withEditorHidden(s)
44+
}
45+
46+
// Legacy exports
47+
export const ogImageSchema = ogImageObjectSchema
948

1049
export const schema = z.object({
11-
ogImage: ogImageSchema,
50+
ogImage: withEditorHidden(ogImageObjectSchema),
1251
})
1352

53+
/** @deprecated Use `defineOgImageSchema()` in your collection schema instead. See https://nuxtseo.com/og-image/integrations/content */
1454
export function asOgImageCollection<T>(collection: Collection<T>): Collection<T> {
55+
console.warn('[og-image] `asOgImageCollection()` is deprecated. Use `defineOgImageSchema()` in your collection schema instead. See https://nuxtseo.com/og-image/integrations/content')
1556
if (collection.type === 'page') {
1657
// @ts-expect-error untyped
1758
collection.schema = collection.schema ? schema.extend(collection.schema.shape) : schema

0 commit comments

Comments
 (0)