sanity-plugin-seofields 1.2.4 → 1.2.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.
Files changed (49) hide show
  1. package/dist/index.cjs +2604 -0
  2. package/dist/index.cjs.map +1 -0
  3. package/dist/index.d.cts +422 -0
  4. package/dist/index.d.ts +339 -492
  5. package/dist/index.js +1284 -2013
  6. package/dist/index.js.map +1 -1
  7. package/dist/next.cjs +182 -0
  8. package/dist/next.cjs.map +1 -0
  9. package/dist/next.d.cts +241 -0
  10. package/dist/next.d.ts +202 -295
  11. package/dist/next.js +110 -70
  12. package/dist/next.js.map +1 -1
  13. package/dist/types-B91ena4g.d.cts +89 -0
  14. package/dist/types-B91ena4g.d.ts +89 -0
  15. package/package.json +37 -18
  16. package/dist/index.d.mts +0 -575
  17. package/dist/index.mjs +0 -3292
  18. package/dist/index.mjs.map +0 -1
  19. package/dist/next.d.mts +0 -334
  20. package/dist/next.mjs +0 -102
  21. package/dist/next.mjs.map +0 -1
  22. package/sanity.json +0 -8
  23. package/src/components/SeoHealthDashboard.tsx +0 -1568
  24. package/src/components/SeoHealthPane.tsx +0 -81
  25. package/src/components/SeoHealthTool.tsx +0 -11
  26. package/src/components/SeoPreview.tsx +0 -178
  27. package/src/components/meta/MetaDescription.tsx +0 -39
  28. package/src/components/meta/MetaTitle.tsx +0 -44
  29. package/src/components/openGraph/OgDescription.tsx +0 -46
  30. package/src/components/openGraph/OgTitle.tsx +0 -45
  31. package/src/components/twitter/twitterDescription.tsx +0 -45
  32. package/src/components/twitter/twitterTitle.tsx +0 -45
  33. package/src/helpers/SeoMetaTags.tsx +0 -154
  34. package/src/helpers/seoMeta.ts +0 -283
  35. package/src/index.ts +0 -26
  36. package/src/next.ts +0 -12
  37. package/src/plugin.ts +0 -344
  38. package/src/schemas/index.ts +0 -121
  39. package/src/schemas/types/index.ts +0 -20
  40. package/src/schemas/types/metaAttribute/index.ts +0 -60
  41. package/src/schemas/types/metaTag/index.ts +0 -17
  42. package/src/schemas/types/openGraph/index.ts +0 -114
  43. package/src/schemas/types/robots/index.ts +0 -26
  44. package/src/schemas/types/twitter/index.ts +0 -108
  45. package/src/types.ts +0 -108
  46. package/src/utils/fieldsUtils.ts +0 -160
  47. package/src/utils/seoUtils.ts +0 -423
  48. package/src/utils/utils.ts +0 -9
  49. package/v2-incompatible.js +0 -11
@@ -1,121 +0,0 @@
1
- import {defineField, defineType, SchemaTypeDefinition} from 'sanity'
2
-
3
- import MetaDescription from '../components/meta/MetaDescription'
4
- import MetaTitle from '../components/meta/MetaTitle'
5
- import SeoPreview from '../components/SeoPreview'
6
- import {SeoFieldsPluginConfig} from '../plugin'
7
- import {getFieldHiddenFunction, getFieldInfo} from '../utils/fieldsUtils'
8
- import {isEmpty} from '../utils/utils'
9
- import openGraph from './types/openGraph'
10
- import twitter from './types/twitter'
11
-
12
- export default function seoFieldsSchema(config: SeoFieldsPluginConfig = {}): SchemaTypeDefinition {
13
- return defineType({
14
- name: 'seoFields',
15
- title: 'SEO Fields',
16
- type: 'object',
17
- fields: [
18
- defineField({
19
- name: 'robots',
20
- title: 'Robots Settings',
21
- type: 'robots', // Use the separate robots type here
22
- hidden: getFieldHiddenFunction('robots', config),
23
- }),
24
- // 👇 conditionally spread preview field
25
- ...((typeof config.seoPreview === 'boolean' && config.seoPreview) ||
26
- (typeof config.seoPreview === 'object' && !isEmpty(config.seoPreview))
27
- ? [
28
- defineField({
29
- name: 'preview',
30
- title: 'SEO Preview',
31
- type: 'string',
32
- components: {input: SeoPreview},
33
- options: {
34
- baseUrl: config.baseUrl || 'https://www.example.com',
35
- ...(typeof config.seoPreview === 'object' &&
36
- config.seoPreview &&
37
- config.seoPreview.prefix
38
- ? {prefix: config.seoPreview.prefix}
39
- : {}),
40
- } as Record<string, unknown>,
41
- // Use a readOnly field to prevent editing
42
- // This field is just for preview purposes
43
- initialValue: '' as string, // Set an initial value
44
- readOnly: true,
45
- }),
46
- ]
47
- : []),
48
-
49
- defineField({
50
- name: 'title',
51
- ...getFieldInfo('title', config.fieldOverrides),
52
- // title: 'Meta Title',
53
- type: 'string',
54
- // description:
55
- // 'The meta title is displayed in search engine results as the clickable headline for a given result. It should be concise and accurately reflect the content of the page.',
56
- components: {
57
- input: MetaTitle,
58
- },
59
- // validation: (Rule) => Rule.max(60).warning('Meta title should be under 60 characters.'),
60
- hidden: getFieldHiddenFunction('title', config),
61
- }),
62
- defineField({
63
- name: 'description',
64
- ...getFieldInfo('description', config.fieldOverrides),
65
- // title: 'Meta Description',
66
- // description:
67
- // 'Provide a concise summary of the page content. This description may be used by search engines in search results.',
68
- type: 'text',
69
- rows: 3,
70
- components: {
71
- input: MetaDescription,
72
- },
73
- // validation: (Rule) => Rule.max(160).warning('Meta description should be under 160 characters.'),
74
- hidden: getFieldHiddenFunction('description', config),
75
- }),
76
- defineField({
77
- name: 'metaImage',
78
- ...getFieldInfo('metaImage', config.fieldOverrides),
79
- // title: 'Meta Image',
80
- // description:
81
- // 'Upload an image that represents the content of the page. This image may be used in social media previews and search engine results.',
82
- type: 'image',
83
- options: {
84
- hotspot: true,
85
- },
86
- hidden: getFieldHiddenFunction('metaImage', config),
87
- }),
88
- defineField({
89
- name: 'metaAttributes',
90
- // title: 'Additional Meta Attributes',
91
- ...getFieldInfo('metaAttributes', config.fieldOverrides),
92
- type: 'array',
93
- of: [{type: 'metaAttribute'}],
94
- // description:
95
- // 'Add custom meta attributes to the head of the document for additional SEO and social media integration.',
96
- hidden: getFieldHiddenFunction('metaAttributes', config),
97
- }),
98
- defineField({
99
- name: 'keywords',
100
- ...getFieldInfo('keywords', config.fieldOverrides),
101
- title: 'Keywords',
102
- type: 'array',
103
- of: [{type: 'string'}],
104
- description:
105
- 'Add relevant keywords for this page. These keywords will be used for SEO purposes.',
106
- hidden: getFieldHiddenFunction('keywords', config),
107
- }),
108
- defineField({
109
- name: 'canonicalUrl',
110
- ...getFieldInfo('canonicalUrl', config.fieldOverrides),
111
- title: 'Canonical URL',
112
- type: 'url',
113
- description:
114
- 'Specify the canonical URL for this page. This helps prevent duplicate content issues by indicating the preferred version of a page.',
115
- hidden: getFieldHiddenFunction('canonicalUrl', config),
116
- }),
117
- openGraph(config) as any,
118
- twitter(config) as any,
119
- ],
120
- })
121
- }
@@ -1,20 +0,0 @@
1
- import {SchemaTypeDefinition} from 'sanity'
2
-
3
- import {SeoFieldsPluginConfig} from '../../plugin'
4
- import seoFields from '..'
5
- import metaAttribute from './metaAttribute'
6
- import metaTag from './metaTag'
7
- import openGraph from './openGraph'
8
- import robots from './robots'
9
- import twitter from './twitter'
10
-
11
- export default function types(config: SeoFieldsPluginConfig = {}): SchemaTypeDefinition[] {
12
- return [
13
- seoFields(config), // pass config here
14
- openGraph(config), // pass config here
15
- twitter(config), // pass config here
16
- metaAttribute as SchemaTypeDefinition,
17
- metaTag,
18
- robots,
19
- ]
20
- }
@@ -1,60 +0,0 @@
1
- import {defineField, defineType} from 'sanity'
2
-
3
- export default defineType({
4
- name: 'metaAttribute',
5
- title: 'Meta Attribute',
6
- type: 'object',
7
- fields: [
8
- defineField({
9
- name: 'key',
10
- title: 'Attribute Name',
11
- type: 'string',
12
- }),
13
- defineField({
14
- name: 'type',
15
- title: 'Attribute Value Type',
16
- type: 'string',
17
- options: {
18
- list: [
19
- {title: 'String', value: 'string'},
20
- {title: 'Image', value: 'image'},
21
- ],
22
- },
23
- initialValue: 'string',
24
- }),
25
- defineField({
26
- name: 'value',
27
- title: 'Attribute Value',
28
- type: 'string',
29
- hidden: ({parent}) => parent?.type === 'image',
30
- }),
31
- defineField({
32
- name: 'image',
33
- title: 'Attribute Image Value',
34
- type: 'image',
35
- hidden: ({parent}) => parent?.type === 'string',
36
- }),
37
- ],
38
- preview: {
39
- select: {
40
- attributeName: 'key',
41
- attributeValueString: 'value',
42
- attributeValueImage: 'image',
43
- },
44
- prepare({attributeName, attributeValueString, attributeValueImage}) {
45
- let subtitle = ''
46
- if (attributeValueString) {
47
- subtitle = `Value: ${attributeValueString}`
48
- } else if (attributeValueImage) {
49
- subtitle = 'Value: [Image]'
50
- } else {
51
- subtitle = 'No Attribute Value'
52
- }
53
- return {
54
- title: attributeName || 'No Attribute Name',
55
- subtitle: subtitle,
56
- media: attributeValueImage,
57
- }
58
- },
59
- },
60
- })
@@ -1,17 +0,0 @@
1
- import {defineType} from 'sanity'
2
-
3
- export default defineType({
4
- name: 'metaTag',
5
- title: 'Meta Tag',
6
- type: 'object',
7
- fields: [
8
- {
9
- name: 'metaAttributes',
10
- title: 'Meta Attributes',
11
- type: 'array',
12
- of: [{type: 'metaAttribute'}],
13
- description:
14
- 'Add custom meta attributes to the head of the document for additional SEO and social media integration.',
15
- },
16
- ],
17
- })
@@ -1,114 +0,0 @@
1
- import {defineField, defineType, SchemaTypeDefinition} from 'sanity'
2
-
3
- import OgDescription from '../../../components/openGraph/OgDescription'
4
- import OgTitle from '../../../components/openGraph/OgTitle'
5
- import {SeoFieldsPluginConfig} from '../../../plugin'
6
- import {getFieldHiddenFunction, getFieldInfo} from '../../../utils/fieldsUtils'
7
-
8
- export default function openGraph(config: SeoFieldsPluginConfig = {}): SchemaTypeDefinition {
9
- return defineType({
10
- name: 'openGraph',
11
- title: 'Open Graph Settings',
12
- type: 'object',
13
- fields: [
14
- defineField({
15
- name: 'url',
16
- type: 'url',
17
- ...getFieldInfo('openGraphUrl', config.fieldOverrides),
18
- hidden: getFieldHiddenFunction('openGraphUrl', config),
19
- description:
20
- 'The canonical URL of the page. This should be the full URL including protocol (https://).',
21
- }),
22
- defineField({
23
- name: 'title',
24
- ...getFieldInfo('openGraphTitle', config.fieldOverrides),
25
- type: 'string',
26
- hidden: getFieldHiddenFunction('openGraphTitle', config),
27
- components: {
28
- input: OgTitle, // Can also wrap with a string input + preview
29
- },
30
- }),
31
- defineField({
32
- name: 'description',
33
- ...getFieldInfo('openGraphDescription', config.fieldOverrides),
34
- type: 'text',
35
- rows: 3,
36
- hidden: getFieldHiddenFunction('openGraphDescription', config),
37
- components: {
38
- input: OgDescription, // Can also wrap with a text area + preview
39
- },
40
- }),
41
- defineField({
42
- name: 'siteName',
43
- ...getFieldInfo('openGraphSiteName', config.fieldOverrides),
44
- type: 'string',
45
- hidden: getFieldHiddenFunction('openGraphSiteName', config),
46
- }),
47
- defineField({
48
- name: 'type',
49
- ...getFieldInfo('openGraphType', config.fieldOverrides),
50
- type: 'string',
51
- options: {
52
- list: [
53
- {title: 'Website', value: 'website'},
54
- {title: 'Article', value: 'article'},
55
- {title: 'Profile', value: 'profile'},
56
- {title: 'Book', value: 'book'},
57
- {title: 'Music', value: 'music'},
58
- {title: 'Video', value: 'video'},
59
- {title: 'Product', value: 'product'},
60
- ],
61
- // layout: 'radio', // Display as radio buttons
62
- },
63
- hidden: getFieldHiddenFunction('openGraphType', config),
64
- initialValue: 'website',
65
- }),
66
- defineField({
67
- name: 'imageType',
68
- ...getFieldInfo('openGraphImageType', config.fieldOverrides),
69
- type: 'string',
70
- options: {
71
- list: [
72
- {title: 'Upload Image', value: 'upload'},
73
- {title: 'Image URL', value: 'url'},
74
- ],
75
- },
76
- hidden: getFieldHiddenFunction('openGraphImage', config),
77
- initialValue: 'upload',
78
- }),
79
- defineField({
80
- name: 'image',
81
- ...getFieldInfo('openGraphImage', config.fieldOverrides),
82
- type: 'image',
83
- options: {
84
- hotspot: true,
85
- },
86
- fields: [
87
- defineField({
88
- name: 'alt',
89
- title: 'Image Alt Text',
90
- type: 'string',
91
- description: 'A description of the image for accessibility purposes.',
92
- }),
93
- ],
94
- hidden: (context) => {
95
- const {parent} = context
96
- if (parent?.imageType !== 'upload') return true
97
- const hiddenFn = getFieldHiddenFunction('openGraphImage', config)
98
- return typeof hiddenFn === 'function' ? hiddenFn(context) : hiddenFn
99
- },
100
- }),
101
- defineField({
102
- name: 'imageUrl',
103
- ...getFieldInfo('openGraphImageUrl', config.fieldOverrides),
104
- type: 'url',
105
- hidden: (context) => {
106
- const {parent} = context
107
- if (parent?.imageType !== 'url') return true
108
- const hiddenFn = getFieldHiddenFunction('openGraphImage', config)
109
- return typeof hiddenFn === 'function' ? hiddenFn(context) : hiddenFn
110
- },
111
- }),
112
- ],
113
- })
114
- }
@@ -1,26 +0,0 @@
1
- import {defineField, defineType} from 'sanity'
2
-
3
- export default defineType({
4
- name: 'robots',
5
- title: 'Robots Settings',
6
- type: 'object',
7
- fields: [
8
- defineField({
9
- name: 'noIndex',
10
- title: 'No Index',
11
- type: 'boolean',
12
- initialValue: false,
13
- description:
14
- 'Enable this to prevent search engines from indexing this page. The page will not appear in search results.',
15
- }),
16
- defineField({
17
- name: 'noFollow',
18
- title: 'No Follow',
19
- type: 'boolean',
20
- initialValue: false,
21
- description:
22
- 'Enable this to prevent search engines from following links on this page. Links will not pass SEO value.',
23
- }),
24
- ],
25
- description: 'Select how search engines should index and follow links on this page.',
26
- })
@@ -1,108 +0,0 @@
1
- import {defineField, defineType, SchemaTypeDefinition} from 'sanity'
2
-
3
- import TwitterDescription from '../../../components/twitter/twitterDescription'
4
- import TwitterTitle from '../../../components/twitter/twitterTitle'
5
- import {SeoFieldsPluginConfig} from '../../../plugin'
6
- import {getFieldHiddenFunction, getFieldInfo} from '../../../utils/fieldsUtils'
7
-
8
- export default function twitter(config: SeoFieldsPluginConfig = {}): SchemaTypeDefinition {
9
- return defineType({
10
- name: 'twitter',
11
- title: 'X (Formerly Twitter)',
12
- type: 'object',
13
- fields: [
14
- defineField({
15
- name: 'card',
16
- ...getFieldInfo('twitterCard', config.fieldOverrides),
17
- type: 'string',
18
- options: {
19
- list: [
20
- {title: 'Summary', value: 'summary'},
21
- {title: 'Summary with Large Image', value: 'summary_large_image'},
22
- {title: 'App', value: 'app'},
23
- {title: 'Player', value: 'player'},
24
- ],
25
- },
26
- hidden: getFieldHiddenFunction('twitterCard', config),
27
- initialValue: 'summary_large_image', // good default
28
- }),
29
- defineField({
30
- name: 'site',
31
- ...getFieldInfo('twitterSite', config.fieldOverrides),
32
- type: 'string',
33
- hidden: getFieldHiddenFunction('twitterSite', config),
34
- }),
35
- defineField({
36
- name: 'creator',
37
- type: 'string',
38
- ...getFieldInfo('twitterCreator', config.fieldOverrides),
39
- hidden: getFieldHiddenFunction('twitterCreator', config),
40
- }),
41
- defineField({
42
- name: 'title',
43
- type: 'string',
44
- ...getFieldInfo('twitterTitle', config.fieldOverrides),
45
- hidden: getFieldHiddenFunction('twitterTitle', config),
46
- components: {
47
- input: TwitterTitle,
48
- },
49
- }),
50
- defineField({
51
- name: 'description',
52
- type: 'text',
53
- rows: 3,
54
- ...getFieldInfo('twitterDescription', config.fieldOverrides),
55
- hidden: getFieldHiddenFunction('twitterDescription', config),
56
- components: {
57
- input: TwitterDescription,
58
- },
59
- }),
60
- defineField({
61
- name: 'imageType',
62
- ...getFieldInfo('twitterImageType', config.fieldOverrides),
63
- type: 'string',
64
- options: {
65
- list: [
66
- {title: 'Upload Image', value: 'upload'},
67
- {title: 'Image URL', value: 'url'},
68
- ],
69
- },
70
- hidden: getFieldHiddenFunction('twitterImage', config),
71
- initialValue: 'upload',
72
- }),
73
- defineField({
74
- name: 'image',
75
- ...getFieldInfo('twitterImage', config.fieldOverrides),
76
- type: 'image',
77
- options: {
78
- hotspot: true,
79
- },
80
- fields: [
81
- defineField({
82
- name: 'alt',
83
- title: 'Image Alt Text',
84
- type: 'string',
85
- description: 'A description of the image for accessibility purposes.',
86
- }),
87
- ],
88
- hidden: (context) => {
89
- const {parent} = context
90
- if (parent?.imageType !== 'upload') return true
91
- const hiddenFn = getFieldHiddenFunction('twitterImage', config)
92
- return typeof hiddenFn === 'function' ? hiddenFn(context) : hiddenFn
93
- },
94
- }),
95
- defineField({
96
- name: 'imageUrl',
97
- ...getFieldInfo('twitterImageUrl', config.fieldOverrides),
98
- type: 'url',
99
- hidden: (context) => {
100
- const {parent} = context
101
- if (parent?.imageType !== 'url') return true
102
- const hiddenFn = getFieldHiddenFunction('twitterImage', config)
103
- return typeof hiddenFn === 'function' ? hiddenFn(context) : hiddenFn
104
- },
105
- }),
106
- ],
107
- })
108
- }
package/src/types.ts DELETED
@@ -1,108 +0,0 @@
1
- // TypeScript interfaces for SEO Fields Plugin
2
-
3
- // Base Sanity types
4
- export interface SanityImage {
5
- _type: 'image'
6
- asset: {
7
- _ref: string
8
- _type: 'reference'
9
- }
10
- hotspot?: {
11
- x: number
12
- y: number
13
- height: number
14
- width: number
15
- }
16
- crop?: {
17
- top: number
18
- bottom: number
19
- left: number
20
- right: number
21
- }
22
- alt?: string
23
- }
24
-
25
- export interface SanityImageWithAlt extends SanityImage {
26
- alt: string
27
- }
28
-
29
- // Robots settings
30
- export interface RobotsSettings {
31
- noIndex?: boolean
32
- noFollow?: boolean
33
- }
34
-
35
- // Meta Attribute
36
- export interface MetaAttribute {
37
- _type: 'metaAttribute'
38
- key?: string
39
- type?: 'string' | 'image'
40
- value?: string
41
- image?: SanityImage
42
- }
43
-
44
- // Open Graph settings
45
- export interface OpenGraphSettings {
46
- _type: 'openGraph'
47
- /** The canonical URL for OpenGraph (og:url). Maps to the `url` field in Sanity. */
48
- url?: string
49
- title?: string
50
- description?: string
51
- siteName?: string
52
- type?: 'website' | 'article' | 'profile' | 'book' | 'music' | 'video' | 'product'
53
- imageType?: 'upload' | 'url'
54
- image?: SanityImageWithAlt
55
- imageUrl?: string
56
- }
57
-
58
- // X (Formerly Twitter) Card settings
59
- export interface TwitterCardSettings {
60
- _type: 'twitter'
61
- card?: 'summary' | 'summary_large_image' | 'app' | 'player'
62
- site?: string
63
- creator?: string
64
- title?: string
65
- description?: string
66
- imageType?: 'upload' | 'url'
67
- image?: SanityImageWithAlt
68
- imageUrl?: string
69
- }
70
-
71
- // Main SEO Fields interface
72
- export interface SeoFields {
73
- _type: 'seoFields'
74
- robots?: RobotsSettings
75
- preview?: string
76
- title?: string
77
- description?: string
78
- metaImage?: SanityImage
79
- metaAttributes?: MetaAttribute[]
80
- keywords?: string[]
81
- canonicalUrl?: string
82
- openGraph?: OpenGraphSettings
83
- twitter?: TwitterCardSettings
84
- }
85
- export type FeedbackTypeColors = 'green' | 'orange' | 'red'
86
- export type FeedbackType = {
87
- text: string
88
- color: FeedbackTypeColors
89
- }
90
-
91
- // SEO Health Dashboard Types
92
- export type SeoHealthStatus = 'excellent' | 'good' | 'fair' | 'poor' | 'missing'
93
-
94
- export interface SeoHealthMetrics {
95
- score: number
96
- status: SeoHealthStatus
97
- issues: string[]
98
- }
99
-
100
- export interface DocumentWithSeoHealth {
101
- _id: string
102
- _type: string
103
- title?: string
104
- slug?: {current: string}
105
- seo?: SeoFields
106
- _updatedAt?: string
107
- health: SeoHealthMetrics
108
- }