sanity-plugin-seofields 1.2.2 → 1.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +35 -0
- package/dist/index.d.ts +35 -0
- package/dist/index.js +580 -459
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +567 -446
- package/dist/index.mjs.map +1 -1
- package/dist/next.d.mts +334 -0
- package/dist/next.d.ts +334 -0
- package/dist/next.js +105 -0
- package/dist/next.js.map +1 -0
- package/dist/next.mjs +102 -0
- package/dist/next.mjs.map +1 -0
- package/package.json +8 -1
- package/src/components/SeoHealthDashboard.tsx +30 -8
- package/src/helpers/SeoMetaTags.tsx +154 -0
- package/src/helpers/seoMeta.ts +283 -0
- package/src/next.ts +12 -0
- package/src/plugin.ts +13 -0
- package/src/types.ts +6 -2
package/dist/next.d.mts
ADDED
|
@@ -0,0 +1,334 @@
|
|
|
1
|
+
import {default as React_2} from 'react'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Convert a Sanity SEO object into a structured metadata object.
|
|
5
|
+
*
|
|
6
|
+
* The return value is structurally compatible with Next.js App Router's
|
|
7
|
+
* `Metadata` type, so you can return it directly from `generateMetadata()`.
|
|
8
|
+
*
|
|
9
|
+
* @example Next.js App Router
|
|
10
|
+
* ```ts
|
|
11
|
+
* import { buildSeoMeta } from 'sanity-plugin-seofields'
|
|
12
|
+
* import { urlFor } from '@/sanity/lib/image'
|
|
13
|
+
*
|
|
14
|
+
* export async function generateMetadata(): Promise<Metadata> {
|
|
15
|
+
* const { seo } = await sanityFetch({ query: PAGE_SEO_QUERY })
|
|
16
|
+
* return buildSeoMeta({
|
|
17
|
+
* seo,
|
|
18
|
+
* baseUrl: process.env.NEXT_PUBLIC_SITE_URL,
|
|
19
|
+
* path: '/about',
|
|
20
|
+
* defaults: { title: 'My Site', siteName: 'My Site' },
|
|
21
|
+
* imageUrlResolver: (img) => urlFor(img).width(1200).url(),
|
|
22
|
+
* })
|
|
23
|
+
* }
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
export declare function buildSeoMeta(options: BuildSeoMetaOptions): SeoMetadata
|
|
27
|
+
|
|
28
|
+
/** Options accepted by buildSeoMeta(). */
|
|
29
|
+
export declare interface BuildSeoMetaOptions {
|
|
30
|
+
/**
|
|
31
|
+
* The raw SEO object from Sanity (_type excluded or included — both work).
|
|
32
|
+
* Pass `null` or `undefined` to fall back entirely to `defaults`.
|
|
33
|
+
*
|
|
34
|
+
* Accepts both the strict plugin `SeoFields` type and Sanity's code-generated
|
|
35
|
+
* type (which has all nested fields optional) without any `as any` cast.
|
|
36
|
+
*/
|
|
37
|
+
seo?: SeoFieldsInput | null
|
|
38
|
+
/**
|
|
39
|
+
* The base URL of your site, e.g. "https://example.com".
|
|
40
|
+
* Used for canonical URL and OpenGraph URL construction.
|
|
41
|
+
*/
|
|
42
|
+
baseUrl?: string
|
|
43
|
+
/**
|
|
44
|
+
* The path for the current page, e.g. "/about".
|
|
45
|
+
* Combined with baseUrl to produce the canonical + OG url.
|
|
46
|
+
* Defaults to "".
|
|
47
|
+
*/
|
|
48
|
+
path?: string
|
|
49
|
+
/**
|
|
50
|
+
* Default values used when the Sanity SEO fields are empty / missing.
|
|
51
|
+
*/
|
|
52
|
+
defaults?: SeoMetaDefaults
|
|
53
|
+
/**
|
|
54
|
+
* Resolve a Sanity image asset to a plain URL string.
|
|
55
|
+
*
|
|
56
|
+
* @example (using @sanity/image-url)
|
|
57
|
+
* imageUrlResolver: (img) => urlFor(img).width(1200).url()
|
|
58
|
+
*/
|
|
59
|
+
imageUrlResolver?: (image: SanityImage | SanityImageWithAlt) => string | null | undefined
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
declare interface MetaAttribute {
|
|
63
|
+
_type: 'metaAttribute'
|
|
64
|
+
key?: string
|
|
65
|
+
type?: 'string' | 'image'
|
|
66
|
+
value?: string
|
|
67
|
+
image?: SanityImage
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
declare type OGType = (typeof VALID_OG_TYPES)[number]
|
|
71
|
+
|
|
72
|
+
declare interface OpenGraphSettings {
|
|
73
|
+
_type: 'openGraph'
|
|
74
|
+
/** The canonical URL for OpenGraph (og:url). Maps to the `url` field in Sanity. */
|
|
75
|
+
url?: string
|
|
76
|
+
title?: string
|
|
77
|
+
description?: string
|
|
78
|
+
siteName?: string
|
|
79
|
+
type?: 'website' | 'article' | 'profile' | 'book' | 'music' | 'video' | 'product'
|
|
80
|
+
imageType?: 'upload' | 'url'
|
|
81
|
+
image?: SanityImageWithAlt
|
|
82
|
+
imageUrl?: string
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
declare interface RobotsSettings {
|
|
86
|
+
noIndex?: boolean
|
|
87
|
+
noFollow?: boolean
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Coerce an arbitrary string to a valid OpenGraph type.
|
|
92
|
+
* Falls back to "website" when the value is invalid.
|
|
93
|
+
*/
|
|
94
|
+
export declare function sanitizeOGType(value?: string): OGType
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Coerce an arbitrary string to a valid Twitter card type.
|
|
98
|
+
* Falls back to "summary_large_image" when the value is invalid.
|
|
99
|
+
*/
|
|
100
|
+
export declare function sanitizeTwitterCard(value?: string): TwitterCard
|
|
101
|
+
|
|
102
|
+
declare interface SanityImage {
|
|
103
|
+
_type: 'image'
|
|
104
|
+
asset: {
|
|
105
|
+
_ref: string
|
|
106
|
+
_type: 'reference'
|
|
107
|
+
}
|
|
108
|
+
hotspot?: {
|
|
109
|
+
x: number
|
|
110
|
+
y: number
|
|
111
|
+
height: number
|
|
112
|
+
width: number
|
|
113
|
+
}
|
|
114
|
+
crop?: {
|
|
115
|
+
top: number
|
|
116
|
+
bottom: number
|
|
117
|
+
left: number
|
|
118
|
+
right: number
|
|
119
|
+
}
|
|
120
|
+
alt?: string
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
declare interface SanityImageWithAlt extends SanityImage {
|
|
124
|
+
alt: string
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
declare interface SeoFields {
|
|
128
|
+
_type: 'seoFields'
|
|
129
|
+
robots?: RobotsSettings
|
|
130
|
+
preview?: string
|
|
131
|
+
title?: string
|
|
132
|
+
description?: string
|
|
133
|
+
metaImage?: SanityImage
|
|
134
|
+
metaAttributes?: MetaAttribute[]
|
|
135
|
+
keywords?: string[]
|
|
136
|
+
canonicalUrl?: string
|
|
137
|
+
openGraph?: OpenGraphSettings
|
|
138
|
+
twitter?: TwitterCardSettings
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Input-compatible variant of SeoFields. Structurally matches Sanity's
|
|
143
|
+
* code-generated types (where `asset`, `alt`, `key`, and `type` are all
|
|
144
|
+
* optional), so you can pass `data.seo` from a sanityFetch result directly
|
|
145
|
+
* without any `as any` or manual casting.
|
|
146
|
+
*/
|
|
147
|
+
declare interface SeoFieldsInput {
|
|
148
|
+
_type?: string
|
|
149
|
+
robots?: {
|
|
150
|
+
noIndex?: boolean | null
|
|
151
|
+
noFollow?: boolean | null
|
|
152
|
+
} | null
|
|
153
|
+
title?: string | null
|
|
154
|
+
description?: string | null
|
|
155
|
+
metaImage?: SeoImageInput | null
|
|
156
|
+
metaAttributes?: Array<{
|
|
157
|
+
_key?: string
|
|
158
|
+
key?: string
|
|
159
|
+
value?: string
|
|
160
|
+
type?: string
|
|
161
|
+
}> | null
|
|
162
|
+
keywords?: string[] | null
|
|
163
|
+
canonicalUrl?: string | null
|
|
164
|
+
openGraph?: {
|
|
165
|
+
_type?: string
|
|
166
|
+
url?: string | null
|
|
167
|
+
title?: string | null
|
|
168
|
+
description?: string | null
|
|
169
|
+
siteName?: string | null
|
|
170
|
+
type?: string | null
|
|
171
|
+
imageType?: string | null
|
|
172
|
+
image?: SeoImageInput | null
|
|
173
|
+
imageUrl?: string | null
|
|
174
|
+
} | null
|
|
175
|
+
twitter?: {
|
|
176
|
+
_type?: string
|
|
177
|
+
card?: string | null
|
|
178
|
+
site?: string | null
|
|
179
|
+
creator?: string | null
|
|
180
|
+
title?: string | null
|
|
181
|
+
description?: string | null
|
|
182
|
+
imageType?: string | null
|
|
183
|
+
image?: SeoImageInput | null
|
|
184
|
+
imageUrl?: string | null
|
|
185
|
+
} | null
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Permissive image shape accepted by buildSeoMeta — compatible with both the
|
|
190
|
+
* plugin's SanityImage and Sanity's code-generated image type (where `asset`
|
|
191
|
+
* and `alt` are optional).
|
|
192
|
+
*/
|
|
193
|
+
declare interface SeoImageInput {
|
|
194
|
+
_type?: string
|
|
195
|
+
asset?: {
|
|
196
|
+
_ref: string
|
|
197
|
+
_type: string
|
|
198
|
+
_weak?: boolean
|
|
199
|
+
[key: string]: unknown
|
|
200
|
+
}
|
|
201
|
+
hotspot?: unknown
|
|
202
|
+
crop?: unknown
|
|
203
|
+
alt?: string
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/** Structured metadata returned by buildSeoMeta(). Compatible with Next.js Metadata (App Router). */
|
|
207
|
+
export declare interface SeoMetadata {
|
|
208
|
+
title?: string | null
|
|
209
|
+
description?: string | null
|
|
210
|
+
keywords?: string[]
|
|
211
|
+
robots?: {
|
|
212
|
+
index?: boolean
|
|
213
|
+
follow?: boolean
|
|
214
|
+
googleBot?: {
|
|
215
|
+
index?: boolean
|
|
216
|
+
follow?: boolean
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
openGraph?: {
|
|
220
|
+
type?: string
|
|
221
|
+
url?: string
|
|
222
|
+
title?: string
|
|
223
|
+
description?: string
|
|
224
|
+
siteName?: string
|
|
225
|
+
images?: Array<{
|
|
226
|
+
url: string
|
|
227
|
+
width?: number
|
|
228
|
+
height?: number
|
|
229
|
+
alt?: string
|
|
230
|
+
}>
|
|
231
|
+
}
|
|
232
|
+
twitter?: {
|
|
233
|
+
card?: string
|
|
234
|
+
site?: string
|
|
235
|
+
creator?: string
|
|
236
|
+
title?: string
|
|
237
|
+
description?: string
|
|
238
|
+
images?: string[]
|
|
239
|
+
}
|
|
240
|
+
alternates?: {
|
|
241
|
+
canonical?: string
|
|
242
|
+
}
|
|
243
|
+
/** Any custom meta attributes from seo.metaAttributes */
|
|
244
|
+
other?: Record<string, string>
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
/** Default values used when SEO fields are missing. */
|
|
248
|
+
export declare interface SeoMetaDefaults {
|
|
249
|
+
title?: string
|
|
250
|
+
description?: string
|
|
251
|
+
siteName?: string
|
|
252
|
+
twitterSite?: string
|
|
253
|
+
twitterCreator?: string
|
|
254
|
+
/** Fallback image URL when no OG / Twitter image is set. */
|
|
255
|
+
ogImage?: string
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
/**
|
|
259
|
+
* Renders all SEO meta tags for a page as plain React elements.
|
|
260
|
+
* Intended to be placed inside your framework's <Head> / <head> component.
|
|
261
|
+
*
|
|
262
|
+
* Renders:
|
|
263
|
+
* - `<title>`
|
|
264
|
+
* - `<meta name="description">`
|
|
265
|
+
* - `<meta name="keywords">`
|
|
266
|
+
* - `<meta name="robots">`
|
|
267
|
+
* - OpenGraph meta tags (`og:*`)
|
|
268
|
+
* - Twitter Card meta tags (`twitter:*`)
|
|
269
|
+
* - Any custom `seo.metaAttributes` as `<meta name="..." content="...">`
|
|
270
|
+
*/
|
|
271
|
+
export declare function SeoMetaTags({
|
|
272
|
+
data,
|
|
273
|
+
baseUrl,
|
|
274
|
+
path,
|
|
275
|
+
defaults,
|
|
276
|
+
imageUrlResolver,
|
|
277
|
+
}: SeoMetaTagsProps): React_2.JSX.Element
|
|
278
|
+
|
|
279
|
+
export declare interface SeoMetaTagsProps {
|
|
280
|
+
/**
|
|
281
|
+
* The raw SEO object from Sanity.
|
|
282
|
+
* Pass `null` / `undefined` to render only the defaults.
|
|
283
|
+
*/
|
|
284
|
+
data?: Partial<SeoFields> | null
|
|
285
|
+
/**
|
|
286
|
+
* Base URL of your site, e.g. "https://example.com".
|
|
287
|
+
* Used for canonical link, og:url fallback.
|
|
288
|
+
*/
|
|
289
|
+
baseUrl?: string
|
|
290
|
+
/**
|
|
291
|
+
* Current page path, e.g. "/about".
|
|
292
|
+
* Defaults to "".
|
|
293
|
+
*/
|
|
294
|
+
path?: string
|
|
295
|
+
/**
|
|
296
|
+
* Default values used when SEO fields are missing.
|
|
297
|
+
*/
|
|
298
|
+
defaults?: BuildSeoMetaOptions['defaults']
|
|
299
|
+
/**
|
|
300
|
+
* Resolve a Sanity image asset reference to a full URL string.
|
|
301
|
+
*
|
|
302
|
+
* @example
|
|
303
|
+
* imageUrlResolver={(img) => urlFor(img).width(1200).url()}
|
|
304
|
+
*/
|
|
305
|
+
imageUrlResolver?: (image: SanityImage | SanityImageWithAlt) => string | null | undefined
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
declare type TwitterCard = (typeof VALID_TWITTER_CARDS)[number]
|
|
309
|
+
|
|
310
|
+
declare interface TwitterCardSettings {
|
|
311
|
+
_type: 'twitter'
|
|
312
|
+
card?: 'summary' | 'summary_large_image' | 'app' | 'player'
|
|
313
|
+
site?: string
|
|
314
|
+
creator?: string
|
|
315
|
+
title?: string
|
|
316
|
+
description?: string
|
|
317
|
+
imageType?: 'upload' | 'url'
|
|
318
|
+
image?: SanityImageWithAlt
|
|
319
|
+
imageUrl?: string
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
declare const VALID_OG_TYPES: readonly [
|
|
323
|
+
'website',
|
|
324
|
+
'article',
|
|
325
|
+
'profile',
|
|
326
|
+
'book',
|
|
327
|
+
'music',
|
|
328
|
+
'video',
|
|
329
|
+
'product',
|
|
330
|
+
]
|
|
331
|
+
|
|
332
|
+
declare const VALID_TWITTER_CARDS: readonly ['summary', 'summary_large_image', 'app', 'player']
|
|
333
|
+
|
|
334
|
+
export {}
|
package/dist/next.d.ts
ADDED
|
@@ -0,0 +1,334 @@
|
|
|
1
|
+
import {default as React_2} from 'react'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Convert a Sanity SEO object into a structured metadata object.
|
|
5
|
+
*
|
|
6
|
+
* The return value is structurally compatible with Next.js App Router's
|
|
7
|
+
* `Metadata` type, so you can return it directly from `generateMetadata()`.
|
|
8
|
+
*
|
|
9
|
+
* @example Next.js App Router
|
|
10
|
+
* ```ts
|
|
11
|
+
* import { buildSeoMeta } from 'sanity-plugin-seofields'
|
|
12
|
+
* import { urlFor } from '@/sanity/lib/image'
|
|
13
|
+
*
|
|
14
|
+
* export async function generateMetadata(): Promise<Metadata> {
|
|
15
|
+
* const { seo } = await sanityFetch({ query: PAGE_SEO_QUERY })
|
|
16
|
+
* return buildSeoMeta({
|
|
17
|
+
* seo,
|
|
18
|
+
* baseUrl: process.env.NEXT_PUBLIC_SITE_URL,
|
|
19
|
+
* path: '/about',
|
|
20
|
+
* defaults: { title: 'My Site', siteName: 'My Site' },
|
|
21
|
+
* imageUrlResolver: (img) => urlFor(img).width(1200).url(),
|
|
22
|
+
* })
|
|
23
|
+
* }
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
export declare function buildSeoMeta(options: BuildSeoMetaOptions): SeoMetadata
|
|
27
|
+
|
|
28
|
+
/** Options accepted by buildSeoMeta(). */
|
|
29
|
+
export declare interface BuildSeoMetaOptions {
|
|
30
|
+
/**
|
|
31
|
+
* The raw SEO object from Sanity (_type excluded or included — both work).
|
|
32
|
+
* Pass `null` or `undefined` to fall back entirely to `defaults`.
|
|
33
|
+
*
|
|
34
|
+
* Accepts both the strict plugin `SeoFields` type and Sanity's code-generated
|
|
35
|
+
* type (which has all nested fields optional) without any `as any` cast.
|
|
36
|
+
*/
|
|
37
|
+
seo?: SeoFieldsInput | null
|
|
38
|
+
/**
|
|
39
|
+
* The base URL of your site, e.g. "https://example.com".
|
|
40
|
+
* Used for canonical URL and OpenGraph URL construction.
|
|
41
|
+
*/
|
|
42
|
+
baseUrl?: string
|
|
43
|
+
/**
|
|
44
|
+
* The path for the current page, e.g. "/about".
|
|
45
|
+
* Combined with baseUrl to produce the canonical + OG url.
|
|
46
|
+
* Defaults to "".
|
|
47
|
+
*/
|
|
48
|
+
path?: string
|
|
49
|
+
/**
|
|
50
|
+
* Default values used when the Sanity SEO fields are empty / missing.
|
|
51
|
+
*/
|
|
52
|
+
defaults?: SeoMetaDefaults
|
|
53
|
+
/**
|
|
54
|
+
* Resolve a Sanity image asset to a plain URL string.
|
|
55
|
+
*
|
|
56
|
+
* @example (using @sanity/image-url)
|
|
57
|
+
* imageUrlResolver: (img) => urlFor(img).width(1200).url()
|
|
58
|
+
*/
|
|
59
|
+
imageUrlResolver?: (image: SanityImage | SanityImageWithAlt) => string | null | undefined
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
declare interface MetaAttribute {
|
|
63
|
+
_type: 'metaAttribute'
|
|
64
|
+
key?: string
|
|
65
|
+
type?: 'string' | 'image'
|
|
66
|
+
value?: string
|
|
67
|
+
image?: SanityImage
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
declare type OGType = (typeof VALID_OG_TYPES)[number]
|
|
71
|
+
|
|
72
|
+
declare interface OpenGraphSettings {
|
|
73
|
+
_type: 'openGraph'
|
|
74
|
+
/** The canonical URL for OpenGraph (og:url). Maps to the `url` field in Sanity. */
|
|
75
|
+
url?: string
|
|
76
|
+
title?: string
|
|
77
|
+
description?: string
|
|
78
|
+
siteName?: string
|
|
79
|
+
type?: 'website' | 'article' | 'profile' | 'book' | 'music' | 'video' | 'product'
|
|
80
|
+
imageType?: 'upload' | 'url'
|
|
81
|
+
image?: SanityImageWithAlt
|
|
82
|
+
imageUrl?: string
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
declare interface RobotsSettings {
|
|
86
|
+
noIndex?: boolean
|
|
87
|
+
noFollow?: boolean
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Coerce an arbitrary string to a valid OpenGraph type.
|
|
92
|
+
* Falls back to "website" when the value is invalid.
|
|
93
|
+
*/
|
|
94
|
+
export declare function sanitizeOGType(value?: string): OGType
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Coerce an arbitrary string to a valid Twitter card type.
|
|
98
|
+
* Falls back to "summary_large_image" when the value is invalid.
|
|
99
|
+
*/
|
|
100
|
+
export declare function sanitizeTwitterCard(value?: string): TwitterCard
|
|
101
|
+
|
|
102
|
+
declare interface SanityImage {
|
|
103
|
+
_type: 'image'
|
|
104
|
+
asset: {
|
|
105
|
+
_ref: string
|
|
106
|
+
_type: 'reference'
|
|
107
|
+
}
|
|
108
|
+
hotspot?: {
|
|
109
|
+
x: number
|
|
110
|
+
y: number
|
|
111
|
+
height: number
|
|
112
|
+
width: number
|
|
113
|
+
}
|
|
114
|
+
crop?: {
|
|
115
|
+
top: number
|
|
116
|
+
bottom: number
|
|
117
|
+
left: number
|
|
118
|
+
right: number
|
|
119
|
+
}
|
|
120
|
+
alt?: string
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
declare interface SanityImageWithAlt extends SanityImage {
|
|
124
|
+
alt: string
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
declare interface SeoFields {
|
|
128
|
+
_type: 'seoFields'
|
|
129
|
+
robots?: RobotsSettings
|
|
130
|
+
preview?: string
|
|
131
|
+
title?: string
|
|
132
|
+
description?: string
|
|
133
|
+
metaImage?: SanityImage
|
|
134
|
+
metaAttributes?: MetaAttribute[]
|
|
135
|
+
keywords?: string[]
|
|
136
|
+
canonicalUrl?: string
|
|
137
|
+
openGraph?: OpenGraphSettings
|
|
138
|
+
twitter?: TwitterCardSettings
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Input-compatible variant of SeoFields. Structurally matches Sanity's
|
|
143
|
+
* code-generated types (where `asset`, `alt`, `key`, and `type` are all
|
|
144
|
+
* optional), so you can pass `data.seo` from a sanityFetch result directly
|
|
145
|
+
* without any `as any` or manual casting.
|
|
146
|
+
*/
|
|
147
|
+
declare interface SeoFieldsInput {
|
|
148
|
+
_type?: string
|
|
149
|
+
robots?: {
|
|
150
|
+
noIndex?: boolean | null
|
|
151
|
+
noFollow?: boolean | null
|
|
152
|
+
} | null
|
|
153
|
+
title?: string | null
|
|
154
|
+
description?: string | null
|
|
155
|
+
metaImage?: SeoImageInput | null
|
|
156
|
+
metaAttributes?: Array<{
|
|
157
|
+
_key?: string
|
|
158
|
+
key?: string
|
|
159
|
+
value?: string
|
|
160
|
+
type?: string
|
|
161
|
+
}> | null
|
|
162
|
+
keywords?: string[] | null
|
|
163
|
+
canonicalUrl?: string | null
|
|
164
|
+
openGraph?: {
|
|
165
|
+
_type?: string
|
|
166
|
+
url?: string | null
|
|
167
|
+
title?: string | null
|
|
168
|
+
description?: string | null
|
|
169
|
+
siteName?: string | null
|
|
170
|
+
type?: string | null
|
|
171
|
+
imageType?: string | null
|
|
172
|
+
image?: SeoImageInput | null
|
|
173
|
+
imageUrl?: string | null
|
|
174
|
+
} | null
|
|
175
|
+
twitter?: {
|
|
176
|
+
_type?: string
|
|
177
|
+
card?: string | null
|
|
178
|
+
site?: string | null
|
|
179
|
+
creator?: string | null
|
|
180
|
+
title?: string | null
|
|
181
|
+
description?: string | null
|
|
182
|
+
imageType?: string | null
|
|
183
|
+
image?: SeoImageInput | null
|
|
184
|
+
imageUrl?: string | null
|
|
185
|
+
} | null
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Permissive image shape accepted by buildSeoMeta — compatible with both the
|
|
190
|
+
* plugin's SanityImage and Sanity's code-generated image type (where `asset`
|
|
191
|
+
* and `alt` are optional).
|
|
192
|
+
*/
|
|
193
|
+
declare interface SeoImageInput {
|
|
194
|
+
_type?: string
|
|
195
|
+
asset?: {
|
|
196
|
+
_ref: string
|
|
197
|
+
_type: string
|
|
198
|
+
_weak?: boolean
|
|
199
|
+
[key: string]: unknown
|
|
200
|
+
}
|
|
201
|
+
hotspot?: unknown
|
|
202
|
+
crop?: unknown
|
|
203
|
+
alt?: string
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/** Structured metadata returned by buildSeoMeta(). Compatible with Next.js Metadata (App Router). */
|
|
207
|
+
export declare interface SeoMetadata {
|
|
208
|
+
title?: string | null
|
|
209
|
+
description?: string | null
|
|
210
|
+
keywords?: string[]
|
|
211
|
+
robots?: {
|
|
212
|
+
index?: boolean
|
|
213
|
+
follow?: boolean
|
|
214
|
+
googleBot?: {
|
|
215
|
+
index?: boolean
|
|
216
|
+
follow?: boolean
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
openGraph?: {
|
|
220
|
+
type?: string
|
|
221
|
+
url?: string
|
|
222
|
+
title?: string
|
|
223
|
+
description?: string
|
|
224
|
+
siteName?: string
|
|
225
|
+
images?: Array<{
|
|
226
|
+
url: string
|
|
227
|
+
width?: number
|
|
228
|
+
height?: number
|
|
229
|
+
alt?: string
|
|
230
|
+
}>
|
|
231
|
+
}
|
|
232
|
+
twitter?: {
|
|
233
|
+
card?: string
|
|
234
|
+
site?: string
|
|
235
|
+
creator?: string
|
|
236
|
+
title?: string
|
|
237
|
+
description?: string
|
|
238
|
+
images?: string[]
|
|
239
|
+
}
|
|
240
|
+
alternates?: {
|
|
241
|
+
canonical?: string
|
|
242
|
+
}
|
|
243
|
+
/** Any custom meta attributes from seo.metaAttributes */
|
|
244
|
+
other?: Record<string, string>
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
/** Default values used when SEO fields are missing. */
|
|
248
|
+
export declare interface SeoMetaDefaults {
|
|
249
|
+
title?: string
|
|
250
|
+
description?: string
|
|
251
|
+
siteName?: string
|
|
252
|
+
twitterSite?: string
|
|
253
|
+
twitterCreator?: string
|
|
254
|
+
/** Fallback image URL when no OG / Twitter image is set. */
|
|
255
|
+
ogImage?: string
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
/**
|
|
259
|
+
* Renders all SEO meta tags for a page as plain React elements.
|
|
260
|
+
* Intended to be placed inside your framework's <Head> / <head> component.
|
|
261
|
+
*
|
|
262
|
+
* Renders:
|
|
263
|
+
* - `<title>`
|
|
264
|
+
* - `<meta name="description">`
|
|
265
|
+
* - `<meta name="keywords">`
|
|
266
|
+
* - `<meta name="robots">`
|
|
267
|
+
* - OpenGraph meta tags (`og:*`)
|
|
268
|
+
* - Twitter Card meta tags (`twitter:*`)
|
|
269
|
+
* - Any custom `seo.metaAttributes` as `<meta name="..." content="...">`
|
|
270
|
+
*/
|
|
271
|
+
export declare function SeoMetaTags({
|
|
272
|
+
data,
|
|
273
|
+
baseUrl,
|
|
274
|
+
path,
|
|
275
|
+
defaults,
|
|
276
|
+
imageUrlResolver,
|
|
277
|
+
}: SeoMetaTagsProps): React_2.JSX.Element
|
|
278
|
+
|
|
279
|
+
export declare interface SeoMetaTagsProps {
|
|
280
|
+
/**
|
|
281
|
+
* The raw SEO object from Sanity.
|
|
282
|
+
* Pass `null` / `undefined` to render only the defaults.
|
|
283
|
+
*/
|
|
284
|
+
data?: Partial<SeoFields> | null
|
|
285
|
+
/**
|
|
286
|
+
* Base URL of your site, e.g. "https://example.com".
|
|
287
|
+
* Used for canonical link, og:url fallback.
|
|
288
|
+
*/
|
|
289
|
+
baseUrl?: string
|
|
290
|
+
/**
|
|
291
|
+
* Current page path, e.g. "/about".
|
|
292
|
+
* Defaults to "".
|
|
293
|
+
*/
|
|
294
|
+
path?: string
|
|
295
|
+
/**
|
|
296
|
+
* Default values used when SEO fields are missing.
|
|
297
|
+
*/
|
|
298
|
+
defaults?: BuildSeoMetaOptions['defaults']
|
|
299
|
+
/**
|
|
300
|
+
* Resolve a Sanity image asset reference to a full URL string.
|
|
301
|
+
*
|
|
302
|
+
* @example
|
|
303
|
+
* imageUrlResolver={(img) => urlFor(img).width(1200).url()}
|
|
304
|
+
*/
|
|
305
|
+
imageUrlResolver?: (image: SanityImage | SanityImageWithAlt) => string | null | undefined
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
declare type TwitterCard = (typeof VALID_TWITTER_CARDS)[number]
|
|
309
|
+
|
|
310
|
+
declare interface TwitterCardSettings {
|
|
311
|
+
_type: 'twitter'
|
|
312
|
+
card?: 'summary' | 'summary_large_image' | 'app' | 'player'
|
|
313
|
+
site?: string
|
|
314
|
+
creator?: string
|
|
315
|
+
title?: string
|
|
316
|
+
description?: string
|
|
317
|
+
imageType?: 'upload' | 'url'
|
|
318
|
+
image?: SanityImageWithAlt
|
|
319
|
+
imageUrl?: string
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
declare const VALID_OG_TYPES: readonly [
|
|
323
|
+
'website',
|
|
324
|
+
'article',
|
|
325
|
+
'profile',
|
|
326
|
+
'book',
|
|
327
|
+
'music',
|
|
328
|
+
'video',
|
|
329
|
+
'product',
|
|
330
|
+
]
|
|
331
|
+
|
|
332
|
+
declare const VALID_TWITTER_CARDS: readonly ['summary', 'summary_large_image', 'app', 'player']
|
|
333
|
+
|
|
334
|
+
export {}
|