sanity-plugin-seofields 1.6.5 → 1.8.0
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 +355 -79
- package/dist/SchemaOrgJsonLdPreview-DJLkIPq4.d.cts +78 -0
- package/dist/SchemaOrgJsonLdPreview-DJLkIPq4.d.ts +78 -0
- package/dist/SeoHealthDashboard-AEKVVMUR-7NWV3C3Y.js +4 -0
- package/dist/SeoHealthDashboard-AEKVVMUR-7NWV3C3Y.js.map +1 -0
- package/dist/SeoHealthDashboard-AEKVVMUR-XWKJUH24.cjs +10 -0
- package/dist/SeoHealthDashboard-AEKVVMUR-XWKJUH24.cjs.map +1 -0
- package/dist/SeoHealthTool-2KKQJLJL.cjs +11 -0
- package/dist/{SeoHealthDashboard-BEZVLLFG.js.map → SeoHealthTool-2KKQJLJL.cjs.map} +1 -1
- package/dist/SeoHealthTool-3CUKGADZ.js +5 -0
- package/dist/{SeoHealthDashboard-D3XU3CUB.cjs.map → SeoHealthTool-3CUKGADZ.js.map} +1 -1
- package/dist/{SeoPreview-WYH7NYNM.cjs → SeoPreview-3EXR6FD4.cjs} +3 -3
- package/dist/{SeoPreview-WYH7NYNM.cjs.map → SeoPreview-3EXR6FD4.cjs.map} +1 -1
- package/dist/{SeoPreview-KEGGQSPJ.js → SeoPreview-4PPAF4NO.js} +3 -3
- package/dist/{SeoPreview-KEGGQSPJ.js.map → SeoPreview-4PPAF4NO.js.map} +1 -1
- package/dist/{chunk-S367Y35J.cjs → chunk-254YHUN3.cjs} +2 -15
- package/dist/{chunk-S367Y35J.cjs.map → chunk-254YHUN3.cjs.map} +1 -1
- package/dist/{chunk-HQTYQMP5.js → chunk-27XSYENH.js} +80 -29
- package/dist/chunk-27XSYENH.js.map +1 -0
- package/dist/{chunk-YHXUWGNA.cjs → chunk-B5IVI5LP.cjs} +918 -157
- package/dist/chunk-B5IVI5LP.cjs.map +1 -0
- package/dist/chunk-BNXMFD3T.cjs +431 -0
- package/dist/chunk-BNXMFD3T.cjs.map +1 -0
- package/dist/{chunk-2NMEKWO5.js → chunk-DDAAVRWG.js} +3 -15
- package/dist/{chunk-2NMEKWO5.js.map → chunk-DDAAVRWG.js.map} +1 -1
- package/dist/chunk-P6IOWIO2.cjs +480 -0
- package/dist/chunk-P6IOWIO2.cjs.map +1 -0
- package/dist/{chunk-XXA6WCWS.js → chunk-UOCZFYYP.js} +18 -203
- package/dist/chunk-UOCZFYYP.js.map +1 -0
- package/dist/{chunk-KTL6NYNG.js → chunk-VR44E62I.js} +897 -148
- package/dist/chunk-VR44E62I.js.map +1 -0
- package/dist/chunk-WKXHX3GO.js +424 -0
- package/dist/chunk-WKXHX3GO.js.map +1 -0
- package/dist/{chunk-BHIZQLY7.cjs → chunk-XZDLJ2N6.cjs} +84 -30
- package/dist/chunk-XZDLJ2N6.cjs.map +1 -0
- package/dist/cli.js +18 -18
- package/dist/{component-H52blyfc.d.ts → component-BzI-LHPw.d.cts} +9 -27
- package/dist/{component-CIE6Sy4F.d.cts → component-DEXwtemT.d.ts} +9 -27
- package/dist/define-cli.cjs +1 -1
- package/dist/define-cli.js +1 -1
- package/dist/index.cjs +1050 -94
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +75 -202
- package/dist/index.d.ts +75 -202
- package/dist/index.js +1009 -63
- package/dist/index.js.map +1 -1
- package/dist/next.cjs +138 -116
- package/dist/next.cjs.map +1 -1
- package/dist/next.d.cts +9 -3
- package/dist/next.d.ts +9 -3
- package/dist/next.js +38 -32
- package/dist/next.js.map +1 -1
- package/dist/schema/next.cjs +105 -89
- package/dist/schema/next.d.cts +4 -4
- package/dist/schema/next.d.ts +4 -4
- package/dist/schema/next.js +4 -4
- package/dist/schema.cjs +219 -157
- package/dist/schema.cjs.map +1 -1
- package/dist/schema.d.cts +30 -16
- package/dist/schema.d.ts +30 -16
- package/dist/schema.js +41 -8
- package/dist/schema.js.map +1 -1
- package/dist/{types-Dp9Pfnt9.d.ts → types-BXSCbl6p.d.cts} +47 -2
- package/dist/{types-CyRdIF-3.d.cts → types-B_vjMPtM.d.cts} +1 -1
- package/dist/{types-BxcJinOf.d.cts → types-C19cQx5D.d.ts} +47 -2
- package/dist/{types-CbYb4MsN.d.ts → types-CW8qFdAn.d.ts} +1 -1
- package/dist/{types-BtSRRG6C.d.cts → types-yVmQfby9.d.cts} +8 -16
- package/dist/{types-BtSRRG6C.d.ts → types-yVmQfby9.d.ts} +8 -16
- package/package.json +2 -1
- package/dist/SeoHealthDashboard-BEZVLLFG.js +0 -4
- package/dist/SeoHealthDashboard-D3XU3CUB.cjs +0 -10
- package/dist/SeoHealthTool-4VZMD4TR.cjs +0 -14
- package/dist/SeoHealthTool-4VZMD4TR.cjs.map +0 -1
- package/dist/SeoHealthTool-BSTYAKQS.js +0 -12
- package/dist/SeoHealthTool-BSTYAKQS.js.map +0 -1
- package/dist/chunk-BCTPOWXA.cjs +0 -669
- package/dist/chunk-BCTPOWXA.cjs.map +0 -1
- package/dist/chunk-BHIZQLY7.cjs.map +0 -1
- package/dist/chunk-HQTYQMP5.js.map +0 -1
- package/dist/chunk-KTL6NYNG.js.map +0 -1
- package/dist/chunk-XXA6WCWS.js.map +0 -1
- package/dist/chunk-YHXUWGNA.cjs.map +0 -1
package/dist/index.d.cts
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
import * as sanity from 'sanity';
|
|
2
2
|
import { SchemaTypeDefinition } from 'sanity';
|
|
3
|
-
import { ComponentType
|
|
4
|
-
import { D as DocumentWithSeoHealth,
|
|
5
|
-
export {
|
|
6
|
-
|
|
3
|
+
import { ComponentType } from 'react';
|
|
4
|
+
import { D as DocumentWithSeoHealth, S as SeoHealthMetrics } from './types-yVmQfby9.cjs';
|
|
5
|
+
export { a as SeoHealthStatus } from './types-yVmQfby9.cjs';
|
|
6
|
+
export { SeoHealthPaneOptions, createSeoHealthPane } from 'seofields-pro';
|
|
7
|
+
export { S as SchemaOrgDocumentJsonLdPreview, S as SchemaOrgJsonLdPreview, a as SchemaOrgJsonLdPreviewOptions, b as SchemaOrgJsonLdPreviewProps } from './SchemaOrgJsonLdPreview-DJLkIPq4.cjs';
|
|
7
8
|
|
|
8
9
|
interface SeoFieldConfig {
|
|
9
10
|
title?: string;
|
|
10
11
|
description?: string;
|
|
11
12
|
}
|
|
12
|
-
type SeoFieldKeys = 'title' | 'description' | 'canonicalUrl' | 'metaImage' | 'keywords' | 'metaAttributes' | 'robots';
|
|
13
|
+
type SeoFieldKeys = 'title' | 'description' | 'canonicalUrl' | 'metaImage' | 'keywords' | 'metaAttributes' | 'robots' | 'focusKeyword' | 'hreflangs' | 'geoChecklist' | 'metaTagsPreview';
|
|
13
14
|
type openGraphFieldKeys = 'openGraphUrl' | 'openGraphTitle' | 'openGraphDescription' | 'openGraphSiteName' | 'openGraphType' | 'openGraphImageType' | 'openGraphImage' | 'openGraphImageUrl';
|
|
14
15
|
type twitterFieldKeys = 'twitterCard' | 'twitterSite' | 'twitterCreator' | 'twitterTitle' | 'twitterDescription' | 'twitterImageType' | 'twitterImage' | 'twitterImageUrl';
|
|
15
16
|
type AllFieldKeys = SeoFieldKeys | openGraphFieldKeys | twitterFieldKeys;
|
|
@@ -17,7 +18,7 @@ type AllFieldKeys = SeoFieldKeys | openGraphFieldKeys | twitterFieldKeys;
|
|
|
17
18
|
* Names of top-level fields inside the `seoFields` object type.
|
|
18
19
|
* Use these when assigning fields to groups in `fieldGroups`.
|
|
19
20
|
*/
|
|
20
|
-
type SeoObjectFieldName = 'robots' | 'preview' | 'title' | 'description' | 'metaImage' | 'metaAttributes' | 'keywords' | 'canonicalUrl' | 'openGraph' | 'twitter';
|
|
21
|
+
type SeoObjectFieldName = 'robots' | 'preview' | 'title' | 'description' | 'metaImage' | 'metaAttributes' | 'keywords' | 'canonicalUrl' | 'openGraph' | 'twitter' | 'focusKeyword' | 'hreflangs' | 'geoChecklist' | 'metaTagsPreview';
|
|
21
22
|
/**
|
|
22
23
|
* Defines a single tab/group within the `seoFields` object.
|
|
23
24
|
*/
|
|
@@ -42,7 +43,17 @@ type ValidHiddenFieldKeys = Exclude<AllFieldKeys, 'openGraphImageUrl' | 'twitter
|
|
|
42
43
|
interface FieldVisibilityConfig {
|
|
43
44
|
hiddenFields?: ValidHiddenFieldKeys[];
|
|
44
45
|
}
|
|
46
|
+
/**
|
|
47
|
+
* Individual SEO fields that must be non-empty before publishing.
|
|
48
|
+
* Dot-notation for nested fields (e.g. 'openGraph.title').
|
|
49
|
+
*/
|
|
50
|
+
type PublishGateRequiredField = 'title' | 'description' | 'metaImage' | 'keywords' | 'canonicalUrl' | 'openGraph.title' | 'openGraph.description' | 'openGraph.image' | 'openGraph.type' | 'twitter.title' | 'twitter.description' | 'twitter.image' | 'twitter.card';
|
|
45
51
|
interface SeoFieldsPluginConfig {
|
|
52
|
+
/**
|
|
53
|
+
* License key for pro features (SEO Health Dashboard, Publish Gate).
|
|
54
|
+
* Obtain at https://sanity-plugin-seofields.thehardik.in
|
|
55
|
+
*/
|
|
56
|
+
licenseKey?: string;
|
|
46
57
|
/**
|
|
47
58
|
* Enable or configure the SEO preview feature.
|
|
48
59
|
* If set to `true`, the SEO preview will be enabled with default settings.
|
|
@@ -127,6 +138,16 @@ interface SeoFieldsPluginConfig {
|
|
|
127
138
|
* ]
|
|
128
139
|
*/
|
|
129
140
|
fieldGroups?: SeoFieldGroup[];
|
|
141
|
+
/**
|
|
142
|
+
* Show the GEO / AI Overview readiness checklist inside seoFields.
|
|
143
|
+
* Defaults to `true`.
|
|
144
|
+
*/
|
|
145
|
+
geo?: boolean;
|
|
146
|
+
/**
|
|
147
|
+
* Show the Meta Tags HTML preview inside seoFields.
|
|
148
|
+
* Defaults to `true`.
|
|
149
|
+
*/
|
|
150
|
+
metaTagsPreview?: boolean;
|
|
130
151
|
/**
|
|
131
152
|
* The base URL of your website, used for generating full URLs in the SEO preview.
|
|
132
153
|
* Defaults to 'https://www.example.com' if not provided.
|
|
@@ -224,7 +245,7 @@ interface SeoFieldsPluginConfig {
|
|
|
224
245
|
apiVersion?: string;
|
|
225
246
|
/**
|
|
226
247
|
* License key for the SEO Health Dashboard pro feature.
|
|
227
|
-
*
|
|
248
|
+
* @deprecated Use the root-level `licenseKey` option instead.
|
|
228
249
|
*/
|
|
229
250
|
licenseKey?: string;
|
|
230
251
|
/**
|
|
@@ -309,6 +330,49 @@ interface SeoFieldsPluginConfig {
|
|
|
309
330
|
*/
|
|
310
331
|
compactStats?: boolean;
|
|
311
332
|
};
|
|
333
|
+
/**
|
|
334
|
+
* Gate publishing based on SEO score or required field presence.
|
|
335
|
+
* Requires a valid root-level `licenseKey` — silently disabled if key is absent or invalid.
|
|
336
|
+
*
|
|
337
|
+
* @example
|
|
338
|
+
* ```ts
|
|
339
|
+
* publishGate: {
|
|
340
|
+
* mode: 'warn',
|
|
341
|
+
* minScore: 70,
|
|
342
|
+
* requiredFields: ['title', 'description', 'openGraph.title'],
|
|
343
|
+
* types: ['post', 'page'],
|
|
344
|
+
* }
|
|
345
|
+
* ```
|
|
346
|
+
*/
|
|
347
|
+
publishGate?: {
|
|
348
|
+
/**
|
|
349
|
+
* 'block' — disables the Publish button with a tooltip reason (default).
|
|
350
|
+
* 'warn' — shows a confirm dialog; editor can bypass and publish anyway.
|
|
351
|
+
* @default 'block'
|
|
352
|
+
*/
|
|
353
|
+
mode?: 'block' | 'warn';
|
|
354
|
+
/**
|
|
355
|
+
* Minimum overall SEO health score (0–100) required to publish.
|
|
356
|
+
* Gate fires when the document's score is below this threshold.
|
|
357
|
+
* @default 60
|
|
358
|
+
*/
|
|
359
|
+
minScore?: number;
|
|
360
|
+
/**
|
|
361
|
+
* Individual fields that MUST be non-empty. Gate fires if any are missing.
|
|
362
|
+
* Use dot-notation for nested fields: 'openGraph.title', 'twitter.image', etc.
|
|
363
|
+
*/
|
|
364
|
+
requiredFields?: PublishGateRequiredField[];
|
|
365
|
+
/**
|
|
366
|
+
* Restrict the gate to specific document types.
|
|
367
|
+
* Omit to apply to all document types that have an `seo` field.
|
|
368
|
+
*/
|
|
369
|
+
types?: string[];
|
|
370
|
+
/**
|
|
371
|
+
* Custom message shown in the block tooltip or warn dialog.
|
|
372
|
+
* Accepts a string or a function receiving (score, issues[]).
|
|
373
|
+
*/
|
|
374
|
+
message?: string | ((score: number, issues: string[]) => string);
|
|
375
|
+
};
|
|
312
376
|
}
|
|
313
377
|
declare const seofields: sanity.Plugin<void | SeoFieldsPluginConfig>;
|
|
314
378
|
|
|
@@ -347,200 +411,9 @@ declare const _default: {
|
|
|
347
411
|
|
|
348
412
|
declare function twitter(config?: SeoFieldsPluginConfig): SchemaTypeDefinition;
|
|
349
413
|
|
|
350
|
-
interface
|
|
351
|
-
|
|
352
|
-
title?: string;
|
|
353
|
-
description?: string;
|
|
354
|
-
showTypeColumn?: boolean;
|
|
355
|
-
showDocumentId?: boolean;
|
|
356
|
-
/**
|
|
357
|
-
* Limit the dashboard to specific document type names.
|
|
358
|
-
* If both queryTypes and customQuery are provided, customQuery takes precedence.
|
|
359
|
-
*/
|
|
360
|
-
queryTypes?: string[];
|
|
361
|
-
/**
|
|
362
|
-
* When using `queryTypes`, also filter by `seo != null`.
|
|
363
|
-
* Set to `false` to include documents of those types even without an seo field.
|
|
364
|
-
* Defaults to `true`.
|
|
365
|
-
*/
|
|
366
|
-
queryRequireSeo?: boolean;
|
|
367
|
-
/**
|
|
368
|
-
* A fully custom GROQ query used to fetch documents.
|
|
369
|
-
* Must return objects with at least: _id, _type, title, seo, _updatedAt
|
|
370
|
-
* Takes precedence over queryTypes.
|
|
371
|
-
*/
|
|
372
|
-
customQuery?: string;
|
|
373
|
-
/**
|
|
374
|
-
* The Sanity API version to use for the client (e.g. '2023-01-01').
|
|
375
|
-
* Defaults to '2023-01-01'.
|
|
376
|
-
*/
|
|
377
|
-
apiVersion?: string;
|
|
378
|
-
/**
|
|
379
|
-
* License key for the SEO Health Dashboard.
|
|
380
|
-
* Obtain a key at https://sanity-plugin-seofields.thehardik.in
|
|
381
|
-
*/
|
|
382
|
-
licenseKey?: string;
|
|
383
|
-
/**
|
|
384
|
-
* Map raw `_type` values to human-readable display labels used in the
|
|
385
|
-
* Type column and the Type filter dropdown.
|
|
386
|
-
* Any type without an entry falls back to the raw `_type` string.
|
|
387
|
-
*
|
|
388
|
-
* @example
|
|
389
|
-
* typeDisplayLabels={{ productDrug: 'Products', singleCondition: 'Condition' }}
|
|
390
|
-
*/
|
|
391
|
-
typeDisplayLabels?: Record<string, string>;
|
|
392
|
-
/**
|
|
393
|
-
* Controls how the type is rendered in the Type column.
|
|
394
|
-
* - `'badge'` (default) — coloured pill, consistent with score badges
|
|
395
|
-
* - `'text'` — plain text, useful for dense layouts
|
|
396
|
-
*/
|
|
397
|
-
typeColumnMode?: 'badge' | 'text';
|
|
398
|
-
/**
|
|
399
|
-
* The document field to use as the display title.
|
|
400
|
-
*
|
|
401
|
-
* - `string` — use this field for every document type (e.g. `'name'`)
|
|
402
|
-
* - `Record<string, string>` — per-type mapping; unmapped types fall back to `title`
|
|
403
|
-
*
|
|
404
|
-
* @example
|
|
405
|
-
* // Same field for all types
|
|
406
|
-
* titleField: 'name'
|
|
407
|
-
*
|
|
408
|
-
* @example
|
|
409
|
-
* // Different field per type
|
|
410
|
-
* titleField: { post: 'title', product: 'name', category: 'label' }
|
|
411
|
-
*/
|
|
412
|
-
titleField?: string | Record<string, string>;
|
|
413
|
-
/**
|
|
414
|
-
* Callback function to render a custom badge next to the document title.
|
|
415
|
-
* Receives the full document and should return badge data or undefined.
|
|
416
|
-
*
|
|
417
|
-
* @example
|
|
418
|
-
* getDocumentBadge: (doc) => {
|
|
419
|
-
* if (doc.services === 'NHS')
|
|
420
|
-
* return { label: 'NHS', bgColor: '#e0f2fe', textColor: '#0369a1' }
|
|
421
|
-
* if (doc.services === 'Private')
|
|
422
|
-
* return { label: 'Private', bgColor: '#fef3c7', textColor: '#92400e' }
|
|
423
|
-
* }
|
|
424
|
-
*/
|
|
425
|
-
getDocumentBadge?: (doc: DocumentWithSeoHealth & Record<string, unknown>) => {
|
|
426
|
-
label: string;
|
|
427
|
-
bgColor?: string;
|
|
428
|
-
textColor?: string;
|
|
429
|
-
fontSize?: string;
|
|
430
|
-
} | undefined;
|
|
431
|
-
/**
|
|
432
|
-
* Custom text shown while the license key is being verified.
|
|
433
|
-
* Defaults to `"Verifying license…"`.
|
|
434
|
-
*/
|
|
435
|
-
loadingLicense?: ReactNode;
|
|
436
|
-
/**
|
|
437
|
-
* Custom text shown while documents are being fetched.
|
|
438
|
-
* Defaults to `"Loading documents…"`.
|
|
439
|
-
*/
|
|
440
|
-
loadingDocuments?: ReactNode;
|
|
441
|
-
/**
|
|
442
|
-
* Custom text shown when the query returns zero results.
|
|
443
|
-
* Defaults to `"No documents found"`.
|
|
444
|
-
*/
|
|
445
|
-
noDocuments?: ReactNode;
|
|
446
|
-
/**
|
|
447
|
-
* Enable preview/demo mode to show dummy data.
|
|
448
|
-
* Useful for testing, documentation, or showcasing the dashboard.
|
|
449
|
-
* When enabled, displays realistic sample documents with various SEO scores.
|
|
450
|
-
* Defaults to `false`.
|
|
451
|
-
*/
|
|
452
|
-
previewMode?: boolean;
|
|
453
|
-
/**
|
|
454
|
-
* When `true`, clicking a document title opens the document editor as a split
|
|
455
|
-
* pane to the right, keeping the SEO Health pane visible on the left.
|
|
456
|
-
* This uses Sanity's pane router and requires the component to be rendered
|
|
457
|
-
* inside a desk-structure pane context (i.e. via `createSeoHealthPane`).
|
|
458
|
-
*
|
|
459
|
-
* When `false` (default), clicking navigates to the document via the standard
|
|
460
|
-
* intent-link system (full navigation).
|
|
461
|
-
*
|
|
462
|
-
* This is set to `true` automatically by `createSeoHealthPane`.
|
|
463
|
-
*/
|
|
464
|
-
openInPane?: boolean;
|
|
465
|
-
/**
|
|
466
|
-
* The `name` of the Sanity structure tool that contains the monitored documents.
|
|
467
|
-
* When provided, clicking a document title navigates directly to that tool's
|
|
468
|
-
* intent URL (`/{basePath}/{structureTool}/intent/edit/id=…;type=…/`) instead of
|
|
469
|
-
* using the generic intent resolver, which always picks the first registered tool.
|
|
470
|
-
*
|
|
471
|
-
* Required when you have multiple structure tools and the documents live in a
|
|
472
|
-
* non-default one (e.g. `name: 'common'`).
|
|
473
|
-
*
|
|
474
|
-
* @example
|
|
475
|
-
* structureTool: 'common'
|
|
476
|
-
*/
|
|
477
|
-
structureTool?: string;
|
|
478
|
-
/**
|
|
479
|
-
* @internal — populated by the plugin when deprecated config keys are detected.
|
|
480
|
-
* Each entry carries the migration hint, the version it was deprecated in, and
|
|
481
|
-
* the matching changelog URL so the banner can group warnings by release.
|
|
482
|
-
*/
|
|
483
|
-
_deprecationWarnings?: DeprecationWarning[];
|
|
484
|
-
/**
|
|
485
|
-
* Whether the export (CSV / JSON) feature is enabled.
|
|
486
|
-
* Defaults to `true`.
|
|
487
|
-
*/
|
|
488
|
-
exportEnabled?: boolean;
|
|
489
|
-
/**
|
|
490
|
-
* Which export formats to offer.
|
|
491
|
-
* Defaults to `['csv', 'json']`.
|
|
492
|
-
*/
|
|
493
|
-
exportFormats?: Array<'csv' | 'json'>;
|
|
494
|
-
/**
|
|
495
|
-
* Render compact inline stat pills in the header instead of the full stats grid.
|
|
496
|
-
* Defaults to `false`.
|
|
497
|
-
*/
|
|
498
|
-
compactStats?: boolean;
|
|
499
|
-
}
|
|
500
|
-
|
|
501
|
-
/**
|
|
502
|
-
* Options accepted by `createSeoHealthPane`.
|
|
503
|
-
* All props from `SeoHealthDashboardProps` are supported.
|
|
504
|
-
*
|
|
505
|
-
* `licenseKey` is **required** — the dashboard will not render without it.
|
|
506
|
-
*/
|
|
507
|
-
interface SeoHealthPaneOptions extends Omit<SeoHealthDashboardProps, 'customQuery'> {
|
|
508
|
-
/** Required license key (format: `SEOF-XXXX-XXXX-XXXX`). */
|
|
509
|
-
licenseKey: string;
|
|
510
|
-
/**
|
|
511
|
-
* A fully custom GROQ query used to fetch documents for the dashboard.
|
|
512
|
-
* The query must return documents with at least: `_id`, `_type`, `title`, `seo`, `_updatedAt`.
|
|
513
|
-
*
|
|
514
|
-
* Takes precedence over `queryTypes` when both are provided.
|
|
515
|
-
*
|
|
516
|
-
* @example
|
|
517
|
-
* query: `*[_type in ["post","page"] && defined(seo)]{ _id, _type, title, slug, seo, _updatedAt }`
|
|
518
|
-
*/
|
|
519
|
-
query?: string;
|
|
414
|
+
interface SeoDocument {
|
|
415
|
+
seo?: Record<string, unknown>;
|
|
520
416
|
}
|
|
521
|
-
|
|
522
|
-
* Creates a desk-structure pane for the SEO Health Dashboard.
|
|
523
|
-
*
|
|
524
|
-
* Returns a **`ComponentBuilder`** with a built-in `.child()` resolver so that
|
|
525
|
-
* clicking any document row opens the document editor as a split pane to the right.
|
|
526
|
-
*
|
|
527
|
-
* Use it **directly** as the `.child()` value — do **not** wrap it in `S.component()`.
|
|
528
|
-
*
|
|
529
|
-
* ```ts
|
|
530
|
-
* // sanity.config.ts
|
|
531
|
-
* structure: (S) =>
|
|
532
|
-
* S.list().items([
|
|
533
|
-
* S.listItem()
|
|
534
|
-
* .title('SEO Health')
|
|
535
|
-
* .child(
|
|
536
|
-
* createSeoHealthPane(S, {
|
|
537
|
-
* licenseKey: 'SEOF-XXXX-XXXX-XXXX',
|
|
538
|
-
* query: `*[_type == "post" && defined(seo)]{ _id, _type, title, slug, seo, _updatedAt }`,
|
|
539
|
-
* })
|
|
540
|
-
* ),
|
|
541
|
-
* ])
|
|
542
|
-
* ```
|
|
543
|
-
*/
|
|
544
|
-
declare function createSeoHealthPane(optionsOrS: StructureBuilder, optionsWhenS: SeoHealthPaneOptions): ComponentBuilder;
|
|
417
|
+
declare const calculateHealthScore: (doc: SeoDocument) => SeoHealthMetrics;
|
|
545
418
|
|
|
546
|
-
export { type AllFieldKeys, DocumentWithSeoHealth, type FieldVisibilityConfig, type SeoFieldConfig, type SeoFieldGroup, type SeoFieldKeys, type SeoFieldsPluginConfig,
|
|
419
|
+
export { type AllFieldKeys, DocumentWithSeoHealth, type FieldVisibilityConfig, type PublishGateRequiredField, type SeoFieldConfig, type SeoFieldGroup, type SeoFieldKeys, type SeoFieldsPluginConfig, SeoHealthMetrics, type SeoObjectFieldName, type ValidHiddenFieldKeys, types as allSchemas, baseMeta as baseMetaSchema, calculateHealthScore, seofields as default, _default$2 as metaAttributeSchema, _default$1 as metaTagSchema, type openGraphFieldKeys, openGraph as openGraphSchema, _default as robotsSchema, seoFieldsSchema, type twitterFieldKeys, twitter as twitterSchema };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
import * as sanity from 'sanity';
|
|
2
2
|
import { SchemaTypeDefinition } from 'sanity';
|
|
3
|
-
import { ComponentType
|
|
4
|
-
import { D as DocumentWithSeoHealth,
|
|
5
|
-
export {
|
|
6
|
-
|
|
3
|
+
import { ComponentType } from 'react';
|
|
4
|
+
import { D as DocumentWithSeoHealth, S as SeoHealthMetrics } from './types-yVmQfby9.js';
|
|
5
|
+
export { a as SeoHealthStatus } from './types-yVmQfby9.js';
|
|
6
|
+
export { SeoHealthPaneOptions, createSeoHealthPane } from 'seofields-pro';
|
|
7
|
+
export { S as SchemaOrgDocumentJsonLdPreview, S as SchemaOrgJsonLdPreview, a as SchemaOrgJsonLdPreviewOptions, b as SchemaOrgJsonLdPreviewProps } from './SchemaOrgJsonLdPreview-DJLkIPq4.js';
|
|
7
8
|
|
|
8
9
|
interface SeoFieldConfig {
|
|
9
10
|
title?: string;
|
|
10
11
|
description?: string;
|
|
11
12
|
}
|
|
12
|
-
type SeoFieldKeys = 'title' | 'description' | 'canonicalUrl' | 'metaImage' | 'keywords' | 'metaAttributes' | 'robots';
|
|
13
|
+
type SeoFieldKeys = 'title' | 'description' | 'canonicalUrl' | 'metaImage' | 'keywords' | 'metaAttributes' | 'robots' | 'focusKeyword' | 'hreflangs' | 'geoChecklist' | 'metaTagsPreview';
|
|
13
14
|
type openGraphFieldKeys = 'openGraphUrl' | 'openGraphTitle' | 'openGraphDescription' | 'openGraphSiteName' | 'openGraphType' | 'openGraphImageType' | 'openGraphImage' | 'openGraphImageUrl';
|
|
14
15
|
type twitterFieldKeys = 'twitterCard' | 'twitterSite' | 'twitterCreator' | 'twitterTitle' | 'twitterDescription' | 'twitterImageType' | 'twitterImage' | 'twitterImageUrl';
|
|
15
16
|
type AllFieldKeys = SeoFieldKeys | openGraphFieldKeys | twitterFieldKeys;
|
|
@@ -17,7 +18,7 @@ type AllFieldKeys = SeoFieldKeys | openGraphFieldKeys | twitterFieldKeys;
|
|
|
17
18
|
* Names of top-level fields inside the `seoFields` object type.
|
|
18
19
|
* Use these when assigning fields to groups in `fieldGroups`.
|
|
19
20
|
*/
|
|
20
|
-
type SeoObjectFieldName = 'robots' | 'preview' | 'title' | 'description' | 'metaImage' | 'metaAttributes' | 'keywords' | 'canonicalUrl' | 'openGraph' | 'twitter';
|
|
21
|
+
type SeoObjectFieldName = 'robots' | 'preview' | 'title' | 'description' | 'metaImage' | 'metaAttributes' | 'keywords' | 'canonicalUrl' | 'openGraph' | 'twitter' | 'focusKeyword' | 'hreflangs' | 'geoChecklist' | 'metaTagsPreview';
|
|
21
22
|
/**
|
|
22
23
|
* Defines a single tab/group within the `seoFields` object.
|
|
23
24
|
*/
|
|
@@ -42,7 +43,17 @@ type ValidHiddenFieldKeys = Exclude<AllFieldKeys, 'openGraphImageUrl' | 'twitter
|
|
|
42
43
|
interface FieldVisibilityConfig {
|
|
43
44
|
hiddenFields?: ValidHiddenFieldKeys[];
|
|
44
45
|
}
|
|
46
|
+
/**
|
|
47
|
+
* Individual SEO fields that must be non-empty before publishing.
|
|
48
|
+
* Dot-notation for nested fields (e.g. 'openGraph.title').
|
|
49
|
+
*/
|
|
50
|
+
type PublishGateRequiredField = 'title' | 'description' | 'metaImage' | 'keywords' | 'canonicalUrl' | 'openGraph.title' | 'openGraph.description' | 'openGraph.image' | 'openGraph.type' | 'twitter.title' | 'twitter.description' | 'twitter.image' | 'twitter.card';
|
|
45
51
|
interface SeoFieldsPluginConfig {
|
|
52
|
+
/**
|
|
53
|
+
* License key for pro features (SEO Health Dashboard, Publish Gate).
|
|
54
|
+
* Obtain at https://sanity-plugin-seofields.thehardik.in
|
|
55
|
+
*/
|
|
56
|
+
licenseKey?: string;
|
|
46
57
|
/**
|
|
47
58
|
* Enable or configure the SEO preview feature.
|
|
48
59
|
* If set to `true`, the SEO preview will be enabled with default settings.
|
|
@@ -127,6 +138,16 @@ interface SeoFieldsPluginConfig {
|
|
|
127
138
|
* ]
|
|
128
139
|
*/
|
|
129
140
|
fieldGroups?: SeoFieldGroup[];
|
|
141
|
+
/**
|
|
142
|
+
* Show the GEO / AI Overview readiness checklist inside seoFields.
|
|
143
|
+
* Defaults to `true`.
|
|
144
|
+
*/
|
|
145
|
+
geo?: boolean;
|
|
146
|
+
/**
|
|
147
|
+
* Show the Meta Tags HTML preview inside seoFields.
|
|
148
|
+
* Defaults to `true`.
|
|
149
|
+
*/
|
|
150
|
+
metaTagsPreview?: boolean;
|
|
130
151
|
/**
|
|
131
152
|
* The base URL of your website, used for generating full URLs in the SEO preview.
|
|
132
153
|
* Defaults to 'https://www.example.com' if not provided.
|
|
@@ -224,7 +245,7 @@ interface SeoFieldsPluginConfig {
|
|
|
224
245
|
apiVersion?: string;
|
|
225
246
|
/**
|
|
226
247
|
* License key for the SEO Health Dashboard pro feature.
|
|
227
|
-
*
|
|
248
|
+
* @deprecated Use the root-level `licenseKey` option instead.
|
|
228
249
|
*/
|
|
229
250
|
licenseKey?: string;
|
|
230
251
|
/**
|
|
@@ -309,6 +330,49 @@ interface SeoFieldsPluginConfig {
|
|
|
309
330
|
*/
|
|
310
331
|
compactStats?: boolean;
|
|
311
332
|
};
|
|
333
|
+
/**
|
|
334
|
+
* Gate publishing based on SEO score or required field presence.
|
|
335
|
+
* Requires a valid root-level `licenseKey` — silently disabled if key is absent or invalid.
|
|
336
|
+
*
|
|
337
|
+
* @example
|
|
338
|
+
* ```ts
|
|
339
|
+
* publishGate: {
|
|
340
|
+
* mode: 'warn',
|
|
341
|
+
* minScore: 70,
|
|
342
|
+
* requiredFields: ['title', 'description', 'openGraph.title'],
|
|
343
|
+
* types: ['post', 'page'],
|
|
344
|
+
* }
|
|
345
|
+
* ```
|
|
346
|
+
*/
|
|
347
|
+
publishGate?: {
|
|
348
|
+
/**
|
|
349
|
+
* 'block' — disables the Publish button with a tooltip reason (default).
|
|
350
|
+
* 'warn' — shows a confirm dialog; editor can bypass and publish anyway.
|
|
351
|
+
* @default 'block'
|
|
352
|
+
*/
|
|
353
|
+
mode?: 'block' | 'warn';
|
|
354
|
+
/**
|
|
355
|
+
* Minimum overall SEO health score (0–100) required to publish.
|
|
356
|
+
* Gate fires when the document's score is below this threshold.
|
|
357
|
+
* @default 60
|
|
358
|
+
*/
|
|
359
|
+
minScore?: number;
|
|
360
|
+
/**
|
|
361
|
+
* Individual fields that MUST be non-empty. Gate fires if any are missing.
|
|
362
|
+
* Use dot-notation for nested fields: 'openGraph.title', 'twitter.image', etc.
|
|
363
|
+
*/
|
|
364
|
+
requiredFields?: PublishGateRequiredField[];
|
|
365
|
+
/**
|
|
366
|
+
* Restrict the gate to specific document types.
|
|
367
|
+
* Omit to apply to all document types that have an `seo` field.
|
|
368
|
+
*/
|
|
369
|
+
types?: string[];
|
|
370
|
+
/**
|
|
371
|
+
* Custom message shown in the block tooltip or warn dialog.
|
|
372
|
+
* Accepts a string or a function receiving (score, issues[]).
|
|
373
|
+
*/
|
|
374
|
+
message?: string | ((score: number, issues: string[]) => string);
|
|
375
|
+
};
|
|
312
376
|
}
|
|
313
377
|
declare const seofields: sanity.Plugin<void | SeoFieldsPluginConfig>;
|
|
314
378
|
|
|
@@ -347,200 +411,9 @@ declare const _default: {
|
|
|
347
411
|
|
|
348
412
|
declare function twitter(config?: SeoFieldsPluginConfig): SchemaTypeDefinition;
|
|
349
413
|
|
|
350
|
-
interface
|
|
351
|
-
|
|
352
|
-
title?: string;
|
|
353
|
-
description?: string;
|
|
354
|
-
showTypeColumn?: boolean;
|
|
355
|
-
showDocumentId?: boolean;
|
|
356
|
-
/**
|
|
357
|
-
* Limit the dashboard to specific document type names.
|
|
358
|
-
* If both queryTypes and customQuery are provided, customQuery takes precedence.
|
|
359
|
-
*/
|
|
360
|
-
queryTypes?: string[];
|
|
361
|
-
/**
|
|
362
|
-
* When using `queryTypes`, also filter by `seo != null`.
|
|
363
|
-
* Set to `false` to include documents of those types even without an seo field.
|
|
364
|
-
* Defaults to `true`.
|
|
365
|
-
*/
|
|
366
|
-
queryRequireSeo?: boolean;
|
|
367
|
-
/**
|
|
368
|
-
* A fully custom GROQ query used to fetch documents.
|
|
369
|
-
* Must return objects with at least: _id, _type, title, seo, _updatedAt
|
|
370
|
-
* Takes precedence over queryTypes.
|
|
371
|
-
*/
|
|
372
|
-
customQuery?: string;
|
|
373
|
-
/**
|
|
374
|
-
* The Sanity API version to use for the client (e.g. '2023-01-01').
|
|
375
|
-
* Defaults to '2023-01-01'.
|
|
376
|
-
*/
|
|
377
|
-
apiVersion?: string;
|
|
378
|
-
/**
|
|
379
|
-
* License key for the SEO Health Dashboard.
|
|
380
|
-
* Obtain a key at https://sanity-plugin-seofields.thehardik.in
|
|
381
|
-
*/
|
|
382
|
-
licenseKey?: string;
|
|
383
|
-
/**
|
|
384
|
-
* Map raw `_type` values to human-readable display labels used in the
|
|
385
|
-
* Type column and the Type filter dropdown.
|
|
386
|
-
* Any type without an entry falls back to the raw `_type` string.
|
|
387
|
-
*
|
|
388
|
-
* @example
|
|
389
|
-
* typeDisplayLabels={{ productDrug: 'Products', singleCondition: 'Condition' }}
|
|
390
|
-
*/
|
|
391
|
-
typeDisplayLabels?: Record<string, string>;
|
|
392
|
-
/**
|
|
393
|
-
* Controls how the type is rendered in the Type column.
|
|
394
|
-
* - `'badge'` (default) — coloured pill, consistent with score badges
|
|
395
|
-
* - `'text'` — plain text, useful for dense layouts
|
|
396
|
-
*/
|
|
397
|
-
typeColumnMode?: 'badge' | 'text';
|
|
398
|
-
/**
|
|
399
|
-
* The document field to use as the display title.
|
|
400
|
-
*
|
|
401
|
-
* - `string` — use this field for every document type (e.g. `'name'`)
|
|
402
|
-
* - `Record<string, string>` — per-type mapping; unmapped types fall back to `title`
|
|
403
|
-
*
|
|
404
|
-
* @example
|
|
405
|
-
* // Same field for all types
|
|
406
|
-
* titleField: 'name'
|
|
407
|
-
*
|
|
408
|
-
* @example
|
|
409
|
-
* // Different field per type
|
|
410
|
-
* titleField: { post: 'title', product: 'name', category: 'label' }
|
|
411
|
-
*/
|
|
412
|
-
titleField?: string | Record<string, string>;
|
|
413
|
-
/**
|
|
414
|
-
* Callback function to render a custom badge next to the document title.
|
|
415
|
-
* Receives the full document and should return badge data or undefined.
|
|
416
|
-
*
|
|
417
|
-
* @example
|
|
418
|
-
* getDocumentBadge: (doc) => {
|
|
419
|
-
* if (doc.services === 'NHS')
|
|
420
|
-
* return { label: 'NHS', bgColor: '#e0f2fe', textColor: '#0369a1' }
|
|
421
|
-
* if (doc.services === 'Private')
|
|
422
|
-
* return { label: 'Private', bgColor: '#fef3c7', textColor: '#92400e' }
|
|
423
|
-
* }
|
|
424
|
-
*/
|
|
425
|
-
getDocumentBadge?: (doc: DocumentWithSeoHealth & Record<string, unknown>) => {
|
|
426
|
-
label: string;
|
|
427
|
-
bgColor?: string;
|
|
428
|
-
textColor?: string;
|
|
429
|
-
fontSize?: string;
|
|
430
|
-
} | undefined;
|
|
431
|
-
/**
|
|
432
|
-
* Custom text shown while the license key is being verified.
|
|
433
|
-
* Defaults to `"Verifying license…"`.
|
|
434
|
-
*/
|
|
435
|
-
loadingLicense?: ReactNode;
|
|
436
|
-
/**
|
|
437
|
-
* Custom text shown while documents are being fetched.
|
|
438
|
-
* Defaults to `"Loading documents…"`.
|
|
439
|
-
*/
|
|
440
|
-
loadingDocuments?: ReactNode;
|
|
441
|
-
/**
|
|
442
|
-
* Custom text shown when the query returns zero results.
|
|
443
|
-
* Defaults to `"No documents found"`.
|
|
444
|
-
*/
|
|
445
|
-
noDocuments?: ReactNode;
|
|
446
|
-
/**
|
|
447
|
-
* Enable preview/demo mode to show dummy data.
|
|
448
|
-
* Useful for testing, documentation, or showcasing the dashboard.
|
|
449
|
-
* When enabled, displays realistic sample documents with various SEO scores.
|
|
450
|
-
* Defaults to `false`.
|
|
451
|
-
*/
|
|
452
|
-
previewMode?: boolean;
|
|
453
|
-
/**
|
|
454
|
-
* When `true`, clicking a document title opens the document editor as a split
|
|
455
|
-
* pane to the right, keeping the SEO Health pane visible on the left.
|
|
456
|
-
* This uses Sanity's pane router and requires the component to be rendered
|
|
457
|
-
* inside a desk-structure pane context (i.e. via `createSeoHealthPane`).
|
|
458
|
-
*
|
|
459
|
-
* When `false` (default), clicking navigates to the document via the standard
|
|
460
|
-
* intent-link system (full navigation).
|
|
461
|
-
*
|
|
462
|
-
* This is set to `true` automatically by `createSeoHealthPane`.
|
|
463
|
-
*/
|
|
464
|
-
openInPane?: boolean;
|
|
465
|
-
/**
|
|
466
|
-
* The `name` of the Sanity structure tool that contains the monitored documents.
|
|
467
|
-
* When provided, clicking a document title navigates directly to that tool's
|
|
468
|
-
* intent URL (`/{basePath}/{structureTool}/intent/edit/id=…;type=…/`) instead of
|
|
469
|
-
* using the generic intent resolver, which always picks the first registered tool.
|
|
470
|
-
*
|
|
471
|
-
* Required when you have multiple structure tools and the documents live in a
|
|
472
|
-
* non-default one (e.g. `name: 'common'`).
|
|
473
|
-
*
|
|
474
|
-
* @example
|
|
475
|
-
* structureTool: 'common'
|
|
476
|
-
*/
|
|
477
|
-
structureTool?: string;
|
|
478
|
-
/**
|
|
479
|
-
* @internal — populated by the plugin when deprecated config keys are detected.
|
|
480
|
-
* Each entry carries the migration hint, the version it was deprecated in, and
|
|
481
|
-
* the matching changelog URL so the banner can group warnings by release.
|
|
482
|
-
*/
|
|
483
|
-
_deprecationWarnings?: DeprecationWarning[];
|
|
484
|
-
/**
|
|
485
|
-
* Whether the export (CSV / JSON) feature is enabled.
|
|
486
|
-
* Defaults to `true`.
|
|
487
|
-
*/
|
|
488
|
-
exportEnabled?: boolean;
|
|
489
|
-
/**
|
|
490
|
-
* Which export formats to offer.
|
|
491
|
-
* Defaults to `['csv', 'json']`.
|
|
492
|
-
*/
|
|
493
|
-
exportFormats?: Array<'csv' | 'json'>;
|
|
494
|
-
/**
|
|
495
|
-
* Render compact inline stat pills in the header instead of the full stats grid.
|
|
496
|
-
* Defaults to `false`.
|
|
497
|
-
*/
|
|
498
|
-
compactStats?: boolean;
|
|
499
|
-
}
|
|
500
|
-
|
|
501
|
-
/**
|
|
502
|
-
* Options accepted by `createSeoHealthPane`.
|
|
503
|
-
* All props from `SeoHealthDashboardProps` are supported.
|
|
504
|
-
*
|
|
505
|
-
* `licenseKey` is **required** — the dashboard will not render without it.
|
|
506
|
-
*/
|
|
507
|
-
interface SeoHealthPaneOptions extends Omit<SeoHealthDashboardProps, 'customQuery'> {
|
|
508
|
-
/** Required license key (format: `SEOF-XXXX-XXXX-XXXX`). */
|
|
509
|
-
licenseKey: string;
|
|
510
|
-
/**
|
|
511
|
-
* A fully custom GROQ query used to fetch documents for the dashboard.
|
|
512
|
-
* The query must return documents with at least: `_id`, `_type`, `title`, `seo`, `_updatedAt`.
|
|
513
|
-
*
|
|
514
|
-
* Takes precedence over `queryTypes` when both are provided.
|
|
515
|
-
*
|
|
516
|
-
* @example
|
|
517
|
-
* query: `*[_type in ["post","page"] && defined(seo)]{ _id, _type, title, slug, seo, _updatedAt }`
|
|
518
|
-
*/
|
|
519
|
-
query?: string;
|
|
414
|
+
interface SeoDocument {
|
|
415
|
+
seo?: Record<string, unknown>;
|
|
520
416
|
}
|
|
521
|
-
|
|
522
|
-
* Creates a desk-structure pane for the SEO Health Dashboard.
|
|
523
|
-
*
|
|
524
|
-
* Returns a **`ComponentBuilder`** with a built-in `.child()` resolver so that
|
|
525
|
-
* clicking any document row opens the document editor as a split pane to the right.
|
|
526
|
-
*
|
|
527
|
-
* Use it **directly** as the `.child()` value — do **not** wrap it in `S.component()`.
|
|
528
|
-
*
|
|
529
|
-
* ```ts
|
|
530
|
-
* // sanity.config.ts
|
|
531
|
-
* structure: (S) =>
|
|
532
|
-
* S.list().items([
|
|
533
|
-
* S.listItem()
|
|
534
|
-
* .title('SEO Health')
|
|
535
|
-
* .child(
|
|
536
|
-
* createSeoHealthPane(S, {
|
|
537
|
-
* licenseKey: 'SEOF-XXXX-XXXX-XXXX',
|
|
538
|
-
* query: `*[_type == "post" && defined(seo)]{ _id, _type, title, slug, seo, _updatedAt }`,
|
|
539
|
-
* })
|
|
540
|
-
* ),
|
|
541
|
-
* ])
|
|
542
|
-
* ```
|
|
543
|
-
*/
|
|
544
|
-
declare function createSeoHealthPane(optionsOrS: StructureBuilder, optionsWhenS: SeoHealthPaneOptions): ComponentBuilder;
|
|
417
|
+
declare const calculateHealthScore: (doc: SeoDocument) => SeoHealthMetrics;
|
|
545
418
|
|
|
546
|
-
export { type AllFieldKeys, DocumentWithSeoHealth, type FieldVisibilityConfig, type SeoFieldConfig, type SeoFieldGroup, type SeoFieldKeys, type SeoFieldsPluginConfig,
|
|
419
|
+
export { type AllFieldKeys, DocumentWithSeoHealth, type FieldVisibilityConfig, type PublishGateRequiredField, type SeoFieldConfig, type SeoFieldGroup, type SeoFieldKeys, type SeoFieldsPluginConfig, SeoHealthMetrics, type SeoObjectFieldName, type ValidHiddenFieldKeys, types as allSchemas, baseMeta as baseMetaSchema, calculateHealthScore, seofields as default, _default$2 as metaAttributeSchema, _default$1 as metaTagSchema, type openGraphFieldKeys, openGraph as openGraphSchema, _default as robotsSchema, seoFieldsSchema, type twitterFieldKeys, twitter as twitterSchema };
|