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 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**: Twitter-specific meta tags with image support
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 | Twitter-specific optimization |
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, and control SEO preview functionality:
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 | Type | Default | Description |
193
- | ---------------- | --------- | ------- | ------------------------------------------- |
194
- | `seoPreview` | `boolean` | `true` | Enable/disable the live SEO preview feature |
195
- | `fieldOverrides` | `object` | `{}` | Customize field titles and descriptions |
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
- ## 🎯 Examples
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 const openGraphSchema: {
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 const twitterSchema: {
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 const openGraphSchema: {
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 const twitterSchema: {
246
+ export declare function twitterSchema(config?: SeoFieldsPluginConfig): {
233
247
  type: 'object'
234
248
  name: 'twitter'
235
249
  } & Omit<ObjectDefinition, 'preview'> & {