sanity-plugin-seofields 1.0.4 → 1.0.6
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/README.md +148 -10
- package/dist/index.d.mts +16 -2
- package/dist/index.d.ts +16 -2
- package/dist/index.js +197 -172
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +197 -172
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
- package/src/plugin.ts +14 -0
- package/src/schemas/index.ts +9 -2
- package/src/schemas/types/index.ts +2 -2
- package/src/schemas/types/openGraph/index.ts +11 -6
- package/src/schemas/types/twitter/index.ts +24 -13
- package/src/types/index.ts +1 -0
- package/src/types.ts +1 -1
- package/src/utils/fieldsUtils.ts +35 -1
- package/src/utils/generaeDynamicJsonLd.ts +1 -1
- package/src/utils/seoUtils.ts +14 -14
package/README.md
CHANGED
|
@@ -9,13 +9,14 @@ A comprehensive Sanity Studio v3 plugin to manage SEO fields like meta titles, d
|
|
|
9
9
|
|
|
10
10
|
- 🎯 **Meta Tags**: Title, description, keywords, and canonical URLs
|
|
11
11
|
- 📱 **Open Graph**: Complete social media sharing optimization
|
|
12
|
-
- 🐦 **Twitter Cards**:
|
|
12
|
+
- 🐦 **X (Formerly Twitter) Cards**: X-specific meta tags with image support
|
|
13
13
|
- 🤖 **Robots Control**: Index/follow settings for search engines
|
|
14
14
|
- 🖼️ **Image Management**: Optimized image handling for social sharing
|
|
15
15
|
- 📋 **Live Preview**: Real-time SEO preview as you edit
|
|
16
16
|
- 🔧 **TypeScript Support**: Full type definitions included
|
|
17
17
|
- 📊 **Custom Attributes**: Flexible meta attribute system
|
|
18
18
|
- ✅ **Validation**: Built-in character limits and best practices
|
|
19
|
+
- 🎛️ **Field Visibility**: Hide sitewide fields on specific content types
|
|
19
20
|
|
|
20
21
|
## 📦 Installation
|
|
21
22
|
|
|
@@ -112,7 +113,7 @@ export default defineType({
|
|
|
112
113
|
}),
|
|
113
114
|
defineField({
|
|
114
115
|
name: 'twitterCard',
|
|
115
|
-
title: 'Twitter Card',
|
|
116
|
+
title: 'X (Formerly Twitter) Card',
|
|
116
117
|
type: 'twitter',
|
|
117
118
|
}),
|
|
118
119
|
defineField({
|
|
@@ -130,7 +131,7 @@ export default defineType({
|
|
|
130
131
|
| --------------- | ------------------------- | -------------------------------- |
|
|
131
132
|
| `seoFields` | Complete SEO package | Main SEO fields for any document |
|
|
132
133
|
| `openGraph` | Open Graph meta tags | Social media sharing |
|
|
133
|
-
| `twitter` | Twitter Card settings
|
|
134
|
+
| `twitter` | X (Formerly Twitter) Card settings | X-specific optimization |
|
|
134
135
|
| `metaTag` | Custom meta attributes | Advanced meta tag management |
|
|
135
136
|
| `metaAttribute` | Individual meta attribute | Building custom meta tags |
|
|
136
137
|
| `robots` | Search engine directives | Control indexing and crawling |
|
|
@@ -151,7 +152,7 @@ export default defineConfig({
|
|
|
151
152
|
|
|
152
153
|
### Advanced Configuration
|
|
153
154
|
|
|
154
|
-
You can customize field titles and descriptions,
|
|
155
|
+
You can customize field titles and descriptions, control SEO preview functionality, and manage field visibility:
|
|
155
156
|
|
|
156
157
|
```typescript
|
|
157
158
|
import seofields, {SeoFieldsPluginConfig} from 'sanity-plugin-seofields'
|
|
@@ -182,6 +183,17 @@ export default defineConfig({
|
|
|
182
183
|
description: 'Keywords that describe the content of this page',
|
|
183
184
|
},
|
|
184
185
|
},
|
|
186
|
+
// Hide sitewide fields on specific content types
|
|
187
|
+
fieldVisibility: {
|
|
188
|
+
page: {
|
|
189
|
+
hiddenFields: ['openGraphSiteName', 'twitterSite']
|
|
190
|
+
},
|
|
191
|
+
post: {
|
|
192
|
+
hiddenFields: ['openGraphSiteName', 'twitterSite']
|
|
193
|
+
}
|
|
194
|
+
},
|
|
195
|
+
// Or hide fields globally
|
|
196
|
+
defaultHiddenFields: ['openGraphSiteName', 'twitterSite']
|
|
185
197
|
} satisfies SeoFieldsPluginConfig),
|
|
186
198
|
],
|
|
187
199
|
})
|
|
@@ -189,10 +201,12 @@ export default defineConfig({
|
|
|
189
201
|
|
|
190
202
|
### Configuration Options
|
|
191
203
|
|
|
192
|
-
| Option
|
|
193
|
-
|
|
|
194
|
-
| `seoPreview`
|
|
195
|
-
| `fieldOverrides`
|
|
204
|
+
| Option | Type | Default | Description |
|
|
205
|
+
| --------------------- | --------- | ------- | ------------------------------------------- |
|
|
206
|
+
| `seoPreview` | `boolean` | `true` | Enable/disable the live SEO preview feature |
|
|
207
|
+
| `fieldOverrides` | `object` | `{}` | Customize field titles and descriptions |
|
|
208
|
+
| `fieldVisibility` | `object` | `{}` | Hide sitewide fields on specific post types |
|
|
209
|
+
| `defaultHiddenFields` | `array` | `[]` | Hide sitewide fields globally |
|
|
196
210
|
|
|
197
211
|
#### Field Configuration
|
|
198
212
|
|
|
@@ -210,6 +224,50 @@ Each field in the `fieldOverrides` object can have:
|
|
|
210
224
|
- `keywords`
|
|
211
225
|
- `metaAttributes`
|
|
212
226
|
|
|
227
|
+
#### Field Visibility Configuration
|
|
228
|
+
|
|
229
|
+
Control which fields are visible on different content types. You can hide any SEO field on any post type:
|
|
230
|
+
|
|
231
|
+
**Available field keys:**
|
|
232
|
+
- `title` - Meta Title field
|
|
233
|
+
- `description` - Meta Description field
|
|
234
|
+
- `canonicalUrl` - Canonical URL field
|
|
235
|
+
- `metaImage` - Meta Image field
|
|
236
|
+
- `keywords` - Keywords field
|
|
237
|
+
- `metaAttributes` - Custom Meta Attributes field
|
|
238
|
+
- `robots` - Robots Settings field
|
|
239
|
+
- `openGraphSiteName` - Open Graph Site Name field (sitewide)
|
|
240
|
+
- `twitterSite` - X (Formerly Twitter) Site Handle field (sitewide)
|
|
241
|
+
|
|
242
|
+
**Example configurations:**
|
|
243
|
+
|
|
244
|
+
```typescript
|
|
245
|
+
// Hide fields globally
|
|
246
|
+
seofields({
|
|
247
|
+
defaultHiddenFields: ['openGraphSiteName', 'twitterSite', 'keywords']
|
|
248
|
+
})
|
|
249
|
+
|
|
250
|
+
// Hide fields on specific content types
|
|
251
|
+
seofields({
|
|
252
|
+
fieldVisibility: {
|
|
253
|
+
page: {
|
|
254
|
+
hiddenFields: ['openGraphSiteName', 'twitterSite', 'keywords']
|
|
255
|
+
},
|
|
256
|
+
post: {
|
|
257
|
+
hiddenFields: ['openGraphSiteName', 'metaAttributes']
|
|
258
|
+
},
|
|
259
|
+
product: {
|
|
260
|
+
hiddenFields: ['canonicalUrl', 'robots']
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
})
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
This is particularly useful when you want to:
|
|
267
|
+
- Manage sitewide settings (like site name and Twitter handle) in a dedicated Site Settings document
|
|
268
|
+
- Simplify the editing experience by hiding fields that aren't relevant for certain content types
|
|
269
|
+
- Create different SEO workflows for different content types
|
|
270
|
+
|
|
213
271
|
### Field Specifications
|
|
214
272
|
|
|
215
273
|
#### Meta Title
|
|
@@ -238,12 +296,19 @@ Each field in the `fieldOverrides` object can have:
|
|
|
238
296
|
- **Best Practice**: Use the preferred URL for the page to avoid duplicate content issues
|
|
239
297
|
- **Required**: Should match the actual page URL for consistency
|
|
240
298
|
|
|
241
|
-
#### Twitter Card Image
|
|
299
|
+
#### X (Formerly Twitter) Card Image
|
|
242
300
|
|
|
243
301
|
- **Summary Card**: Minimum 120x120px
|
|
244
302
|
- **Large Image**: Minimum 280x150px
|
|
245
303
|
- **Required**: Alt text for accessibility
|
|
246
304
|
|
|
305
|
+
#### Twitter Card Creator
|
|
306
|
+
|
|
307
|
+
- **Purpose**: Attribution to content creator on Twitter
|
|
308
|
+
- **Format**: Twitter handle with @ symbol (e.g., @creator)
|
|
309
|
+
- **Usage**: Identifies the individual author of the content
|
|
310
|
+
- **Best Practice**: Use actual Twitter handles for proper attribution
|
|
311
|
+
|
|
247
312
|
## 💻 TypeScript Usage
|
|
248
313
|
|
|
249
314
|
The plugin includes full TypeScript support:
|
|
@@ -290,6 +355,14 @@ const seoData: SeoFields = {
|
|
|
290
355
|
url: 'https://example.com/page',
|
|
291
356
|
type: 'website',
|
|
292
357
|
},
|
|
358
|
+
twitter: {
|
|
359
|
+
_type: 'twitter',
|
|
360
|
+
card: 'summary_large_image',
|
|
361
|
+
site: '@example',
|
|
362
|
+
creator: '@creator',
|
|
363
|
+
title: 'Twitter Title',
|
|
364
|
+
description: 'Twitter description',
|
|
365
|
+
},
|
|
293
366
|
}
|
|
294
367
|
```
|
|
295
368
|
|
|
@@ -301,6 +374,8 @@ import type {
|
|
|
301
374
|
SeoFieldsPluginConfig,
|
|
302
375
|
SeoFieldConfig,
|
|
303
376
|
SeoFieldKeys,
|
|
377
|
+
SitewideFieldKeys,
|
|
378
|
+
FieldVisibilityConfig,
|
|
304
379
|
OpenGraphSettings,
|
|
305
380
|
TwitterCardSettings,
|
|
306
381
|
MetaAttribute,
|
|
@@ -310,7 +385,53 @@ import type {
|
|
|
310
385
|
} from 'sanity-plugin-seofields'
|
|
311
386
|
```
|
|
312
387
|
|
|
313
|
-
##
|
|
388
|
+
## 🎛️ Field Visibility Feature
|
|
389
|
+
|
|
390
|
+
The field visibility feature allows you to hide any SEO field on specific content types. This is perfect for managing sitewide settings in a dedicated Site Settings document or creating customized editing experiences for different content types.
|
|
391
|
+
|
|
392
|
+
### Quick Example
|
|
393
|
+
|
|
394
|
+
```typescript
|
|
395
|
+
// Hide specific fields on different content types
|
|
396
|
+
seofields({
|
|
397
|
+
fieldVisibility: {
|
|
398
|
+
page: {
|
|
399
|
+
hiddenFields: ['openGraphSiteName', 'twitterSite', 'keywords']
|
|
400
|
+
},
|
|
401
|
+
post: {
|
|
402
|
+
hiddenFields: ['openGraphSiteName', 'metaAttributes']
|
|
403
|
+
},
|
|
404
|
+
product: {
|
|
405
|
+
hiddenFields: ['canonicalUrl', 'robots']
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
})
|
|
409
|
+
```
|
|
410
|
+
|
|
411
|
+
### Site Settings Integration
|
|
412
|
+
|
|
413
|
+
Create a Site Settings document to manage sitewide fields:
|
|
414
|
+
|
|
415
|
+
```typescript
|
|
416
|
+
// schemas/siteSettings.ts
|
|
417
|
+
export default defineType({
|
|
418
|
+
name: 'siteSettings',
|
|
419
|
+
title: 'Site Settings',
|
|
420
|
+
type: 'document',
|
|
421
|
+
fields: [
|
|
422
|
+
defineField({
|
|
423
|
+
name: 'openGraphSiteName',
|
|
424
|
+
title: 'Open Graph Site Name',
|
|
425
|
+
type: 'string',
|
|
426
|
+
}),
|
|
427
|
+
defineField({
|
|
428
|
+
name: 'twitterSite',
|
|
429
|
+
title: 'X (Formerly Twitter) Site Handle',
|
|
430
|
+
type: 'string',
|
|
431
|
+
}),
|
|
432
|
+
],
|
|
433
|
+
})
|
|
434
|
+
```
|
|
314
435
|
|
|
315
436
|
### Complete SEO Setup
|
|
316
437
|
|
|
@@ -384,6 +505,12 @@ export function SEOHead({seo}: SEOProps) {
|
|
|
384
505
|
{seo.twitter?.card && (
|
|
385
506
|
<meta name="twitter:card" content={seo.twitter.card} />
|
|
386
507
|
)}
|
|
508
|
+
{seo.twitter?.site && (
|
|
509
|
+
<meta name="twitter:site" content={seo.twitter.site} />
|
|
510
|
+
)}
|
|
511
|
+
{seo.twitter?.creator && (
|
|
512
|
+
<meta name="twitter:creator" content={seo.twitter.creator} />
|
|
513
|
+
)}
|
|
387
514
|
|
|
388
515
|
{/* Robots */}
|
|
389
516
|
{seo.robots?.noIndex && <meta name="robots" content="noindex" />}
|
|
@@ -422,6 +549,17 @@ export function SEO({seo}: SEOProps) {
|
|
|
422
549
|
<meta property="og:description" content={seo?.openGraph?.description} />
|
|
423
550
|
<meta property="og:url" content={seo?.openGraph?.url} />
|
|
424
551
|
<meta property="og:type" content={seo?.openGraph?.type || 'website'} />
|
|
552
|
+
|
|
553
|
+
{/* Twitter */}
|
|
554
|
+
{seo?.twitter?.card && (
|
|
555
|
+
<meta name="twitter:card" content={seo.twitter.card} />
|
|
556
|
+
)}
|
|
557
|
+
{seo?.twitter?.site && (
|
|
558
|
+
<meta name="twitter:site" content={seo.twitter.site} />
|
|
559
|
+
)}
|
|
560
|
+
{seo?.twitter?.creator && (
|
|
561
|
+
<meta name="twitter:creator" content={seo.twitter.creator} />
|
|
562
|
+
)}
|
|
425
563
|
</Helmet>
|
|
426
564
|
)
|
|
427
565
|
}
|
package/dist/index.d.mts
CHANGED
|
@@ -2,6 +2,8 @@ import {ObjectDefinition} from 'sanity'
|
|
|
2
2
|
import {Plugin as Plugin_2} from 'sanity'
|
|
3
3
|
import {PreviewConfig} from 'sanity'
|
|
4
4
|
|
|
5
|
+
export declare type AllFieldKeys = SeoFieldKeys | SitewideFieldKeys
|
|
6
|
+
|
|
5
7
|
export declare function allSchemas(config?: SeoFieldsPluginConfig): (
|
|
6
8
|
| ({
|
|
7
9
|
type: 'object'
|
|
@@ -56,6 +58,11 @@ export declare function allSchemas(config?: SeoFieldsPluginConfig): (
|
|
|
56
58
|
|
|
57
59
|
export declare const defaultSeoValidationRules: SeoValidationRules
|
|
58
60
|
|
|
61
|
+
export declare interface FieldVisibilityConfig {
|
|
62
|
+
hiddenFields?: AllFieldKeys[]
|
|
63
|
+
postType?: string
|
|
64
|
+
}
|
|
65
|
+
|
|
59
66
|
export declare const isMetaAttribute: (obj: any) => obj is MetaAttribute
|
|
60
67
|
|
|
61
68
|
export declare const isOpenGraphSettings: (obj: any) => obj is OpenGraphSettings
|
|
@@ -99,7 +106,7 @@ export declare const metaTagSchema: {
|
|
|
99
106
|
preview?: PreviewConfig<Record<string, string>, Record<never, any>> | undefined
|
|
100
107
|
}
|
|
101
108
|
|
|
102
|
-
export declare
|
|
109
|
+
export declare function openGraphSchema(config?: SeoFieldsPluginConfig): {
|
|
103
110
|
type: 'object'
|
|
104
111
|
name: 'openGraph'
|
|
105
112
|
} & Omit<ObjectDefinition, 'preview'> & {
|
|
@@ -166,6 +173,7 @@ export declare type SeoFieldKeys =
|
|
|
166
173
|
| 'metaImage'
|
|
167
174
|
| 'keywords'
|
|
168
175
|
| 'metaAttributes'
|
|
176
|
+
| 'robots'
|
|
169
177
|
|
|
170
178
|
export declare interface SeoFields {
|
|
171
179
|
_type: 'seoFields'
|
|
@@ -188,6 +196,10 @@ export declare interface SeoFieldsPluginConfig {
|
|
|
188
196
|
fieldOverrides?: {
|
|
189
197
|
[key in SeoFieldKeys]?: SeoFieldConfig
|
|
190
198
|
}
|
|
199
|
+
fieldVisibility?: {
|
|
200
|
+
[postType: string]: FieldVisibilityConfig
|
|
201
|
+
}
|
|
202
|
+
defaultHiddenFields?: AllFieldKeys[]
|
|
191
203
|
}
|
|
192
204
|
|
|
193
205
|
export declare function seoFieldsSchema(config?: SeoFieldsPluginConfig): {
|
|
@@ -220,6 +232,8 @@ export declare interface SeoValidationRules {
|
|
|
220
232
|
}
|
|
221
233
|
}
|
|
222
234
|
|
|
235
|
+
export declare type SitewideFieldKeys = 'openGraphSiteName' | 'twitterSite'
|
|
236
|
+
|
|
223
237
|
export declare interface TwitterCardSettings {
|
|
224
238
|
_type: 'twitter'
|
|
225
239
|
card?: 'summary' | 'summary_large_image' | 'app' | 'player'
|
|
@@ -229,7 +243,7 @@ export declare interface TwitterCardSettings {
|
|
|
229
243
|
image?: SanityImageWithAlt
|
|
230
244
|
}
|
|
231
245
|
|
|
232
|
-
export declare
|
|
246
|
+
export declare function twitterSchema(config?: SeoFieldsPluginConfig): {
|
|
233
247
|
type: 'object'
|
|
234
248
|
name: 'twitter'
|
|
235
249
|
} & Omit<ObjectDefinition, 'preview'> & {
|
package/dist/index.d.ts
CHANGED
|
@@ -2,6 +2,8 @@ import {ObjectDefinition} from 'sanity'
|
|
|
2
2
|
import {Plugin as Plugin_2} from 'sanity'
|
|
3
3
|
import {PreviewConfig} from 'sanity'
|
|
4
4
|
|
|
5
|
+
export declare type AllFieldKeys = SeoFieldKeys | SitewideFieldKeys
|
|
6
|
+
|
|
5
7
|
export declare function allSchemas(config?: SeoFieldsPluginConfig): (
|
|
6
8
|
| ({
|
|
7
9
|
type: 'object'
|
|
@@ -56,6 +58,11 @@ export declare function allSchemas(config?: SeoFieldsPluginConfig): (
|
|
|
56
58
|
|
|
57
59
|
export declare const defaultSeoValidationRules: SeoValidationRules
|
|
58
60
|
|
|
61
|
+
export declare interface FieldVisibilityConfig {
|
|
62
|
+
hiddenFields?: AllFieldKeys[]
|
|
63
|
+
postType?: string
|
|
64
|
+
}
|
|
65
|
+
|
|
59
66
|
export declare const isMetaAttribute: (obj: any) => obj is MetaAttribute
|
|
60
67
|
|
|
61
68
|
export declare const isOpenGraphSettings: (obj: any) => obj is OpenGraphSettings
|
|
@@ -99,7 +106,7 @@ export declare const metaTagSchema: {
|
|
|
99
106
|
preview?: PreviewConfig<Record<string, string>, Record<never, any>> | undefined
|
|
100
107
|
}
|
|
101
108
|
|
|
102
|
-
export declare
|
|
109
|
+
export declare function openGraphSchema(config?: SeoFieldsPluginConfig): {
|
|
103
110
|
type: 'object'
|
|
104
111
|
name: 'openGraph'
|
|
105
112
|
} & Omit<ObjectDefinition, 'preview'> & {
|
|
@@ -166,6 +173,7 @@ export declare type SeoFieldKeys =
|
|
|
166
173
|
| 'metaImage'
|
|
167
174
|
| 'keywords'
|
|
168
175
|
| 'metaAttributes'
|
|
176
|
+
| 'robots'
|
|
169
177
|
|
|
170
178
|
export declare interface SeoFields {
|
|
171
179
|
_type: 'seoFields'
|
|
@@ -188,6 +196,10 @@ export declare interface SeoFieldsPluginConfig {
|
|
|
188
196
|
fieldOverrides?: {
|
|
189
197
|
[key in SeoFieldKeys]?: SeoFieldConfig
|
|
190
198
|
}
|
|
199
|
+
fieldVisibility?: {
|
|
200
|
+
[postType: string]: FieldVisibilityConfig
|
|
201
|
+
}
|
|
202
|
+
defaultHiddenFields?: AllFieldKeys[]
|
|
191
203
|
}
|
|
192
204
|
|
|
193
205
|
export declare function seoFieldsSchema(config?: SeoFieldsPluginConfig): {
|
|
@@ -220,6 +232,8 @@ export declare interface SeoValidationRules {
|
|
|
220
232
|
}
|
|
221
233
|
}
|
|
222
234
|
|
|
235
|
+
export declare type SitewideFieldKeys = 'openGraphSiteName' | 'twitterSite'
|
|
236
|
+
|
|
223
237
|
export declare interface TwitterCardSettings {
|
|
224
238
|
_type: 'twitter'
|
|
225
239
|
card?: 'summary' | 'summary_large_image' | 'app' | 'player'
|
|
@@ -229,7 +243,7 @@ export declare interface TwitterCardSettings {
|
|
|
229
243
|
image?: SanityImageWithAlt
|
|
230
244
|
}
|
|
231
245
|
|
|
232
|
-
export declare
|
|
246
|
+
export declare function twitterSchema(config?: SeoFieldsPluginConfig): {
|
|
233
247
|
type: 'object'
|
|
234
248
|
name: 'twitter'
|
|
235
249
|
} & Omit<ObjectDefinition, 'preview'> & {
|