sanity-plugin-seofields 1.7.0 → 1.9.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 +440 -29
- package/dist/SchemaOrgJsonLdPreview-DJLkIPq4.d.cts +78 -0
- package/dist/SchemaOrgJsonLdPreview-DJLkIPq4.d.ts +78 -0
- package/dist/SeoHealthTool-2COI27KI.cjs +8 -0
- package/dist/SeoHealthTool-2COI27KI.cjs.map +1 -0
- package/dist/SeoHealthTool-CWI3KB2V.js +8 -0
- package/dist/SeoHealthTool-CWI3KB2V.js.map +1 -0
- package/dist/{SeoPreview-WYH7NYNM.cjs → SeoPreview-LMZAWWOE.cjs} +35 -38
- package/dist/SeoPreview-LMZAWWOE.cjs.map +1 -0
- package/dist/{SeoPreview-KEGGQSPJ.js → SeoPreview-UNQBKTQO.js} +14 -11
- package/dist/SeoPreview-UNQBKTQO.js.map +1 -0
- package/dist/chunk-3OK3S2F7.cjs +673 -0
- package/dist/chunk-3OK3S2F7.cjs.map +1 -0
- package/dist/{chunk-GWPOJSGW.cjs → chunk-5XTQRILL.cjs} +1022 -307
- package/dist/chunk-5XTQRILL.cjs.map +1 -0
- package/dist/{chunk-2NMEKWO5.js → chunk-7N4MLTMR.js} +8 -15
- package/dist/chunk-7N4MLTMR.js.map +1 -0
- package/dist/{chunk-S367Y35J.cjs → chunk-A57XNQC7.cjs} +9 -20
- package/dist/chunk-A57XNQC7.cjs.map +1 -0
- package/dist/chunk-BWLJDK5J.js +624 -0
- package/dist/chunk-BWLJDK5J.js.map +1 -0
- package/dist/chunk-FUUWBQE2.cjs +195 -0
- package/dist/chunk-FUUWBQE2.cjs.map +1 -0
- package/dist/{chunk-ZBHLMQTS.cjs → chunk-HHO2AKAP.js} +44 -17
- package/dist/chunk-HHO2AKAP.js.map +1 -0
- package/dist/chunk-KIEO6QG3.js +195 -0
- package/dist/chunk-KIEO6QG3.js.map +1 -0
- package/dist/chunk-R2U7JF7U.cjs +624 -0
- package/dist/chunk-R2U7JF7U.cjs.map +1 -0
- package/dist/{chunk-HRKRV2X7.js → chunk-XZKQWV2H.js} +974 -148
- package/dist/chunk-XZKQWV2H.js.map +1 -0
- package/dist/{chunk-HDZZQCH7.js → chunk-Y46ACXM4.cjs} +45 -5
- package/dist/chunk-Y46ACXM4.cjs.map +1 -0
- package/dist/chunk-Z5AOUU4H.js +673 -0
- package/dist/chunk-Z5AOUU4H.js.map +1 -0
- package/dist/cli.js +27 -27
- package/dist/{component-DQ4KuQQD.d.ts → component-CjT1hvxh.d.ts} +3 -27
- package/dist/{component-D1sBm6ts.d.cts → component-WYh0z8as.d.cts} +3 -27
- package/dist/define-cli.cjs +2 -4
- package/dist/define-cli.cjs.map +1 -1
- package/dist/define-cli.js +4 -4
- package/dist/define-cli.js.map +1 -1
- package/dist/head.cjs +14 -0
- package/dist/head.cjs.map +1 -0
- package/dist/head.d.cts +254 -0
- package/dist/head.d.ts +254 -0
- package/dist/head.js +14 -0
- package/dist/head.js.map +1 -0
- package/dist/index.cjs +1797 -230
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +11 -598
- package/dist/index.d.ts +11 -598
- package/dist/index.js +1777 -197
- package/dist/index.js.map +1 -1
- package/dist/next.cjs +210 -447
- package/dist/next.cjs.map +1 -1
- package/dist/next.d.cts +8 -200
- package/dist/next.d.ts +8 -200
- package/dist/next.js +200 -124
- package/dist/next.js.map +1 -1
- package/dist/plugin-DQdThyxG.d.ts +449 -0
- package/dist/plugin-DoGeZP79.d.cts +449 -0
- package/dist/schema/next.cjs +173 -319
- package/dist/schema/next.cjs.map +1 -1
- package/dist/schema/next.d.cts +4 -4
- package/dist/schema/next.d.ts +4 -4
- package/dist/schema/next.js +172 -8
- package/dist/schema/next.js.map +1 -1
- package/dist/schema.cjs +390 -489
- package/dist/schema.cjs.map +1 -1
- package/dist/schema.d.cts +26 -16
- package/dist/schema.d.ts +26 -16
- package/dist/schema.js +236 -13
- package/dist/schema.js.map +1 -1
- package/dist/server.cjs +149 -0
- package/dist/server.cjs.map +1 -0
- package/dist/server.d.cts +102 -0
- package/dist/server.d.ts +102 -0
- package/dist/server.js +149 -0
- package/dist/server.js.map +1 -0
- package/dist/{types-CeBULNFF.d.ts → types-BAdN1RMu.d.ts} +2 -2
- package/dist/{types-_wBLg6RV.d.cts → types-C5i3KMgs.d.cts} +2 -2
- package/dist/{types-9_wbCIi9.d.ts → types-DP-DiW6f.d.cts} +29 -2
- package/dist/{types-Bb49oRBV.d.cts → types-DRLUGLtX.d.ts} +29 -2
- package/dist/{types-B91ena4g.d.cts → types-DxlPXihz.d.cts} +8 -1
- package/dist/{types-B91ena4g.d.ts → types-DxlPXihz.d.ts} +8 -1
- package/package.json +25 -3
- package/dist/SeoHealthDashboard-IP5BJ322.cjs +0 -10
- package/dist/SeoHealthDashboard-IP5BJ322.cjs.map +0 -1
- package/dist/SeoHealthDashboard-PTUEVYZL.js +0 -4
- package/dist/SeoHealthDashboard-PTUEVYZL.js.map +0 -1
- package/dist/SeoHealthTool-CZZRMWQK.cjs +0 -14
- package/dist/SeoHealthTool-CZZRMWQK.cjs.map +0 -1
- package/dist/SeoHealthTool-IULT4G25.js +0 -12
- package/dist/SeoHealthTool-IULT4G25.js.map +0 -1
- package/dist/SeoPreview-KEGGQSPJ.js.map +0 -1
- package/dist/SeoPreview-WYH7NYNM.cjs.map +0 -1
- package/dist/chunk-2NMEKWO5.js.map +0 -1
- package/dist/chunk-5YRH47VQ.cjs +0 -2167
- package/dist/chunk-5YRH47VQ.cjs.map +0 -1
- package/dist/chunk-ARELX3GK.cjs +0 -689
- package/dist/chunk-ARELX3GK.cjs.map +0 -1
- package/dist/chunk-AW7OKBQQ.js +0 -2161
- package/dist/chunk-AW7OKBQQ.js.map +0 -1
- package/dist/chunk-FONJYVF2.js +0 -610
- package/dist/chunk-FONJYVF2.js.map +0 -1
- package/dist/chunk-GWPOJSGW.cjs.map +0 -1
- package/dist/chunk-HDZZQCH7.js.map +0 -1
- package/dist/chunk-HRKRV2X7.js.map +0 -1
- package/dist/chunk-S367Y35J.cjs.map +0 -1
- package/dist/chunk-ZBHLMQTS.cjs.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -1,49 +1,922 @@
|
|
|
1
|
-
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } }
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
var _chunk3OK3S2F7cjs = require('./chunk-3OK3S2F7.cjs');
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
var _chunk5XTQRILLcjs = require('./chunk-5XTQRILL.cjs');
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
var _chunkY46ACXM4cjs = require('./chunk-Y46ACXM4.cjs');
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
var _chunkA57XNQC7cjs = require('./chunk-A57XNQC7.cjs');
|
|
30
|
+
|
|
31
|
+
// src/plugin.ts
|
|
32
|
+
var _react = require('react');
|
|
33
|
+
var _sanity = require('sanity');
|
|
34
|
+
|
|
35
|
+
// src/actions/SeoPublishGateAction.tsx
|
|
36
|
+
var _seofieldspro = require('seofields-pro');
|
|
37
|
+
|
|
38
|
+
// src/schemas/index.ts
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
// src/components/geo/GEOChecklist.tsx
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
var _jsxruntime = require('react/jsx-runtime');
|
|
54
|
+
var GEOChecklist = (props) => {
|
|
55
|
+
var _a;
|
|
56
|
+
const { path, schemaType } = props;
|
|
57
|
+
const [expanded, setExpanded] = _react.useState.call(void 0, false);
|
|
58
|
+
const licenseKey = (_a = schemaType.options) == null ? void 0 : _a.licenseKey;
|
|
59
|
+
const seoFields = _sanity.useFormValue.call(void 0, [path[0]]);
|
|
60
|
+
const rootDoc = _sanity.useFormValue.call(void 0, []);
|
|
61
|
+
const freeChecks = _react.useMemo.call(void 0, () => {
|
|
62
|
+
var _a2, _b, _c, _d;
|
|
63
|
+
const desc = (seoFields == null ? void 0 : seoFields.description) || "";
|
|
64
|
+
const title = (seoFields == null ? void 0 : seoFields.title) || "";
|
|
65
|
+
return [
|
|
66
|
+
{
|
|
67
|
+
id: "description_answer_ready",
|
|
68
|
+
label: "Description is answer-ready (100\u2013160 chars)",
|
|
69
|
+
pass: !!desc && desc.length >= 100 && desc.length <= 160,
|
|
70
|
+
hint: "Write a concise 100\u2013160 char answer that directly addresses user intent."
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
id: "not_noindexed",
|
|
74
|
+
label: "Page is indexable (not noindex)",
|
|
75
|
+
pass: !((_a2 = seoFields == null ? void 0 : seoFields.robots) == null ? void 0 : _a2.noIndex),
|
|
76
|
+
hint: "Page is set to noindex \u2014 AI overviews cannot cite noindexed pages."
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
id: "title_concise",
|
|
80
|
+
label: "Title is 30\u201360 characters",
|
|
81
|
+
pass: !!(title && title.length >= 30 && title.length <= 60),
|
|
82
|
+
hint: "Keep your title between 30\u201360 characters for optimal SERP and AI snippet display."
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
id: "og_image_present",
|
|
86
|
+
label: "OG or meta image present",
|
|
87
|
+
pass: !!(((_b = seoFields == null ? void 0 : seoFields.metaImage) == null ? void 0 : _b.asset) || ((_d = (_c = seoFields == null ? void 0 : seoFields.openGraph) == null ? void 0 : _c.image) == null ? void 0 : _d.asset)),
|
|
88
|
+
hint: "Add a meta or OG image for rich results and social previews."
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
id: "has_keywords",
|
|
92
|
+
label: "Keywords added",
|
|
93
|
+
pass: !!((seoFields == null ? void 0 : seoFields.keywords) && seoFields.keywords.filter((k) => k && k.trim().length > 0).length > 0),
|
|
94
|
+
hint: "Add at least one keyword to improve topical signal for AI classifiers."
|
|
95
|
+
}
|
|
96
|
+
];
|
|
97
|
+
}, [seoFields]);
|
|
98
|
+
const proChecks = _react.useMemo.call(void 0,
|
|
99
|
+
() => licenseKey ? _seofieldspro.buildGEOProChecks.call(void 0, seoFields, rootDoc) : null,
|
|
100
|
+
[licenseKey, seoFields, rootDoc]
|
|
101
|
+
);
|
|
102
|
+
const freePassing = freeChecks.filter((c) => c.pass).length;
|
|
103
|
+
const proPassing = proChecks ? proChecks.filter((c) => c.pass).length : 0;
|
|
104
|
+
const totalPassing = freePassing + (proChecks ? proPassing : 0);
|
|
105
|
+
const totalChecks = freeChecks.length + (proChecks ? proChecks.length : 0);
|
|
106
|
+
const percentage = totalChecks > 0 ? totalPassing / totalChecks * 100 : 0;
|
|
107
|
+
let scoreColor = "#dc2626";
|
|
108
|
+
let scoreBg = "#fef2f2";
|
|
109
|
+
let scoreText = "#b91c1c";
|
|
110
|
+
if (percentage >= 80) {
|
|
111
|
+
scoreColor = "#16a34a";
|
|
112
|
+
scoreBg = "#f0fdf4";
|
|
113
|
+
scoreText = "#15803d";
|
|
114
|
+
} else if (percentage >= 50) {
|
|
115
|
+
scoreColor = "#ca8a04";
|
|
116
|
+
scoreBg = "#fefce8";
|
|
117
|
+
scoreText = "#a16207";
|
|
118
|
+
}
|
|
119
|
+
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
120
|
+
"div",
|
|
121
|
+
{
|
|
122
|
+
style: {
|
|
123
|
+
borderRadius: 10,
|
|
124
|
+
border: "1px solid #e5e7eb",
|
|
125
|
+
overflow: "hidden",
|
|
126
|
+
fontFamily: "inherit"
|
|
127
|
+
},
|
|
128
|
+
children: [
|
|
129
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
130
|
+
"div",
|
|
131
|
+
{
|
|
132
|
+
style: {
|
|
133
|
+
padding: "16px 20px 14px",
|
|
134
|
+
borderBottom: "1px solid #f3f4f6",
|
|
135
|
+
display: "flex",
|
|
136
|
+
alignItems: "center",
|
|
137
|
+
justifyContent: "space-between",
|
|
138
|
+
gap: 12
|
|
139
|
+
},
|
|
140
|
+
children: [
|
|
141
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { children: [
|
|
142
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { style: { fontSize: 13, fontWeight: 600, color: "#111827", marginBottom: 2 }, children: "AI Overview Readiness" }),
|
|
143
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { style: { fontSize: 11, color: "#9ca3af" }, children: "Signals that improve visibility in AI-generated overviews" })
|
|
144
|
+
] }),
|
|
145
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
146
|
+
"div",
|
|
147
|
+
{
|
|
148
|
+
style: {
|
|
149
|
+
backgroundColor: scoreBg,
|
|
150
|
+
borderRadius: 20,
|
|
151
|
+
padding: "4px 12px",
|
|
152
|
+
display: "flex",
|
|
153
|
+
alignItems: "center",
|
|
154
|
+
gap: 4,
|
|
155
|
+
flexShrink: 0
|
|
156
|
+
},
|
|
157
|
+
children: [
|
|
158
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { style: { fontSize: 16, fontWeight: 700, color: scoreColor }, children: totalPassing }),
|
|
159
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { style: { fontSize: 12, color: scoreText, opacity: 0.7 }, children: [
|
|
160
|
+
"/ ",
|
|
161
|
+
totalChecks
|
|
162
|
+
] })
|
|
163
|
+
]
|
|
164
|
+
}
|
|
165
|
+
)
|
|
166
|
+
]
|
|
167
|
+
}
|
|
168
|
+
),
|
|
169
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { style: { height: 3, backgroundColor: "#f3f4f6" }, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
170
|
+
"div",
|
|
171
|
+
{
|
|
172
|
+
style: {
|
|
173
|
+
height: "100%",
|
|
174
|
+
width: `${percentage}%`,
|
|
175
|
+
backgroundColor: scoreColor,
|
|
176
|
+
transition: "width 0.4s ease"
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
) }),
|
|
180
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { style: { padding: "10px 20px" }, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
181
|
+
"button",
|
|
182
|
+
{
|
|
183
|
+
type: "button",
|
|
184
|
+
onClick: () => setExpanded((prev) => !prev),
|
|
185
|
+
style: {
|
|
186
|
+
background: "none",
|
|
187
|
+
border: "none",
|
|
188
|
+
padding: 0,
|
|
189
|
+
cursor: "pointer",
|
|
190
|
+
fontSize: 12,
|
|
191
|
+
color: "#6366f1",
|
|
192
|
+
fontWeight: 500,
|
|
193
|
+
display: "flex",
|
|
194
|
+
alignItems: "center",
|
|
195
|
+
gap: 4
|
|
196
|
+
},
|
|
197
|
+
children: [
|
|
198
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
199
|
+
"svg",
|
|
200
|
+
{
|
|
201
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
202
|
+
width: "12",
|
|
203
|
+
height: "12",
|
|
204
|
+
viewBox: "0 0 24 24",
|
|
205
|
+
fill: "none",
|
|
206
|
+
stroke: "currentColor",
|
|
207
|
+
strokeWidth: "2",
|
|
208
|
+
strokeLinecap: "round",
|
|
209
|
+
strokeLinejoin: "round",
|
|
210
|
+
style: {
|
|
211
|
+
display: "inline-block",
|
|
212
|
+
transform: expanded ? "rotate(90deg)" : "rotate(0deg)",
|
|
213
|
+
transition: "transform 0.2s ease",
|
|
214
|
+
flexShrink: 0
|
|
215
|
+
},
|
|
216
|
+
children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { d: "m9 18 6-6-6-6" })
|
|
217
|
+
}
|
|
218
|
+
),
|
|
219
|
+
expanded ? "Hide checks" : "Show all checks"
|
|
220
|
+
]
|
|
221
|
+
}
|
|
222
|
+
) }),
|
|
223
|
+
expanded && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { children: [
|
|
224
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { style: { padding: "0 20px 16px" }, children: [
|
|
225
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
226
|
+
"div",
|
|
227
|
+
{
|
|
228
|
+
style: {
|
|
229
|
+
fontSize: 10,
|
|
230
|
+
fontWeight: 700,
|
|
231
|
+
letterSpacing: "0.08em",
|
|
232
|
+
color: "#9ca3af",
|
|
233
|
+
marginBottom: 10,
|
|
234
|
+
textTransform: "uppercase"
|
|
235
|
+
},
|
|
236
|
+
children: "Core Checks"
|
|
237
|
+
}
|
|
238
|
+
),
|
|
239
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { style: { display: "flex", flexDirection: "column", gap: 6 }, children: freeChecks.map((check) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, CheckRow, { check }, check.id)) })
|
|
240
|
+
] }),
|
|
241
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
242
|
+
"div",
|
|
243
|
+
{
|
|
244
|
+
style: {
|
|
245
|
+
margin: "0 12px 12px",
|
|
246
|
+
borderRadius: 8,
|
|
247
|
+
backgroundColor: licenseKey ? "#faf5ff" : "#f9fafb",
|
|
248
|
+
border: `1px solid ${licenseKey ? "#e9d5ff" : "#f3f4f6"}`,
|
|
249
|
+
overflow: "hidden"
|
|
250
|
+
},
|
|
251
|
+
children: [
|
|
252
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
253
|
+
"div",
|
|
254
|
+
{
|
|
255
|
+
style: {
|
|
256
|
+
padding: "10px 16px",
|
|
257
|
+
borderBottom: `1px solid ${licenseKey ? "#e9d5ff" : "#f3f4f6"}`,
|
|
258
|
+
display: "flex",
|
|
259
|
+
alignItems: "center",
|
|
260
|
+
gap: 8
|
|
261
|
+
},
|
|
262
|
+
children: [
|
|
263
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
264
|
+
"span",
|
|
265
|
+
{
|
|
266
|
+
style: {
|
|
267
|
+
fontSize: 10,
|
|
268
|
+
fontWeight: 700,
|
|
269
|
+
letterSpacing: "0.08em",
|
|
270
|
+
color: licenseKey ? "#7c3aed" : "#9ca3af",
|
|
271
|
+
textTransform: "uppercase"
|
|
272
|
+
},
|
|
273
|
+
children: "Pro Insights"
|
|
274
|
+
}
|
|
275
|
+
),
|
|
276
|
+
!licenseKey && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
277
|
+
"span",
|
|
278
|
+
{
|
|
279
|
+
style: {
|
|
280
|
+
fontSize: 10,
|
|
281
|
+
backgroundColor: "#f3e8ff",
|
|
282
|
+
color: "#7c3aed",
|
|
283
|
+
borderRadius: 4,
|
|
284
|
+
padding: "1px 6px",
|
|
285
|
+
fontWeight: 600
|
|
286
|
+
},
|
|
287
|
+
children: "Unlock with licenseKey"
|
|
288
|
+
}
|
|
289
|
+
),
|
|
290
|
+
licenseKey && proChecks && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
291
|
+
"span",
|
|
292
|
+
{
|
|
293
|
+
style: {
|
|
294
|
+
fontSize: 10,
|
|
295
|
+
backgroundColor: "#d8b4fe",
|
|
296
|
+
color: "#5b21b6",
|
|
297
|
+
borderRadius: 4,
|
|
298
|
+
padding: "1px 6px",
|
|
299
|
+
fontWeight: 600
|
|
300
|
+
},
|
|
301
|
+
children: [
|
|
302
|
+
proPassing,
|
|
303
|
+
" / ",
|
|
304
|
+
proChecks.length,
|
|
305
|
+
" passing"
|
|
306
|
+
]
|
|
307
|
+
}
|
|
308
|
+
)
|
|
309
|
+
]
|
|
310
|
+
}
|
|
311
|
+
),
|
|
312
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { style: { padding: "10px 16px" }, children: proChecks ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _seofieldspro.GEOChecklistProChecks, { checks: proChecks }) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _seofieldspro.GEOLockedTeaser, {}) })
|
|
313
|
+
]
|
|
314
|
+
}
|
|
315
|
+
)
|
|
316
|
+
] })
|
|
317
|
+
]
|
|
318
|
+
}
|
|
319
|
+
);
|
|
320
|
+
};
|
|
321
|
+
function CheckRow({ check }) {
|
|
322
|
+
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
323
|
+
"div",
|
|
324
|
+
{
|
|
325
|
+
style: {
|
|
326
|
+
display: "flex",
|
|
327
|
+
alignItems: "flex-start",
|
|
328
|
+
gap: 10,
|
|
329
|
+
padding: "9px 12px",
|
|
330
|
+
borderRadius: 7,
|
|
331
|
+
backgroundColor: check.pass ? "transparent" : "#fff8f8",
|
|
332
|
+
border: `1px solid ${check.pass ? "transparent" : "#fee2e2"}`
|
|
333
|
+
},
|
|
334
|
+
children: [
|
|
335
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
336
|
+
"div",
|
|
337
|
+
{
|
|
338
|
+
style: {
|
|
339
|
+
width: 20,
|
|
340
|
+
height: 20,
|
|
341
|
+
borderRadius: "50%",
|
|
342
|
+
backgroundColor: check.pass ? "#dcfce7" : "#fee2e2",
|
|
343
|
+
display: "flex",
|
|
344
|
+
alignItems: "center",
|
|
345
|
+
justifyContent: "center",
|
|
346
|
+
flexShrink: 0,
|
|
347
|
+
marginTop: 1
|
|
348
|
+
},
|
|
349
|
+
children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
350
|
+
"span",
|
|
351
|
+
{
|
|
352
|
+
style: {
|
|
353
|
+
fontSize: 10,
|
|
354
|
+
fontWeight: 800,
|
|
355
|
+
color: check.pass ? "#16a34a" : "#dc2626",
|
|
356
|
+
lineHeight: 1
|
|
357
|
+
},
|
|
358
|
+
children: check.pass ? "\u2713" : "\u2717"
|
|
359
|
+
}
|
|
360
|
+
)
|
|
361
|
+
}
|
|
362
|
+
),
|
|
363
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { style: { flex: 1, minWidth: 0 }, children: [
|
|
364
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
365
|
+
"div",
|
|
366
|
+
{
|
|
367
|
+
style: {
|
|
368
|
+
fontSize: 12,
|
|
369
|
+
fontWeight: 500,
|
|
370
|
+
color: check.pass ? "#374151" : "#1f2937",
|
|
371
|
+
lineHeight: 1.4
|
|
372
|
+
},
|
|
373
|
+
children: check.label
|
|
374
|
+
}
|
|
375
|
+
),
|
|
376
|
+
!check.pass && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { style: { fontSize: 11, color: "#9ca3af", marginTop: 3, lineHeight: 1.5 }, children: check.hint })
|
|
377
|
+
] })
|
|
378
|
+
]
|
|
379
|
+
}
|
|
380
|
+
);
|
|
381
|
+
}
|
|
382
|
+
var GEOChecklist_default = GEOChecklist;
|
|
383
|
+
|
|
384
|
+
// src/components/meta/FocusKeywordInput.tsx
|
|
385
|
+
var _ui = require('@sanity/ui');
|
|
386
|
+
|
|
387
|
+
|
|
388
|
+
|
|
389
|
+
// src/components/ai/SeoGenButton.tsx
|
|
390
|
+
var _icons = require('@sanity/icons');
|
|
391
|
+
|
|
392
|
+
|
|
393
|
+
|
|
394
|
+
|
|
395
|
+
// src/utils/extractDocText.ts
|
|
396
|
+
function extractBlockText(block) {
|
|
397
|
+
if (block._type === "block" && Array.isArray(block.children)) {
|
|
398
|
+
return block.children.map((s) => {
|
|
399
|
+
var _a;
|
|
400
|
+
return (_a = s.text) != null ? _a : "";
|
|
401
|
+
}).join("");
|
|
402
|
+
}
|
|
403
|
+
const parts = [];
|
|
404
|
+
for (const key of Object.keys(block)) {
|
|
405
|
+
if (key === "_type" || key === "_key") continue;
|
|
406
|
+
const val = block[key];
|
|
407
|
+
if (typeof val === "string" && val.trim()) parts.push(val.trim());
|
|
408
|
+
else if (Array.isArray(val)) parts.push(extractArrayText(val));
|
|
409
|
+
}
|
|
410
|
+
return parts.filter(Boolean).join(" ");
|
|
411
|
+
}
|
|
412
|
+
function extractArrayText(arr) {
|
|
413
|
+
return arr.map((b) => extractBlockText(b)).filter(Boolean).join("\n");
|
|
414
|
+
}
|
|
415
|
+
function extractFieldText(value) {
|
|
416
|
+
if (typeof value === "string") return value;
|
|
417
|
+
if (!Array.isArray(value)) return "";
|
|
418
|
+
return extractArrayText(value).replace(/\n{3,}/g, "\n\n").trim();
|
|
419
|
+
}
|
|
420
|
+
function extractDocText(doc, bodyField) {
|
|
421
|
+
const fields = [bodyField].flat();
|
|
422
|
+
const text = fields.map((f) => extractFieldText(doc[f])).filter(Boolean).join("\n\n");
|
|
423
|
+
return text.slice(0, 4e3);
|
|
424
|
+
}
|
|
425
|
+
function resolveContentFields(content, docType) {
|
|
426
|
+
var _a;
|
|
427
|
+
if (!content || typeof content === "string" || Array.isArray(content)) return content != null ? content : "body";
|
|
428
|
+
const key = docType && docType in content ? docType : "default";
|
|
429
|
+
return (_a = content[key]) != null ? _a : "body";
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
// src/components/ai/SeoGenButton.tsx
|
|
433
|
+
|
|
434
|
+
function SeoGenButton({
|
|
435
|
+
field,
|
|
436
|
+
ai,
|
|
437
|
+
seoFieldPath,
|
|
438
|
+
onGenerate
|
|
439
|
+
}) {
|
|
440
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
441
|
+
const [state, setState] = _react.useState.call(void 0, "idle");
|
|
442
|
+
const [errorMsg, setErrorMsg] = _react.useState.call(void 0, null);
|
|
443
|
+
const abortRef = _react.useRef.call(void 0, null);
|
|
444
|
+
const cooldownRef = _react.useRef.call(void 0, null);
|
|
445
|
+
const rootDoc = _sanity.useFormValue.call(void 0, []);
|
|
446
|
+
const workspace = _sanity.useWorkspace.call(void 0, );
|
|
447
|
+
const seoObj = _sanity.useFormValue.call(void 0, [seoFieldPath]);
|
|
448
|
+
const focusKeyword = (_a = seoObj == null ? void 0 : seoObj.focusKeyword) != null ? _a : "";
|
|
449
|
+
const keywords = (_b = seoObj == null ? void 0 : seoObj.keywords) != null ? _b : [];
|
|
450
|
+
const bodyField = resolveContentFields(ai == null ? void 0 : ai.content, rootDoc == null ? void 0 : rootDoc._type);
|
|
451
|
+
const content = rootDoc ? extractDocText(rootDoc, bodyField) : "";
|
|
452
|
+
const meta = field === "focusKeyword" ? {
|
|
453
|
+
title: (_c = seoObj == null ? void 0 : seoObj.title) != null ? _c : void 0,
|
|
454
|
+
description: (_d = seoObj == null ? void 0 : seoObj.description) != null ? _d : void 0,
|
|
455
|
+
slug: (_f = (_e = rootDoc == null ? void 0 : rootDoc.slug) == null ? void 0 : _e.current) != null ? _f : void 0
|
|
456
|
+
} : void 0;
|
|
457
|
+
const handleGenerate = _react.useCallback.call(void 0, async () => {
|
|
458
|
+
var _a2;
|
|
459
|
+
if (!ai) return;
|
|
460
|
+
(_a2 = abortRef.current) == null ? void 0 : _a2.abort();
|
|
461
|
+
if (cooldownRef.current) clearTimeout(cooldownRef.current);
|
|
462
|
+
setState("loading");
|
|
463
|
+
setErrorMsg(null);
|
|
464
|
+
try {
|
|
465
|
+
let result;
|
|
466
|
+
if (ai.testMode) {
|
|
467
|
+
await new Promise((r) => setTimeout(r, 400));
|
|
468
|
+
result = _chunk3OK3S2F7cjs.pickTestOutput.call(void 0, field);
|
|
469
|
+
} else {
|
|
470
|
+
const controller = new AbortController();
|
|
471
|
+
abortRef.current = controller;
|
|
472
|
+
result = await _chunk3OK3S2F7cjs.generateSeoText.call(void 0, field, content, focusKeyword, keywords, {
|
|
473
|
+
config: _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {}, ai), { _projectId: workspace.projectId }),
|
|
474
|
+
signal: controller.signal,
|
|
475
|
+
meta
|
|
476
|
+
});
|
|
477
|
+
}
|
|
478
|
+
onGenerate(result);
|
|
479
|
+
setState("cooldown");
|
|
480
|
+
cooldownRef.current = setTimeout(() => setState("idle"), 2e3);
|
|
481
|
+
} catch (err) {
|
|
482
|
+
if (err.name === "AbortError") {
|
|
483
|
+
setState("idle");
|
|
484
|
+
return;
|
|
485
|
+
}
|
|
486
|
+
setErrorMsg(err instanceof Error ? err.message : "Generation failed.");
|
|
487
|
+
setState("error");
|
|
488
|
+
}
|
|
489
|
+
}, [ai, field, content, focusKeyword, keywords, meta, onGenerate, workspace.projectId]);
|
|
490
|
+
_react.useEffect.call(void 0, () => {
|
|
491
|
+
return () => {
|
|
492
|
+
var _a2;
|
|
493
|
+
(_a2 = abortRef.current) == null ? void 0 : _a2.abort();
|
|
494
|
+
if (cooldownRef.current) clearTimeout(cooldownRef.current);
|
|
495
|
+
};
|
|
496
|
+
}, []);
|
|
497
|
+
const isConfigured = Boolean(
|
|
498
|
+
(ai == null ? void 0 : ai.apiKey) || (ai == null ? void 0 : ai.endpoint) || (ai == null ? void 0 : ai.testMode) || (ai == null ? void 0 : ai.provider) === "ollama"
|
|
499
|
+
);
|
|
500
|
+
if (!isConfigured) return null;
|
|
501
|
+
const isLoading = state === "loading";
|
|
502
|
+
const isTestMode = Boolean(ai == null ? void 0 : ai.testMode);
|
|
503
|
+
let buttonText = "Generate with AI";
|
|
504
|
+
if (isLoading) buttonText = "Generating\u2026";
|
|
505
|
+
else if (isTestMode) buttonText = "Generate (test)";
|
|
506
|
+
const isFullWidth = ((_g = ai == null ? void 0 : ai.buttonWidth) != null ? _g : "full") === "full";
|
|
507
|
+
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _ui.Flex, { direction: "column", gap: 1, align: isFullWidth ? "stretch" : "flex-start", children: [
|
|
508
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
509
|
+
_ui.Button,
|
|
510
|
+
{
|
|
511
|
+
mode: "ghost",
|
|
512
|
+
tone: "primary",
|
|
513
|
+
paddingX: isFullWidth ? 2 : 3,
|
|
514
|
+
paddingY: 3,
|
|
515
|
+
fontSize: 1,
|
|
516
|
+
icon: _icons.SparklesIcon,
|
|
517
|
+
text: buttonText,
|
|
518
|
+
onClick: handleGenerate,
|
|
519
|
+
disabled: isLoading || state === "cooldown"
|
|
520
|
+
}
|
|
521
|
+
),
|
|
522
|
+
!content && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _ui.Text, { size: 0, muted: true, children: [
|
|
523
|
+
"(Set ",
|
|
524
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "code", { children: "ai.content" }),
|
|
525
|
+
" in plugin config for better results)"
|
|
526
|
+
] }),
|
|
527
|
+
state === "error" && errorMsg && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _ui.Card, { padding: 2, tone: "critical", radius: 2, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _ui.Text, { size: 1, children: errorMsg }) })
|
|
528
|
+
] });
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
// src/components/meta/FocusKeywordInput.tsx
|
|
532
|
+
|
|
533
|
+
var FocusKeywordInput = (props) => {
|
|
534
|
+
var _a;
|
|
535
|
+
const { value, renderDefault, path, schemaType, onChange } = props;
|
|
536
|
+
const { options } = schemaType;
|
|
537
|
+
const parent = _sanity.useFormValue.call(void 0, [path[0]]);
|
|
538
|
+
const rootDoc = _sanity.useFormValue.call(void 0, []);
|
|
539
|
+
const feedbackItems = _react.useMemo.call(void 0, () => {
|
|
540
|
+
var _a2;
|
|
541
|
+
if (!value) return [];
|
|
542
|
+
const title = (parent == null ? void 0 : parent.title) || "";
|
|
543
|
+
const description = (parent == null ? void 0 : parent.description) || "";
|
|
544
|
+
const slug = ((_a2 = rootDoc == null ? void 0 : rootDoc.slug) == null ? void 0 : _a2.current) || "";
|
|
545
|
+
const placement = _chunkY46ACXM4cjs.getFocusKeywordPlacement.call(void 0, value, title, description);
|
|
546
|
+
const items = [];
|
|
547
|
+
if (title) {
|
|
548
|
+
if (placement.atStartOfTitle) {
|
|
549
|
+
items.push({ text: "Keyword at start of title \u2014 excellent", color: "green" });
|
|
550
|
+
} else if (placement.inTitle) {
|
|
551
|
+
items.push({
|
|
552
|
+
text: "Keyword in title \u2014 move it to the start for more prominence",
|
|
553
|
+
color: "orange"
|
|
554
|
+
});
|
|
555
|
+
} else {
|
|
556
|
+
items.push({ text: "Keyword missing from meta title", color: "red" });
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
if (description) {
|
|
560
|
+
if (placement.inDescription) {
|
|
561
|
+
items.push({ text: "Keyword in meta description", color: "green" });
|
|
562
|
+
} else {
|
|
563
|
+
items.push({ text: "Not in description \u2014 include it naturally", color: "orange" });
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
if (slug) {
|
|
567
|
+
const kwSlug = value.toLowerCase().replace(/\s+/g, "-");
|
|
568
|
+
if (slug.includes(kwSlug)) {
|
|
569
|
+
items.push({ text: "Keyword in URL slug", color: "green" });
|
|
570
|
+
} else {
|
|
571
|
+
items.push({
|
|
572
|
+
text: "Keyword not in URL slug \u2014 consider it for new pages",
|
|
573
|
+
color: "orange"
|
|
574
|
+
});
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
if (placement.isStuffed) {
|
|
578
|
+
items.push({
|
|
579
|
+
text: "Keyword appears too many times in title \u2014 avoid stuffing",
|
|
580
|
+
color: "red"
|
|
581
|
+
});
|
|
582
|
+
}
|
|
583
|
+
return items;
|
|
584
|
+
}, [value, parent == null ? void 0 : parent.title, parent == null ? void 0 : parent.description, (_a = rootDoc == null ? void 0 : rootDoc.slug) == null ? void 0 : _a.current]);
|
|
585
|
+
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _ui.Stack, { space: 3, children: [
|
|
586
|
+
renderDefault(props),
|
|
587
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
588
|
+
SeoGenButton,
|
|
589
|
+
{
|
|
590
|
+
field: "focusKeyword",
|
|
591
|
+
ai: options == null ? void 0 : options.ai,
|
|
592
|
+
seoFieldPath: String(path[0]),
|
|
593
|
+
onGenerate: (v) => onChange(_sanity.PatchEvent.from(_sanity.set.call(void 0, v)))
|
|
594
|
+
}
|
|
595
|
+
),
|
|
596
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _ui.Stack, { space: 2, children: feedbackItems.map((item) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { style: { display: "flex", alignItems: "center", gap: 7 }, children: [
|
|
597
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
598
|
+
"div",
|
|
599
|
+
{
|
|
600
|
+
style: {
|
|
601
|
+
minWidth: 10,
|
|
602
|
+
height: 10,
|
|
603
|
+
borderRadius: "50%",
|
|
604
|
+
backgroundColor: item.color
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
),
|
|
608
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _ui.Text, { weight: "bold", muted: true, size: 14, children: item.text })
|
|
609
|
+
] }, item.text)) })
|
|
610
|
+
] });
|
|
611
|
+
};
|
|
612
|
+
var FocusKeywordInput_default = FocusKeywordInput;
|
|
613
|
+
|
|
614
|
+
// src/components/meta/KeywordsInput.tsx
|
|
615
|
+
|
|
616
|
+
|
|
617
|
+
|
|
618
|
+
// src/components/ai/KeywordSuggestions.tsx
|
|
619
|
+
|
|
620
|
+
|
|
621
|
+
|
|
622
|
+
|
|
623
|
+
|
|
624
|
+
function KeywordSuggestions({
|
|
625
|
+
ai,
|
|
626
|
+
seoFieldPath,
|
|
627
|
+
existing,
|
|
628
|
+
onAdd,
|
|
629
|
+
onAddAll
|
|
630
|
+
}) {
|
|
631
|
+
var _a;
|
|
632
|
+
const [panelState, setPanelState] = _react.useState.call(void 0, "idle");
|
|
633
|
+
const [suggestions, setSuggestions] = _react.useState.call(void 0, []);
|
|
634
|
+
const [errorMsg, setErrorMsg] = _react.useState.call(void 0, null);
|
|
635
|
+
const abortRef = _react.useRef.call(void 0, null);
|
|
636
|
+
const rootDoc = _sanity.useFormValue.call(void 0, []);
|
|
637
|
+
const workspace = _sanity.useWorkspace.call(void 0, );
|
|
638
|
+
const seoObj = _sanity.useFormValue.call(void 0, [seoFieldPath]);
|
|
639
|
+
const focusKeyword = (_a = seoObj == null ? void 0 : seoObj.focusKeyword) != null ? _a : "";
|
|
640
|
+
const bodyField = resolveContentFields(ai == null ? void 0 : ai.content, rootDoc == null ? void 0 : rootDoc._type);
|
|
641
|
+
const content = rootDoc ? extractDocText(rootDoc, bodyField) : "";
|
|
642
|
+
const handleSuggest = _react.useCallback.call(void 0, async () => {
|
|
643
|
+
var _a2;
|
|
644
|
+
if (!ai) return;
|
|
645
|
+
(_a2 = abortRef.current) == null ? void 0 : _a2.abort();
|
|
646
|
+
abortRef.current = new AbortController();
|
|
647
|
+
setPanelState("loading");
|
|
648
|
+
setErrorMsg(null);
|
|
649
|
+
setSuggestions([]);
|
|
650
|
+
try {
|
|
651
|
+
let csv;
|
|
652
|
+
if (ai.testMode) {
|
|
653
|
+
await new Promise((r) => setTimeout(r, 400));
|
|
654
|
+
csv = _chunk3OK3S2F7cjs.pickTestOutput.call(void 0, "keywords");
|
|
655
|
+
} else {
|
|
656
|
+
csv = await _chunk3OK3S2F7cjs.generateSeoText.call(void 0, "keywords", content, focusKeyword, existing, {
|
|
657
|
+
config: _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {}, ai), { _projectId: workspace.projectId }),
|
|
658
|
+
signal: abortRef.current.signal
|
|
659
|
+
});
|
|
660
|
+
}
|
|
661
|
+
const parsed = csv.split(",").map((k) => k.replace(/^["']|["']$/g, "").trim()).filter(Boolean);
|
|
662
|
+
if (parsed.length === 0) {
|
|
663
|
+
setErrorMsg("No keywords returned. Try again.");
|
|
664
|
+
setPanelState("error");
|
|
665
|
+
return;
|
|
666
|
+
}
|
|
667
|
+
setSuggestions(parsed);
|
|
668
|
+
setPanelState("suggestions");
|
|
669
|
+
} catch (err) {
|
|
670
|
+
if (err.name === "AbortError") {
|
|
671
|
+
setPanelState("idle");
|
|
672
|
+
return;
|
|
673
|
+
}
|
|
674
|
+
setErrorMsg(err instanceof Error ? err.message : "Keyword generation failed.");
|
|
675
|
+
setPanelState("error");
|
|
676
|
+
}
|
|
677
|
+
}, [ai, content, focusKeyword, existing, workspace.projectId]);
|
|
678
|
+
const handleAdd = _react.useCallback.call(void 0,
|
|
679
|
+
(kw) => {
|
|
680
|
+
onAdd(kw);
|
|
681
|
+
setSuggestions((prev) => prev.filter((s) => s !== kw));
|
|
682
|
+
if (suggestions.length <= 1) setPanelState("idle");
|
|
683
|
+
},
|
|
684
|
+
[onAdd, suggestions.length]
|
|
685
|
+
);
|
|
686
|
+
const handleAddAll = _react.useCallback.call(void 0, () => {
|
|
687
|
+
const toAdd = suggestions.filter((kw) => !existing.includes(kw));
|
|
688
|
+
if (toAdd.length > 0) onAddAll(toAdd);
|
|
689
|
+
setSuggestions([]);
|
|
690
|
+
setPanelState("idle");
|
|
691
|
+
}, [suggestions, existing, onAddAll]);
|
|
692
|
+
const handleDismiss = _react.useCallback.call(void 0, () => {
|
|
693
|
+
var _a2;
|
|
694
|
+
(_a2 = abortRef.current) == null ? void 0 : _a2.abort();
|
|
695
|
+
setSuggestions([]);
|
|
696
|
+
setPanelState("idle");
|
|
697
|
+
setErrorMsg(null);
|
|
698
|
+
}, []);
|
|
699
|
+
_react.useEffect.call(void 0, () => {
|
|
700
|
+
return () => {
|
|
701
|
+
var _a2;
|
|
702
|
+
(_a2 = abortRef.current) == null ? void 0 : _a2.abort();
|
|
703
|
+
};
|
|
704
|
+
}, []);
|
|
705
|
+
const isConfigured = Boolean(
|
|
706
|
+
(ai == null ? void 0 : ai.apiKey) || (ai == null ? void 0 : ai.endpoint) || (ai == null ? void 0 : ai.testMode) || (ai == null ? void 0 : ai.provider) === "ollama"
|
|
707
|
+
);
|
|
708
|
+
if (!isConfigured) return null;
|
|
709
|
+
if (panelState === "idle" || panelState === "error") {
|
|
710
|
+
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _ui.Stack, { space: 2, children: [
|
|
711
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
712
|
+
_ui.Button,
|
|
713
|
+
{
|
|
714
|
+
mode: "ghost",
|
|
715
|
+
tone: "primary",
|
|
716
|
+
paddingX: 2,
|
|
717
|
+
paddingY: 3,
|
|
718
|
+
fontSize: 1,
|
|
719
|
+
icon: _icons.SparklesIcon,
|
|
720
|
+
text: (ai == null ? void 0 : ai.testMode) ? "Suggest Keywords (test)" : "Suggest Keywords with AI",
|
|
721
|
+
onClick: handleSuggest
|
|
722
|
+
}
|
|
723
|
+
),
|
|
724
|
+
panelState === "error" && errorMsg && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _ui.Card, { padding: 2, tone: "critical", radius: 2, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _ui.Text, { size: 1, children: errorMsg }) })
|
|
725
|
+
] });
|
|
726
|
+
}
|
|
727
|
+
if (panelState === "loading") {
|
|
728
|
+
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _ui.Flex, { align: "center", gap: 2, paddingY: 2, children: [
|
|
729
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _ui.Spinner, { muted: true }),
|
|
730
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _ui.Text, { size: 1, muted: true, children: "Finding keywords\u2026" })
|
|
731
|
+
] });
|
|
732
|
+
}
|
|
733
|
+
const pendingSuggestions = suggestions.filter((kw) => !existing.includes(kw));
|
|
734
|
+
const alreadyAdded = suggestions.filter((kw) => existing.includes(kw));
|
|
735
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _ui.Card, { padding: 3, radius: 2, tone: "transparent", border: true, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _ui.Stack, { space: 3, children: [
|
|
736
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _ui.Flex, { align: "center", justify: "space-between", children: [
|
|
737
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _ui.Text, { size: 1, weight: "semibold", muted: true, children: "AI keyword suggestions" }),
|
|
738
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _ui.Flex, { gap: 2, children: [
|
|
739
|
+
pendingSuggestions.length > 1 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
740
|
+
_ui.Button,
|
|
741
|
+
{
|
|
742
|
+
mode: "ghost",
|
|
743
|
+
tone: "primary",
|
|
744
|
+
paddingX: 2,
|
|
745
|
+
paddingY: 2,
|
|
746
|
+
fontSize: 1,
|
|
747
|
+
text: "Add all",
|
|
748
|
+
onClick: handleAddAll
|
|
749
|
+
}
|
|
750
|
+
),
|
|
751
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
752
|
+
_ui.Button,
|
|
753
|
+
{
|
|
754
|
+
mode: "ghost",
|
|
755
|
+
tone: "default",
|
|
756
|
+
paddingX: 2,
|
|
757
|
+
paddingY: 2,
|
|
758
|
+
fontSize: 1,
|
|
759
|
+
text: "Dismiss",
|
|
760
|
+
onClick: handleDismiss
|
|
761
|
+
}
|
|
762
|
+
)
|
|
763
|
+
] })
|
|
764
|
+
] }),
|
|
765
|
+
pendingSuggestions.length > 0 && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _ui.Box, { children: [
|
|
766
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _ui.Text, { size: 0, muted: true, style: { marginBottom: 8 }, children: "Click to add:" }),
|
|
767
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _ui.Flex, { gap: 2, wrap: "wrap", style: { marginTop: 6 }, children: pendingSuggestions.map((kw) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
768
|
+
"button",
|
|
769
|
+
{
|
|
770
|
+
type: "button",
|
|
771
|
+
onClick: () => handleAdd(kw),
|
|
772
|
+
style: {
|
|
773
|
+
padding: "4px 10px",
|
|
774
|
+
borderRadius: 20,
|
|
775
|
+
border: "1px solid var(--card-border-color)",
|
|
776
|
+
background: "transparent",
|
|
777
|
+
color: "var(--card-fg-color)",
|
|
778
|
+
cursor: "pointer",
|
|
779
|
+
fontSize: 12,
|
|
780
|
+
lineHeight: 1.4,
|
|
781
|
+
transition: "background 0.15s"
|
|
782
|
+
},
|
|
783
|
+
onMouseEnter: (e) => {
|
|
784
|
+
;
|
|
785
|
+
e.currentTarget.style.background = "var(--card-border-color)";
|
|
786
|
+
},
|
|
787
|
+
onMouseLeave: (e) => {
|
|
788
|
+
;
|
|
789
|
+
e.currentTarget.style.background = "transparent";
|
|
790
|
+
},
|
|
791
|
+
children: [
|
|
792
|
+
"+ ",
|
|
793
|
+
kw
|
|
794
|
+
]
|
|
795
|
+
},
|
|
796
|
+
kw
|
|
797
|
+
)) })
|
|
798
|
+
] }),
|
|
799
|
+
alreadyAdded.length > 0 && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _ui.Box, { children: [
|
|
800
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _ui.Text, { size: 0, muted: true, style: { marginBottom: 6 }, children: "Already added:" }),
|
|
801
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _ui.Flex, { gap: 2, wrap: "wrap", style: { marginTop: 4 }, children: alreadyAdded.map((kw) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _ui.Badge, { tone: "positive", radius: 5, fontSize: 0, padding: 2, children: [
|
|
802
|
+
"\u2713 ",
|
|
803
|
+
kw
|
|
804
|
+
] }, kw)) })
|
|
805
|
+
] }),
|
|
806
|
+
pendingSuggestions.length === 0 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _ui.Text, { size: 1, muted: true, children: "All suggested keywords added." })
|
|
807
|
+
] }) });
|
|
808
|
+
}
|
|
809
|
+
|
|
810
|
+
// src/components/meta/KeywordsInput.tsx
|
|
811
|
+
|
|
812
|
+
var KeywordsInput = (props) => {
|
|
813
|
+
const { value, renderDefault, path, schemaType, onChange } = props;
|
|
814
|
+
const { options } = schemaType;
|
|
815
|
+
const existing = value != null ? value : [];
|
|
816
|
+
const handleAdd = (kw) => {
|
|
817
|
+
if (existing.includes(kw)) return;
|
|
818
|
+
onChange(_sanity.PatchEvent.from(_sanity.set.call(void 0, [...existing, kw])));
|
|
819
|
+
};
|
|
820
|
+
const handleAddAll = (keywords) => {
|
|
821
|
+
const merged = [.../* @__PURE__ */ new Set([...existing, ...keywords])];
|
|
822
|
+
onChange(_sanity.PatchEvent.from(_sanity.set.call(void 0, merged)));
|
|
823
|
+
};
|
|
824
|
+
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _ui.Stack, { space: 3, children: [
|
|
825
|
+
renderDefault(props),
|
|
826
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
827
|
+
KeywordSuggestions,
|
|
828
|
+
{
|
|
829
|
+
ai: options == null ? void 0 : options.ai,
|
|
830
|
+
seoFieldPath: String(path[0]),
|
|
831
|
+
existing,
|
|
832
|
+
onAdd: handleAdd,
|
|
833
|
+
onAddAll: handleAddAll
|
|
834
|
+
}
|
|
835
|
+
)
|
|
836
|
+
] });
|
|
837
|
+
};
|
|
838
|
+
var KeywordsInput_default = KeywordsInput;
|
|
839
|
+
|
|
840
|
+
// src/components/meta/MetaDescription.tsx
|
|
841
|
+
|
|
2
842
|
|
|
3
|
-
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
843
|
|
|
5
|
-
var chunkZBHLMQTS_cjs = require('./chunk-ZBHLMQTS.cjs');
|
|
6
|
-
var chunkS367Y35J_cjs = require('./chunk-S367Y35J.cjs');
|
|
7
|
-
var react = require('react');
|
|
8
|
-
var sanity = require('sanity');
|
|
9
|
-
var ui = require('@sanity/ui');
|
|
10
|
-
var jsxRuntime = require('react/jsx-runtime');
|
|
11
844
|
|
|
12
845
|
var MetaDescription = (props) => {
|
|
13
|
-
const { value, renderDefault, path } = props;
|
|
14
|
-
const
|
|
846
|
+
const { value, renderDefault, path, schemaType, onChange } = props;
|
|
847
|
+
const { options } = schemaType;
|
|
848
|
+
const parent = _sanity.useFormValue.call(void 0, [path[0]]);
|
|
15
849
|
const isParentseoField = parent && (parent == null ? void 0 : parent._type) === "seoFields";
|
|
16
|
-
const keywords =
|
|
17
|
-
const feedbackItems =
|
|
18
|
-
() =>
|
|
850
|
+
const keywords = _react.useMemo.call(void 0, () => (parent == null ? void 0 : parent.keywords) || [], [parent == null ? void 0 : parent.keywords]);
|
|
851
|
+
const feedbackItems = _react.useMemo.call(void 0,
|
|
852
|
+
() => _chunkY46ACXM4cjs.getMetaDescriptionValidationMessages.call(void 0, value || "", keywords, isParentseoField),
|
|
19
853
|
[value, keywords, isParentseoField]
|
|
20
854
|
);
|
|
21
|
-
|
|
855
|
+
const readability = _react.useMemo.call(void 0, () => _chunk3OK3S2F7cjs.analyzeReadability.call(void 0, value || ""), [value]);
|
|
856
|
+
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _ui.Stack, { space: 3, children: [
|
|
22
857
|
renderDefault(props),
|
|
23
|
-
/* @__PURE__ */
|
|
24
|
-
|
|
858
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
859
|
+
SeoGenButton,
|
|
860
|
+
{
|
|
861
|
+
field: "description",
|
|
862
|
+
ai: options == null ? void 0 : options.ai,
|
|
863
|
+
seoFieldPath: String(path[0]),
|
|
864
|
+
onGenerate: (v) => onChange(_sanity.PatchEvent.from(_sanity.set.call(void 0, v)))
|
|
865
|
+
}
|
|
866
|
+
),
|
|
867
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _ui.Stack, { space: 2, children: feedbackItems.map((item) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { style: { display: "flex", alignItems: "center", gap: 7 }, children: [
|
|
868
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
25
869
|
"div",
|
|
26
870
|
{
|
|
27
871
|
style: { width: 10, height: 10, borderRadius: "50%", backgroundColor: item.color }
|
|
28
872
|
}
|
|
29
873
|
),
|
|
30
|
-
/* @__PURE__ */
|
|
31
|
-
] }, item.text)) })
|
|
874
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _ui.Text, { weight: "bold", muted: true, size: 14, children: item.text })
|
|
875
|
+
] }, item.text)) }),
|
|
876
|
+
readability && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { style: { display: "flex", alignItems: "center", gap: 7 }, children: [
|
|
877
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
878
|
+
"div",
|
|
879
|
+
{
|
|
880
|
+
style: {
|
|
881
|
+
minWidth: 10,
|
|
882
|
+
height: 10,
|
|
883
|
+
borderRadius: "50%",
|
|
884
|
+
backgroundColor: readability.color
|
|
885
|
+
}
|
|
886
|
+
}
|
|
887
|
+
),
|
|
888
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _ui.Text, { weight: "bold", muted: true, size: 14, children: [
|
|
889
|
+
"Readability: ",
|
|
890
|
+
readability.label,
|
|
891
|
+
" (Flesch ",
|
|
892
|
+
readability.score,
|
|
893
|
+
" \xB7 Grade",
|
|
894
|
+
" ",
|
|
895
|
+
readability.gradeLevel,
|
|
896
|
+
")"
|
|
897
|
+
] })
|
|
898
|
+
] })
|
|
32
899
|
] });
|
|
33
900
|
};
|
|
34
901
|
var MetaDescription_default = MetaDescription;
|
|
902
|
+
|
|
903
|
+
// src/components/meta/MetaImage.tsx
|
|
904
|
+
|
|
905
|
+
|
|
906
|
+
|
|
907
|
+
|
|
35
908
|
var MetaImage = (props) => {
|
|
36
909
|
const { value, renderDefault, path } = props;
|
|
37
|
-
const seoParent =
|
|
910
|
+
const seoParent = _sanity.useFormValue.call(void 0, [path[0]]);
|
|
38
911
|
const hasImage = !!(value == null ? void 0 : value.asset);
|
|
39
|
-
const feedbackItems =
|
|
40
|
-
() =>
|
|
912
|
+
const feedbackItems = _react.useMemo.call(void 0,
|
|
913
|
+
() => _chunkY46ACXM4cjs.getMetaImageValidation.call(void 0, hasImage, seoParent),
|
|
41
914
|
[hasImage, seoParent]
|
|
42
915
|
);
|
|
43
|
-
return /* @__PURE__ */
|
|
916
|
+
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _ui.Stack, { space: 3, children: [
|
|
44
917
|
renderDefault(props),
|
|
45
|
-
/* @__PURE__ */
|
|
46
|
-
/* @__PURE__ */
|
|
918
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _ui.Stack, { space: 2, children: feedbackItems.map((item) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { style: { display: "flex", alignItems: "center", gap: 7 }, children: [
|
|
919
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
47
920
|
"div",
|
|
48
921
|
{
|
|
49
922
|
style: {
|
|
@@ -54,24 +927,233 @@ var MetaImage = (props) => {
|
|
|
54
927
|
}
|
|
55
928
|
}
|
|
56
929
|
),
|
|
57
|
-
/* @__PURE__ */
|
|
930
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _ui.Text, { weight: "bold", muted: true, size: 14, children: item.text })
|
|
58
931
|
] }, item.text)) })
|
|
59
932
|
] });
|
|
60
933
|
};
|
|
61
934
|
var MetaImage_default = MetaImage;
|
|
935
|
+
|
|
936
|
+
// src/components/meta/MetaTagsPreview.tsx
|
|
937
|
+
|
|
938
|
+
|
|
939
|
+
|
|
940
|
+
|
|
941
|
+
function resolveImageUrl(asset, projectId, dataset) {
|
|
942
|
+
const ref = asset == null ? void 0 : asset._ref;
|
|
943
|
+
if (!ref) return null;
|
|
944
|
+
const parts = ref.replace("image-", "").split("-");
|
|
945
|
+
const ext = parts[parts.length - 1];
|
|
946
|
+
const dims = parts[parts.length - 2];
|
|
947
|
+
const id = parts.slice(0, parts.length - 2).join("-");
|
|
948
|
+
return `https://cdn.sanity.io/images/${projectId}/${dataset}/${id}-${dims}.${ext}`;
|
|
949
|
+
}
|
|
950
|
+
var MetaTagsPreview = (props) => {
|
|
951
|
+
const { path } = props;
|
|
952
|
+
const [expanded, setExpanded] = _react.useState.call(void 0, false);
|
|
953
|
+
const [copyLabel, setCopyLabel] = _react.useState.call(void 0, "Copy");
|
|
954
|
+
const { scheme } = _sanity.useColorScheme.call(void 0, );
|
|
955
|
+
const seoFields = _sanity.useFormValue.call(void 0, [path[0]]);
|
|
956
|
+
const client = _sanity.useClient.call(void 0, { apiVersion: "2024-01-01" });
|
|
957
|
+
const { projectId = "", dataset = "" } = client.config();
|
|
958
|
+
const rawHtml = _react.useMemo.call(void 0, () => {
|
|
959
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
960
|
+
const lines = [];
|
|
961
|
+
lines.push('<meta charset="UTF-8" />');
|
|
962
|
+
lines.push('<meta name="viewport" content="width=device-width, initial-scale=1" />');
|
|
963
|
+
if (seoFields == null ? void 0 : seoFields.title) lines.push(`<title>${seoFields.title}</title>`);
|
|
964
|
+
if (seoFields == null ? void 0 : seoFields.description)
|
|
965
|
+
lines.push(`<meta name="description" content="${seoFields.description}" />`);
|
|
966
|
+
if (seoFields == null ? void 0 : seoFields.robots) {
|
|
967
|
+
const parts = [];
|
|
968
|
+
if (seoFields.robots.noIndex) parts.push("noindex");
|
|
969
|
+
if (seoFields.robots.noFollow) parts.push("nofollow");
|
|
970
|
+
if (seoFields.robots.noTranslate) parts.push("notranslate");
|
|
971
|
+
if (seoFields.robots.noImageIndex) parts.push("noimageindex");
|
|
972
|
+
if (parts.length) lines.push(`<meta name="robots" content="${parts.join(", ")}" />`);
|
|
973
|
+
}
|
|
974
|
+
if ((_a = seoFields == null ? void 0 : seoFields.keywords) == null ? void 0 : _a.length)
|
|
975
|
+
lines.push(`<meta name="keywords" content="${seoFields.keywords.join(", ")}" />`);
|
|
976
|
+
if (seoFields == null ? void 0 : seoFields.canonicalUrl)
|
|
977
|
+
lines.push(`<link rel="canonical" href="${seoFields.canonicalUrl}" />`);
|
|
978
|
+
const og = seoFields == null ? void 0 : seoFields.openGraph;
|
|
979
|
+
if (og == null ? void 0 : og.type) lines.push(`<meta property="og:type" content="${og.type}" />`);
|
|
980
|
+
if (og == null ? void 0 : og.title) lines.push(`<meta property="og:title" content="${og.title}" />`);
|
|
981
|
+
if (og == null ? void 0 : og.description)
|
|
982
|
+
lines.push(`<meta property="og:description" content="${og.description}" />`);
|
|
983
|
+
if (og == null ? void 0 : og.siteName) lines.push(`<meta property="og:site_name" content="${og.siteName}" />`);
|
|
984
|
+
if (og == null ? void 0 : og.url) lines.push(`<meta property="og:url" content="${og.url}" />`);
|
|
985
|
+
const ogImg = (og == null ? void 0 : og.imageUrl) || resolveImageUrl((_b = og == null ? void 0 : og.image) == null ? void 0 : _b.asset, projectId, dataset) || resolveImageUrl((_c = seoFields == null ? void 0 : seoFields.metaImage) == null ? void 0 : _c.asset, projectId, dataset);
|
|
986
|
+
if (ogImg) lines.push(`<meta property="og:image" content="${ogImg}" />`);
|
|
987
|
+
const tw = seoFields == null ? void 0 : seoFields.twitter;
|
|
988
|
+
if (tw == null ? void 0 : tw.card) lines.push(`<meta name="twitter:card" content="${tw.card}" />`);
|
|
989
|
+
if (tw == null ? void 0 : tw.site) lines.push(`<meta name="twitter:site" content="${tw.site}" />`);
|
|
990
|
+
if (tw == null ? void 0 : tw.creator) lines.push(`<meta name="twitter:creator" content="${tw.creator}" />`);
|
|
991
|
+
if (tw == null ? void 0 : tw.title) lines.push(`<meta name="twitter:title" content="${tw.title}" />`);
|
|
992
|
+
if (tw == null ? void 0 : tw.description)
|
|
993
|
+
lines.push(`<meta name="twitter:description" content="${tw.description}" />`);
|
|
994
|
+
const twImg = (tw == null ? void 0 : tw.imageUrl) || resolveImageUrl((_d = tw == null ? void 0 : tw.image) == null ? void 0 : _d.asset, projectId, dataset);
|
|
995
|
+
if (twImg) lines.push(`<meta name="twitter:image" content="${twImg}" />`);
|
|
996
|
+
if ((_e = seoFields == null ? void 0 : seoFields.hreflangs) == null ? void 0 : _e.length) {
|
|
997
|
+
for (const e of seoFields.hreflangs) {
|
|
998
|
+
if (e.locale && e.url)
|
|
999
|
+
lines.push(`<link rel="alternate" hreflang="${e.locale}" href="${e.url}" />`);
|
|
1000
|
+
}
|
|
1001
|
+
}
|
|
1002
|
+
if ((_f = seoFields == null ? void 0 : seoFields.metaAttributes) == null ? void 0 : _f.length) {
|
|
1003
|
+
for (const attr of seoFields.metaAttributes) {
|
|
1004
|
+
if (attr.key && attr.type === "string" && attr.value) {
|
|
1005
|
+
lines.push(`<meta name="${attr.key}" content="${attr.value}" />`);
|
|
1006
|
+
} else if (attr.key && attr.type === "image" && ((_g = attr.image) == null ? void 0 : _g.asset)) {
|
|
1007
|
+
const imgUrl = resolveImageUrl(attr.image.asset, projectId, dataset);
|
|
1008
|
+
if (imgUrl) lines.push(`<meta name="${attr.key}" content="${imgUrl}" />`);
|
|
1009
|
+
}
|
|
1010
|
+
}
|
|
1011
|
+
}
|
|
1012
|
+
return lines.join("\n");
|
|
1013
|
+
}, [seoFields, projectId, dataset]);
|
|
1014
|
+
const tagCount = _react.useMemo.call(void 0, () => rawHtml.split("\n").filter(Boolean).length, [rawHtml]);
|
|
1015
|
+
const tokens = _react.useMemo.call(void 0, () => _chunk5XTQRILLcjs.tokenizeHtml.call(void 0, rawHtml, scheme), [rawHtml, scheme]);
|
|
1016
|
+
const handleCopy = () => {
|
|
1017
|
+
navigator.clipboard.writeText(rawHtml).then(() => {
|
|
1018
|
+
setCopyLabel("Copied!");
|
|
1019
|
+
setTimeout(() => setCopyLabel("Copy"), 2e3);
|
|
1020
|
+
});
|
|
1021
|
+
};
|
|
1022
|
+
const isDark = scheme === "dark";
|
|
1023
|
+
const codeBg = isDark ? "#161b22" : "#f6f8fa";
|
|
1024
|
+
const codeBorder = isDark ? "#30363d" : "#d0d7de";
|
|
1025
|
+
const headerBg = isDark ? "#21262d" : "#f0f2f4";
|
|
1026
|
+
const headerBorder = isDark ? "#30363d" : "#d0d7de";
|
|
1027
|
+
const headerText = isDark ? "#e6edf3" : "#24292f";
|
|
1028
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _ui.Card, { padding: 3, radius: 2, tone: "default", border: true, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _ui.Stack, { space: 3, children: [
|
|
1029
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _ui.Flex, { align: "center", justify: "space-between", gap: 3, children: [
|
|
1030
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _ui.Text, { weight: "semibold", size: 1, children: "Meta Tags Preview" }),
|
|
1031
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _ui.Flex, { gap: 2, align: "center", children: [
|
|
1032
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _ui.Text, { size: 0, muted: true, children: [
|
|
1033
|
+
tagCount,
|
|
1034
|
+
" tags generated"
|
|
1035
|
+
] }),
|
|
1036
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1037
|
+
_ui.Button,
|
|
1038
|
+
{
|
|
1039
|
+
text: copyLabel,
|
|
1040
|
+
tone: "default",
|
|
1041
|
+
mode: "ghost",
|
|
1042
|
+
fontSize: 1,
|
|
1043
|
+
padding: 2,
|
|
1044
|
+
onClick: handleCopy
|
|
1045
|
+
}
|
|
1046
|
+
)
|
|
1047
|
+
] })
|
|
1048
|
+
] }),
|
|
1049
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
1050
|
+
"button",
|
|
1051
|
+
{
|
|
1052
|
+
type: "button",
|
|
1053
|
+
onClick: () => setExpanded((p) => !p),
|
|
1054
|
+
style: {
|
|
1055
|
+
display: "flex",
|
|
1056
|
+
alignItems: "center",
|
|
1057
|
+
justifyContent: "center",
|
|
1058
|
+
gap: 6,
|
|
1059
|
+
width: "100%",
|
|
1060
|
+
background: headerBg,
|
|
1061
|
+
border: `1px solid ${headerBorder}`,
|
|
1062
|
+
borderRadius: 6,
|
|
1063
|
+
padding: "6px 12px",
|
|
1064
|
+
cursor: "pointer",
|
|
1065
|
+
fontSize: 12,
|
|
1066
|
+
fontWeight: 500,
|
|
1067
|
+
color: headerText
|
|
1068
|
+
},
|
|
1069
|
+
children: [
|
|
1070
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { style: { fontSize: 10 }, children: expanded ? "\u25B2" : "\u25BC" }),
|
|
1071
|
+
expanded ? "Hide tags" : "Show tags"
|
|
1072
|
+
]
|
|
1073
|
+
}
|
|
1074
|
+
),
|
|
1075
|
+
expanded && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
1076
|
+
"div",
|
|
1077
|
+
{
|
|
1078
|
+
style: {
|
|
1079
|
+
borderRadius: 6,
|
|
1080
|
+
border: `1px solid ${codeBorder}`,
|
|
1081
|
+
overflow: "hidden"
|
|
1082
|
+
},
|
|
1083
|
+
children: [
|
|
1084
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
1085
|
+
"div",
|
|
1086
|
+
{
|
|
1087
|
+
style: {
|
|
1088
|
+
background: headerBg,
|
|
1089
|
+
borderBottom: `1px solid ${headerBorder}`,
|
|
1090
|
+
padding: "6px 14px",
|
|
1091
|
+
display: "flex",
|
|
1092
|
+
alignItems: "center",
|
|
1093
|
+
gap: 6
|
|
1094
|
+
},
|
|
1095
|
+
children: [
|
|
1096
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1097
|
+
"span",
|
|
1098
|
+
{
|
|
1099
|
+
style: {
|
|
1100
|
+
width: 8,
|
|
1101
|
+
height: 8,
|
|
1102
|
+
borderRadius: "50%",
|
|
1103
|
+
background: isDark ? "#388bfd" : "#0550ae",
|
|
1104
|
+
display: "inline-block"
|
|
1105
|
+
}
|
|
1106
|
+
}
|
|
1107
|
+
),
|
|
1108
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { style: { fontSize: 11, color: headerText, fontFamily: "monospace" }, children: "HTML" })
|
|
1109
|
+
]
|
|
1110
|
+
}
|
|
1111
|
+
),
|
|
1112
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1113
|
+
_ui.Box,
|
|
1114
|
+
{
|
|
1115
|
+
as: "pre",
|
|
1116
|
+
padding: 3,
|
|
1117
|
+
style: {
|
|
1118
|
+
margin: 0,
|
|
1119
|
+
maxHeight: 420,
|
|
1120
|
+
overflow: "auto",
|
|
1121
|
+
fontSize: 12,
|
|
1122
|
+
fontFamily: 'ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace',
|
|
1123
|
+
lineHeight: 1.7,
|
|
1124
|
+
whiteSpace: "pre-wrap",
|
|
1125
|
+
wordBreak: "break-word",
|
|
1126
|
+
backgroundColor: codeBg
|
|
1127
|
+
},
|
|
1128
|
+
children: tokens.map((token, idx) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { style: { color: token.color }, children: token.text }, idx))
|
|
1129
|
+
}
|
|
1130
|
+
)
|
|
1131
|
+
]
|
|
1132
|
+
}
|
|
1133
|
+
)
|
|
1134
|
+
] }) });
|
|
1135
|
+
};
|
|
1136
|
+
var MetaTagsPreview_default = MetaTagsPreview;
|
|
1137
|
+
|
|
1138
|
+
// src/components/meta/MetaTitle.tsx
|
|
1139
|
+
|
|
1140
|
+
|
|
1141
|
+
|
|
1142
|
+
|
|
62
1143
|
var MetaTitle = (props) => {
|
|
63
|
-
var _a, _b;
|
|
64
|
-
const { value, renderDefault, path, schemaType } = props;
|
|
1144
|
+
var _a, _b, _c;
|
|
1145
|
+
const { value, renderDefault, path, schemaType, onChange } = props;
|
|
65
1146
|
const { options } = schemaType;
|
|
66
|
-
const parent =
|
|
1147
|
+
const parent = _sanity.useFormValue.call(void 0, [path[0]]);
|
|
67
1148
|
const isParentseoField = parent && (parent == null ? void 0 : parent._type) === "seoFields";
|
|
68
|
-
const keywords =
|
|
69
|
-
const rootDoc = (_a =
|
|
70
|
-
const client =
|
|
71
|
-
const [groqTitleSuffix, setGroqTitleSuffix] =
|
|
1149
|
+
const keywords = _react.useMemo.call(void 0, () => (parent == null ? void 0 : parent.keywords) || [], [parent == null ? void 0 : parent.keywords]);
|
|
1150
|
+
const rootDoc = (_a = _sanity.useFormValue.call(void 0, [])) != null ? _a : {};
|
|
1151
|
+
const client = _sanity.useClient.call(void 0, { apiVersion: (_b = options == null ? void 0 : options.apiVersion) != null ? _b : "2024-01-01" });
|
|
1152
|
+
const [groqTitleSuffix, setGroqTitleSuffix] = _react.useState.call(void 0, "");
|
|
1153
|
+
const [isDuplicateTitle, setIsDuplicateTitle] = _react.useState.call(void 0, false);
|
|
72
1154
|
const titleSuffixQuery = options == null ? void 0 : options.titleSuffixQuery;
|
|
73
1155
|
const titleSuffixOption = options == null ? void 0 : options.titleSuffix;
|
|
74
|
-
|
|
1156
|
+
_react.useEffect.call(void 0, () => {
|
|
75
1157
|
if (!titleSuffixQuery) return;
|
|
76
1158
|
client.fetch(titleSuffixQuery).then((result) => {
|
|
77
1159
|
setGroqTitleSuffix(result === null || result === void 0 ? "" : String(result));
|
|
@@ -79,7 +1161,22 @@ var MetaTitle = (props) => {
|
|
|
79
1161
|
setGroqTitleSuffix("");
|
|
80
1162
|
});
|
|
81
1163
|
}, [titleSuffixQuery, client]);
|
|
82
|
-
const
|
|
1164
|
+
const currentDocId = (_c = rootDoc._id) != null ? _c : "";
|
|
1165
|
+
_react.useEffect.call(void 0, () => {
|
|
1166
|
+
if (!(value == null ? void 0 : value.trim()) || !currentDocId) {
|
|
1167
|
+
setIsDuplicateTitle(false);
|
|
1168
|
+
return () => {
|
|
1169
|
+
};
|
|
1170
|
+
}
|
|
1171
|
+
const timer = setTimeout(() => {
|
|
1172
|
+
client.fetch(
|
|
1173
|
+
`count(*[seo.title == $title && _id != $id && !(_id in path("drafts.**"))])`,
|
|
1174
|
+
{ title: value, id: currentDocId }
|
|
1175
|
+
).then((count) => setIsDuplicateTitle(count > 0)).catch(() => setIsDuplicateTitle(false));
|
|
1176
|
+
}, 600);
|
|
1177
|
+
return () => clearTimeout(timer);
|
|
1178
|
+
}, [value, client, currentDocId]);
|
|
1179
|
+
const resolvedSuffix = _react.useMemo.call(void 0, () => {
|
|
83
1180
|
if (titleSuffixQuery) return groqTitleSuffix;
|
|
84
1181
|
if (!titleSuffixOption) return "";
|
|
85
1182
|
if (typeof titleSuffixOption === "function") {
|
|
@@ -88,31 +1185,60 @@ var MetaTitle = (props) => {
|
|
|
88
1185
|
return titleSuffixOption;
|
|
89
1186
|
}, [titleSuffixQuery, groqTitleSuffix, titleSuffixOption, rootDoc]);
|
|
90
1187
|
const suffixLength = resolvedSuffix ? resolvedSuffix.length + 3 : 0;
|
|
91
|
-
const feedbackItems =
|
|
92
|
-
() =>
|
|
1188
|
+
const feedbackItems = _react.useMemo.call(void 0,
|
|
1189
|
+
() => _chunkY46ACXM4cjs.getMetaTitleValidationMessages.call(void 0, value || "", keywords, isParentseoField, suffixLength),
|
|
93
1190
|
[value, keywords, isParentseoField, suffixLength]
|
|
94
1191
|
);
|
|
95
|
-
return /* @__PURE__ */
|
|
1192
|
+
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _ui.Stack, { space: 3, children: [
|
|
96
1193
|
renderDefault(props),
|
|
97
|
-
/* @__PURE__ */
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
1194
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1195
|
+
SeoGenButton,
|
|
1196
|
+
{
|
|
1197
|
+
field: "title",
|
|
1198
|
+
ai: options == null ? void 0 : options.ai,
|
|
1199
|
+
seoFieldPath: String(path[0]),
|
|
1200
|
+
onGenerate: (v) => onChange(_sanity.PatchEvent.from(_sanity.set.call(void 0, v)))
|
|
1201
|
+
}
|
|
1202
|
+
),
|
|
1203
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _ui.Stack, { space: 2, children: [
|
|
1204
|
+
feedbackItems.map((item) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { style: { display: "flex", alignItems: "center", gap: 7 }, children: [
|
|
1205
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1206
|
+
"div",
|
|
1207
|
+
{
|
|
1208
|
+
style: {
|
|
1209
|
+
minWidth: 10,
|
|
1210
|
+
height: 10,
|
|
1211
|
+
borderRadius: "50%",
|
|
1212
|
+
backgroundColor: item.color
|
|
1213
|
+
}
|
|
106
1214
|
}
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
1215
|
+
),
|
|
1216
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _ui.Text, { weight: "bold", muted: true, size: 14, children: item.text })
|
|
1217
|
+
] }, item.text)),
|
|
1218
|
+
isDuplicateTitle && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { style: { display: "flex", alignItems: "center", gap: 7 }, children: [
|
|
1219
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1220
|
+
"div",
|
|
1221
|
+
{
|
|
1222
|
+
style: {
|
|
1223
|
+
minWidth: 10,
|
|
1224
|
+
height: 10,
|
|
1225
|
+
borderRadius: "50%",
|
|
1226
|
+
backgroundColor: "orange"
|
|
1227
|
+
}
|
|
1228
|
+
}
|
|
1229
|
+
),
|
|
1230
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _ui.Text, { weight: "bold", muted: true, size: 14, children: "Duplicate meta title \u2014 another published document uses this exact title." })
|
|
1231
|
+
] })
|
|
1232
|
+
] })
|
|
111
1233
|
] });
|
|
112
1234
|
};
|
|
113
1235
|
var MetaTitle_default = MetaTitle;
|
|
114
1236
|
|
|
115
1237
|
// src/utils/fieldsUtils.ts
|
|
1238
|
+
function withLicense(ai, licenseKey) {
|
|
1239
|
+
if (!ai) return void 0;
|
|
1240
|
+
return licenseKey ? _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {}, ai), { _licenseKey: licenseKey }) : ai;
|
|
1241
|
+
}
|
|
116
1242
|
var DEFAULT_FIELD_INFO = {
|
|
117
1243
|
title: {
|
|
118
1244
|
title: "Meta Title",
|
|
@@ -136,7 +1262,7 @@ var DEFAULT_FIELD_INFO = {
|
|
|
136
1262
|
},
|
|
137
1263
|
robots: {
|
|
138
1264
|
title: "Robots Settings",
|
|
139
|
-
description: "Configure how search engine crawlers should index
|
|
1265
|
+
description: "Configure how search engine crawlers should index, follow links, translate content, and index images on this page."
|
|
140
1266
|
},
|
|
141
1267
|
metaAttributes: {
|
|
142
1268
|
title: "Additional Meta Attributes",
|
|
@@ -205,6 +1331,22 @@ var DEFAULT_FIELD_INFO = {
|
|
|
205
1331
|
twitterImageUrl: {
|
|
206
1332
|
title: "X Image URL",
|
|
207
1333
|
description: "Enter the full URL of the image for X (formerly Twitter). Ensure the image is accessible and meets the recommended size."
|
|
1334
|
+
},
|
|
1335
|
+
focusKeyword: {
|
|
1336
|
+
title: "Focus Keyword",
|
|
1337
|
+
description: "The primary keyword you want this page to rank for. Used to check keyword placement in title, description, and URL."
|
|
1338
|
+
},
|
|
1339
|
+
hreflangs: {
|
|
1340
|
+
title: "Hreflang Entries",
|
|
1341
|
+
description: "Add alternate language/region versions of this page. Include x-default for the fallback URL."
|
|
1342
|
+
},
|
|
1343
|
+
geoChecklist: {
|
|
1344
|
+
title: "AI Overview Readiness",
|
|
1345
|
+
description: "Checklist of signals that improve visibility in AI-generated overviews."
|
|
1346
|
+
},
|
|
1347
|
+
metaTagsPreview: {
|
|
1348
|
+
title: "Meta Tags Preview",
|
|
1349
|
+
description: "Preview the full HTML <head> meta tags generated for this page."
|
|
208
1350
|
}
|
|
209
1351
|
};
|
|
210
1352
|
var getFieldInfo = (fieldName, fieldOverrides) => {
|
|
@@ -234,19 +1376,38 @@ var getFieldHiddenFunction = (fieldName, config) => {
|
|
|
234
1376
|
var isEmpty = (value) => {
|
|
235
1377
|
return value === null || value === void 0 || typeof value === "string" && value.trim() === "" || Array.isArray(value) && value.length === 0 || typeof value === "object" && !Array.isArray(value) && Object.keys(value).length === 0;
|
|
236
1378
|
};
|
|
1379
|
+
|
|
1380
|
+
// src/schemas/types/openGraph/index.ts
|
|
1381
|
+
|
|
1382
|
+
|
|
1383
|
+
// src/components/openGraph/OgDescription.tsx
|
|
1384
|
+
|
|
1385
|
+
|
|
1386
|
+
|
|
1387
|
+
|
|
237
1388
|
var OgDescription = (props) => {
|
|
238
|
-
const { value, renderDefault, path } = props;
|
|
239
|
-
const
|
|
1389
|
+
const { value, renderDefault, path, schemaType, onChange } = props;
|
|
1390
|
+
const { options } = schemaType;
|
|
1391
|
+
const parent = _sanity.useFormValue.call(void 0, [path[0]]);
|
|
240
1392
|
const isParentseoField = parent && (parent == null ? void 0 : parent._type) === "seoFields";
|
|
241
|
-
const keywords =
|
|
242
|
-
const feedbackItems =
|
|
243
|
-
() =>
|
|
1393
|
+
const keywords = _react.useMemo.call(void 0, () => (parent == null ? void 0 : parent.keywords) || [], [parent == null ? void 0 : parent.keywords]);
|
|
1394
|
+
const feedbackItems = _react.useMemo.call(void 0,
|
|
1395
|
+
() => _chunkY46ACXM4cjs.getOgDescriptionValidation.call(void 0, value || "", keywords, isParentseoField),
|
|
244
1396
|
[value, keywords, isParentseoField]
|
|
245
1397
|
);
|
|
246
|
-
return /* @__PURE__ */
|
|
1398
|
+
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _ui.Stack, { space: 3, children: [
|
|
247
1399
|
renderDefault(props),
|
|
248
|
-
/* @__PURE__ */
|
|
249
|
-
|
|
1400
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1401
|
+
SeoGenButton,
|
|
1402
|
+
{
|
|
1403
|
+
field: "ogDescription",
|
|
1404
|
+
ai: options == null ? void 0 : options.ai,
|
|
1405
|
+
seoFieldPath: String(path[0]),
|
|
1406
|
+
onGenerate: (v) => onChange(_sanity.PatchEvent.from(_sanity.set.call(void 0, v)))
|
|
1407
|
+
}
|
|
1408
|
+
),
|
|
1409
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _ui.Stack, { space: 2, children: feedbackItems.map((item) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { style: { display: "flex", alignItems: "center", gap: 7 }, children: [
|
|
1410
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
250
1411
|
"div",
|
|
251
1412
|
{
|
|
252
1413
|
style: {
|
|
@@ -257,25 +1418,31 @@ var OgDescription = (props) => {
|
|
|
257
1418
|
}
|
|
258
1419
|
}
|
|
259
1420
|
),
|
|
260
|
-
/* @__PURE__ */
|
|
1421
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _ui.Text, { weight: "bold", muted: true, size: 14, children: item.text })
|
|
261
1422
|
] }, item.text)) })
|
|
262
1423
|
] });
|
|
263
1424
|
};
|
|
264
1425
|
var OgDescription_default = OgDescription;
|
|
1426
|
+
|
|
1427
|
+
// src/components/openGraph/OgImage.tsx
|
|
1428
|
+
|
|
1429
|
+
|
|
1430
|
+
|
|
1431
|
+
|
|
265
1432
|
var OgImage = (props) => {
|
|
266
1433
|
const { value, renderDefault, path } = props;
|
|
267
|
-
const seoParent =
|
|
1434
|
+
const seoParent = _sanity.useFormValue.call(void 0, [path[0]]);
|
|
268
1435
|
const imgValue = value;
|
|
269
1436
|
const hasImage = !!(imgValue == null ? void 0 : imgValue.asset);
|
|
270
1437
|
const altText = imgValue == null ? void 0 : imgValue.alt;
|
|
271
|
-
const feedbackItems =
|
|
272
|
-
() =>
|
|
1438
|
+
const feedbackItems = _react.useMemo.call(void 0,
|
|
1439
|
+
() => _chunkY46ACXM4cjs.getOgImageValidation.call(void 0, hasImage, altText, seoParent),
|
|
273
1440
|
[hasImage, altText, seoParent]
|
|
274
1441
|
);
|
|
275
|
-
return /* @__PURE__ */
|
|
1442
|
+
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _ui.Stack, { space: 3, children: [
|
|
276
1443
|
renderDefault(props),
|
|
277
|
-
/* @__PURE__ */
|
|
278
|
-
/* @__PURE__ */
|
|
1444
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _ui.Stack, { space: 2, children: feedbackItems.map((item) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { style: { display: "flex", alignItems: "center", gap: 7 }, children: [
|
|
1445
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
279
1446
|
"div",
|
|
280
1447
|
{
|
|
281
1448
|
style: {
|
|
@@ -286,19 +1453,25 @@ var OgImage = (props) => {
|
|
|
286
1453
|
}
|
|
287
1454
|
}
|
|
288
1455
|
),
|
|
289
|
-
/* @__PURE__ */
|
|
1456
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _ui.Text, { weight: "bold", muted: true, size: 14, children: item.text })
|
|
290
1457
|
] }, item.text)) })
|
|
291
1458
|
] });
|
|
292
1459
|
};
|
|
293
1460
|
var OgImage_default = OgImage;
|
|
1461
|
+
|
|
1462
|
+
// src/components/openGraph/OgImageUrl.tsx
|
|
1463
|
+
|
|
1464
|
+
|
|
1465
|
+
|
|
1466
|
+
|
|
294
1467
|
var OgImageUrl = (props) => {
|
|
295
1468
|
const { value, renderDefault, path } = props;
|
|
296
|
-
const seoParent =
|
|
297
|
-
const feedbackItems =
|
|
298
|
-
return /* @__PURE__ */
|
|
1469
|
+
const seoParent = _sanity.useFormValue.call(void 0, [path[0]]);
|
|
1470
|
+
const feedbackItems = _react.useMemo.call(void 0, () => _chunkY46ACXM4cjs.getOgImageUrlValidation.call(void 0, value, seoParent), [value, seoParent]);
|
|
1471
|
+
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _ui.Stack, { space: 3, children: [
|
|
299
1472
|
renderDefault(props),
|
|
300
|
-
/* @__PURE__ */
|
|
301
|
-
/* @__PURE__ */
|
|
1473
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _ui.Stack, { space: 2, children: feedbackItems.map((item) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { style: { display: "flex", alignItems: "center", gap: 7 }, children: [
|
|
1474
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
302
1475
|
"div",
|
|
303
1476
|
{
|
|
304
1477
|
style: {
|
|
@@ -309,24 +1482,40 @@ var OgImageUrl = (props) => {
|
|
|
309
1482
|
}
|
|
310
1483
|
}
|
|
311
1484
|
),
|
|
312
|
-
/* @__PURE__ */
|
|
1485
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _ui.Text, { weight: "bold", muted: true, size: 14, children: item.text })
|
|
313
1486
|
] }, item.text)) })
|
|
314
1487
|
] });
|
|
315
1488
|
};
|
|
316
1489
|
var OgImageUrl_default = OgImageUrl;
|
|
1490
|
+
|
|
1491
|
+
// src/components/openGraph/OgTitle.tsx
|
|
1492
|
+
|
|
1493
|
+
|
|
1494
|
+
|
|
1495
|
+
|
|
317
1496
|
var OgTitle = (props) => {
|
|
318
|
-
const { value, renderDefault, path } = props;
|
|
319
|
-
const
|
|
1497
|
+
const { value, renderDefault, path, schemaType, onChange } = props;
|
|
1498
|
+
const { options } = schemaType;
|
|
1499
|
+
const parent = _sanity.useFormValue.call(void 0, [path[0]]);
|
|
320
1500
|
const isParentseoField = parent && (parent == null ? void 0 : parent._type) === "seoFields";
|
|
321
|
-
const keywords =
|
|
322
|
-
const feedbackItems =
|
|
323
|
-
() =>
|
|
1501
|
+
const keywords = _react.useMemo.call(void 0, () => (parent == null ? void 0 : parent.keywords) || [], [parent == null ? void 0 : parent.keywords]);
|
|
1502
|
+
const feedbackItems = _react.useMemo.call(void 0,
|
|
1503
|
+
() => _chunkY46ACXM4cjs.getOgTitleValidation.call(void 0, value || "", keywords, isParentseoField),
|
|
324
1504
|
[value, keywords, isParentseoField]
|
|
325
1505
|
);
|
|
326
|
-
return /* @__PURE__ */
|
|
1506
|
+
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _ui.Stack, { space: 3, children: [
|
|
327
1507
|
renderDefault(props),
|
|
328
|
-
/* @__PURE__ */
|
|
329
|
-
|
|
1508
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1509
|
+
SeoGenButton,
|
|
1510
|
+
{
|
|
1511
|
+
field: "ogTitle",
|
|
1512
|
+
ai: options == null ? void 0 : options.ai,
|
|
1513
|
+
seoFieldPath: String(path[0]),
|
|
1514
|
+
onGenerate: (v) => onChange(_sanity.PatchEvent.from(_sanity.set.call(void 0, v)))
|
|
1515
|
+
}
|
|
1516
|
+
),
|
|
1517
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _ui.Stack, { space: 2, children: feedbackItems.map((item) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { style: { display: "flex", alignItems: "center", gap: 7 }, children: [
|
|
1518
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
330
1519
|
"div",
|
|
331
1520
|
{
|
|
332
1521
|
style: {
|
|
@@ -337,7 +1526,7 @@ var OgTitle = (props) => {
|
|
|
337
1526
|
}
|
|
338
1527
|
}
|
|
339
1528
|
),
|
|
340
|
-
/* @__PURE__ */
|
|
1529
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _ui.Text, { weight: "bold", muted: true, size: 14, children: item.text })
|
|
341
1530
|
] }, item.text)) })
|
|
342
1531
|
] });
|
|
343
1532
|
};
|
|
@@ -345,29 +1534,29 @@ var OgTitle_default = OgTitle;
|
|
|
345
1534
|
|
|
346
1535
|
// src/schemas/types/openGraph/index.ts
|
|
347
1536
|
function openGraph(config = {}) {
|
|
348
|
-
return
|
|
1537
|
+
return _sanity.defineType.call(void 0, {
|
|
349
1538
|
name: "openGraph",
|
|
350
1539
|
title: "Open Graph Settings",
|
|
351
1540
|
type: "object",
|
|
352
1541
|
fields: [
|
|
353
|
-
|
|
1542
|
+
_sanity.defineField.call(void 0, _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {
|
|
354
1543
|
name: "url",
|
|
355
1544
|
type: "url"
|
|
356
1545
|
}, getFieldInfo("openGraphUrl", config.fieldOverrides)), {
|
|
357
1546
|
hidden: getFieldHiddenFunction("openGraphUrl", config),
|
|
358
1547
|
description: "The canonical URL of the page. This should be the full URL including protocol (https://)."
|
|
359
1548
|
})),
|
|
360
|
-
|
|
1549
|
+
_sanity.defineField.call(void 0, _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {
|
|
361
1550
|
name: "title"
|
|
362
1551
|
}, getFieldInfo("openGraphTitle", config.fieldOverrides)), {
|
|
363
1552
|
type: "string",
|
|
364
1553
|
hidden: getFieldHiddenFunction("openGraphTitle", config),
|
|
365
1554
|
components: {
|
|
366
1555
|
input: OgTitle_default
|
|
367
|
-
|
|
368
|
-
}
|
|
1556
|
+
},
|
|
1557
|
+
options: _chunkA57XNQC7cjs.__spreadValues.call(void 0, {}, config.ai ? { ai: withLicense(config.ai, config.licenseKey) } : {})
|
|
369
1558
|
})),
|
|
370
|
-
|
|
1559
|
+
_sanity.defineField.call(void 0, _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {
|
|
371
1560
|
name: "description"
|
|
372
1561
|
}, getFieldInfo("openGraphDescription", config.fieldOverrides)), {
|
|
373
1562
|
type: "text",
|
|
@@ -375,16 +1564,16 @@ function openGraph(config = {}) {
|
|
|
375
1564
|
hidden: getFieldHiddenFunction("openGraphDescription", config),
|
|
376
1565
|
components: {
|
|
377
1566
|
input: OgDescription_default
|
|
378
|
-
|
|
379
|
-
}
|
|
1567
|
+
},
|
|
1568
|
+
options: _chunkA57XNQC7cjs.__spreadValues.call(void 0, {}, config.ai ? { ai: withLicense(config.ai, config.licenseKey) } : {})
|
|
380
1569
|
})),
|
|
381
|
-
|
|
1570
|
+
_sanity.defineField.call(void 0, _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {
|
|
382
1571
|
name: "siteName"
|
|
383
1572
|
}, getFieldInfo("openGraphSiteName", config.fieldOverrides)), {
|
|
384
1573
|
type: "string",
|
|
385
1574
|
hidden: getFieldHiddenFunction("openGraphSiteName", config)
|
|
386
1575
|
})),
|
|
387
|
-
|
|
1576
|
+
_sanity.defineField.call(void 0, _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {
|
|
388
1577
|
name: "type"
|
|
389
1578
|
}, getFieldInfo("openGraphType", config.fieldOverrides)), {
|
|
390
1579
|
type: "string",
|
|
@@ -403,7 +1592,7 @@ function openGraph(config = {}) {
|
|
|
403
1592
|
hidden: getFieldHiddenFunction("openGraphType", config),
|
|
404
1593
|
initialValue: "website"
|
|
405
1594
|
})),
|
|
406
|
-
|
|
1595
|
+
_sanity.defineField.call(void 0, _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {
|
|
407
1596
|
name: "imageType"
|
|
408
1597
|
}, getFieldInfo("openGraphImageType", config.fieldOverrides)), {
|
|
409
1598
|
type: "string",
|
|
@@ -416,7 +1605,7 @@ function openGraph(config = {}) {
|
|
|
416
1605
|
hidden: getFieldHiddenFunction("openGraphImage", config),
|
|
417
1606
|
initialValue: "upload"
|
|
418
1607
|
})),
|
|
419
|
-
|
|
1608
|
+
_sanity.defineField.call(void 0, _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {
|
|
420
1609
|
name: "image"
|
|
421
1610
|
}, getFieldInfo("openGraphImage", config.fieldOverrides)), {
|
|
422
1611
|
type: "image",
|
|
@@ -427,7 +1616,7 @@ function openGraph(config = {}) {
|
|
|
427
1616
|
input: OgImage_default
|
|
428
1617
|
},
|
|
429
1618
|
fields: [
|
|
430
|
-
|
|
1619
|
+
_sanity.defineField.call(void 0, {
|
|
431
1620
|
name: "alt",
|
|
432
1621
|
title: "Image Alt Text",
|
|
433
1622
|
type: "string",
|
|
@@ -441,7 +1630,7 @@ function openGraph(config = {}) {
|
|
|
441
1630
|
return typeof hiddenFn === "function" ? hiddenFn(context) : hiddenFn;
|
|
442
1631
|
}
|
|
443
1632
|
})),
|
|
444
|
-
|
|
1633
|
+
_sanity.defineField.call(void 0, _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {
|
|
445
1634
|
name: "imageUrl"
|
|
446
1635
|
}, getFieldInfo("openGraphImageUrl", config.fieldOverrides)), {
|
|
447
1636
|
type: "url",
|
|
@@ -458,19 +1647,38 @@ function openGraph(config = {}) {
|
|
|
458
1647
|
]
|
|
459
1648
|
});
|
|
460
1649
|
}
|
|
1650
|
+
|
|
1651
|
+
// src/schemas/types/twitter/index.ts
|
|
1652
|
+
|
|
1653
|
+
|
|
1654
|
+
// src/components/twitter/twitterDescription.tsx
|
|
1655
|
+
|
|
1656
|
+
|
|
1657
|
+
|
|
1658
|
+
|
|
461
1659
|
var TwitterDescription = (props) => {
|
|
462
|
-
const { value, renderDefault, path } = props;
|
|
463
|
-
const
|
|
1660
|
+
const { value, renderDefault, path, schemaType, onChange } = props;
|
|
1661
|
+
const { options } = schemaType;
|
|
1662
|
+
const parent = _sanity.useFormValue.call(void 0, [path[0]]);
|
|
464
1663
|
const isParentseoField = parent && (parent == null ? void 0 : parent._type) === "seoFields";
|
|
465
|
-
const keywords =
|
|
466
|
-
const feedbackItems =
|
|
467
|
-
() =>
|
|
1664
|
+
const keywords = _react.useMemo.call(void 0, () => (parent == null ? void 0 : parent.keywords) || [], [parent == null ? void 0 : parent.keywords]);
|
|
1665
|
+
const feedbackItems = _react.useMemo.call(void 0,
|
|
1666
|
+
() => _chunkY46ACXM4cjs.getTwitterDescriptionValidation.call(void 0, value || "", keywords, isParentseoField),
|
|
468
1667
|
[value, keywords, isParentseoField]
|
|
469
1668
|
);
|
|
470
|
-
return /* @__PURE__ */
|
|
1669
|
+
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _ui.Stack, { space: 3, children: [
|
|
471
1670
|
renderDefault(props),
|
|
472
|
-
/* @__PURE__ */
|
|
473
|
-
|
|
1671
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1672
|
+
SeoGenButton,
|
|
1673
|
+
{
|
|
1674
|
+
field: "twitterDescription",
|
|
1675
|
+
ai: options == null ? void 0 : options.ai,
|
|
1676
|
+
seoFieldPath: String(path[0]),
|
|
1677
|
+
onGenerate: (v) => onChange(_sanity.PatchEvent.from(_sanity.set.call(void 0, v)))
|
|
1678
|
+
}
|
|
1679
|
+
),
|
|
1680
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _ui.Stack, { space: 2, children: feedbackItems.map((item) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { style: { display: "flex", alignItems: "center", gap: 7 }, children: [
|
|
1681
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
474
1682
|
"div",
|
|
475
1683
|
{
|
|
476
1684
|
style: {
|
|
@@ -481,25 +1689,31 @@ var TwitterDescription = (props) => {
|
|
|
481
1689
|
}
|
|
482
1690
|
}
|
|
483
1691
|
),
|
|
484
|
-
/* @__PURE__ */
|
|
1692
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _ui.Text, { weight: "bold", muted: true, size: 14, children: item.text })
|
|
485
1693
|
] }, item.text)) })
|
|
486
1694
|
] });
|
|
487
1695
|
};
|
|
488
1696
|
var twitterDescription_default = TwitterDescription;
|
|
1697
|
+
|
|
1698
|
+
// src/components/twitter/TwitterImage.tsx
|
|
1699
|
+
|
|
1700
|
+
|
|
1701
|
+
|
|
1702
|
+
|
|
489
1703
|
var TwitterImage = (props) => {
|
|
490
1704
|
const { value, renderDefault, path } = props;
|
|
491
|
-
const seoParent =
|
|
1705
|
+
const seoParent = _sanity.useFormValue.call(void 0, [path[0]]);
|
|
492
1706
|
const imgValue = value;
|
|
493
1707
|
const hasImage = !!(imgValue == null ? void 0 : imgValue.asset);
|
|
494
1708
|
const altText = imgValue == null ? void 0 : imgValue.alt;
|
|
495
|
-
const feedbackItems =
|
|
496
|
-
() =>
|
|
1709
|
+
const feedbackItems = _react.useMemo.call(void 0,
|
|
1710
|
+
() => _chunkY46ACXM4cjs.getTwitterImageValidation.call(void 0, hasImage, altText, seoParent),
|
|
497
1711
|
[hasImage, altText, seoParent]
|
|
498
1712
|
);
|
|
499
|
-
return /* @__PURE__ */
|
|
1713
|
+
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _ui.Stack, { space: 3, children: [
|
|
500
1714
|
renderDefault(props),
|
|
501
|
-
/* @__PURE__ */
|
|
502
|
-
/* @__PURE__ */
|
|
1715
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _ui.Stack, { space: 2, children: feedbackItems.map((item) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { style: { display: "flex", alignItems: "center", gap: 7 }, children: [
|
|
1716
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
503
1717
|
"div",
|
|
504
1718
|
{
|
|
505
1719
|
style: {
|
|
@@ -510,22 +1724,28 @@ var TwitterImage = (props) => {
|
|
|
510
1724
|
}
|
|
511
1725
|
}
|
|
512
1726
|
),
|
|
513
|
-
/* @__PURE__ */
|
|
1727
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _ui.Text, { weight: "bold", muted: true, size: 14, children: item.text })
|
|
514
1728
|
] }, item.text)) })
|
|
515
1729
|
] });
|
|
516
1730
|
};
|
|
517
1731
|
var TwitterImage_default = TwitterImage;
|
|
1732
|
+
|
|
1733
|
+
// src/components/twitter/TwitterImageUrl.tsx
|
|
1734
|
+
|
|
1735
|
+
|
|
1736
|
+
|
|
1737
|
+
|
|
518
1738
|
var TwitterImageUrl = (props) => {
|
|
519
1739
|
const { value, renderDefault, path } = props;
|
|
520
|
-
const seoParent =
|
|
521
|
-
const feedbackItems =
|
|
522
|
-
() =>
|
|
1740
|
+
const seoParent = _sanity.useFormValue.call(void 0, [path[0]]);
|
|
1741
|
+
const feedbackItems = _react.useMemo.call(void 0,
|
|
1742
|
+
() => _chunkY46ACXM4cjs.getTwitterImageUrlValidation.call(void 0, value, seoParent),
|
|
523
1743
|
[value, seoParent]
|
|
524
1744
|
);
|
|
525
|
-
return /* @__PURE__ */
|
|
1745
|
+
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _ui.Stack, { space: 3, children: [
|
|
526
1746
|
renderDefault(props),
|
|
527
|
-
/* @__PURE__ */
|
|
528
|
-
/* @__PURE__ */
|
|
1747
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _ui.Stack, { space: 2, children: feedbackItems.map((item) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { style: { display: "flex", alignItems: "center", gap: 7 }, children: [
|
|
1748
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
529
1749
|
"div",
|
|
530
1750
|
{
|
|
531
1751
|
style: {
|
|
@@ -536,24 +1756,40 @@ var TwitterImageUrl = (props) => {
|
|
|
536
1756
|
}
|
|
537
1757
|
}
|
|
538
1758
|
),
|
|
539
|
-
/* @__PURE__ */
|
|
1759
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _ui.Text, { weight: "bold", muted: true, size: 14, children: item.text })
|
|
540
1760
|
] }, item.text)) })
|
|
541
1761
|
] });
|
|
542
1762
|
};
|
|
543
1763
|
var TwitterImageUrl_default = TwitterImageUrl;
|
|
1764
|
+
|
|
1765
|
+
// src/components/twitter/twitterTitle.tsx
|
|
1766
|
+
|
|
1767
|
+
|
|
1768
|
+
|
|
1769
|
+
|
|
544
1770
|
var TwitterTitle = (props) => {
|
|
545
|
-
const { value, renderDefault, path } = props;
|
|
546
|
-
const
|
|
1771
|
+
const { value, renderDefault, path, schemaType, onChange } = props;
|
|
1772
|
+
const { options } = schemaType;
|
|
1773
|
+
const parent = _sanity.useFormValue.call(void 0, [path[0]]);
|
|
547
1774
|
const isParentseoField = parent && (parent == null ? void 0 : parent._type) === "seoFields";
|
|
548
|
-
const keywords =
|
|
549
|
-
const feedbackItems =
|
|
550
|
-
() =>
|
|
1775
|
+
const keywords = _react.useMemo.call(void 0, () => (parent == null ? void 0 : parent.keywords) || [], [parent == null ? void 0 : parent.keywords]);
|
|
1776
|
+
const feedbackItems = _react.useMemo.call(void 0,
|
|
1777
|
+
() => _chunkY46ACXM4cjs.getTwitterTitleValidation.call(void 0, value || "", keywords, isParentseoField),
|
|
551
1778
|
[value, keywords, isParentseoField]
|
|
552
1779
|
);
|
|
553
|
-
return /* @__PURE__ */
|
|
1780
|
+
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _ui.Stack, { space: 3, children: [
|
|
554
1781
|
renderDefault(props),
|
|
555
|
-
/* @__PURE__ */
|
|
556
|
-
|
|
1782
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1783
|
+
SeoGenButton,
|
|
1784
|
+
{
|
|
1785
|
+
field: "twitterTitle",
|
|
1786
|
+
ai: options == null ? void 0 : options.ai,
|
|
1787
|
+
seoFieldPath: String(path[0]),
|
|
1788
|
+
onGenerate: (v) => onChange(_sanity.PatchEvent.from(_sanity.set.call(void 0, v)))
|
|
1789
|
+
}
|
|
1790
|
+
),
|
|
1791
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _ui.Stack, { space: 2, children: feedbackItems.map((item) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { style: { display: "flex", alignItems: "center", gap: 7 }, children: [
|
|
1792
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
557
1793
|
"div",
|
|
558
1794
|
{
|
|
559
1795
|
style: {
|
|
@@ -564,7 +1800,7 @@ var TwitterTitle = (props) => {
|
|
|
564
1800
|
}
|
|
565
1801
|
}
|
|
566
1802
|
),
|
|
567
|
-
/* @__PURE__ */
|
|
1803
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _ui.Text, { weight: "bold", muted: true, size: 14, children: item.text })
|
|
568
1804
|
] }, item.text)) })
|
|
569
1805
|
] });
|
|
570
1806
|
};
|
|
@@ -572,12 +1808,12 @@ var twitterTitle_default = TwitterTitle;
|
|
|
572
1808
|
|
|
573
1809
|
// src/schemas/types/twitter/index.ts
|
|
574
1810
|
function twitter(config = {}) {
|
|
575
|
-
return
|
|
1811
|
+
return _sanity.defineType.call(void 0, {
|
|
576
1812
|
name: "twitter",
|
|
577
1813
|
title: "X (Formerly Twitter)",
|
|
578
1814
|
type: "object",
|
|
579
1815
|
fields: [
|
|
580
|
-
|
|
1816
|
+
_sanity.defineField.call(void 0, _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {
|
|
581
1817
|
name: "card"
|
|
582
1818
|
}, getFieldInfo("twitterCard", config.fieldOverrides)), {
|
|
583
1819
|
type: "string",
|
|
@@ -593,28 +1829,29 @@ function twitter(config = {}) {
|
|
|
593
1829
|
initialValue: "summary_large_image"
|
|
594
1830
|
// good default
|
|
595
1831
|
})),
|
|
596
|
-
|
|
1832
|
+
_sanity.defineField.call(void 0, _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {
|
|
597
1833
|
name: "site"
|
|
598
1834
|
}, getFieldInfo("twitterSite", config.fieldOverrides)), {
|
|
599
1835
|
type: "string",
|
|
600
1836
|
hidden: getFieldHiddenFunction("twitterSite", config)
|
|
601
1837
|
})),
|
|
602
|
-
|
|
1838
|
+
_sanity.defineField.call(void 0, _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {
|
|
603
1839
|
name: "creator",
|
|
604
1840
|
type: "string"
|
|
605
1841
|
}, getFieldInfo("twitterCreator", config.fieldOverrides)), {
|
|
606
1842
|
hidden: getFieldHiddenFunction("twitterCreator", config)
|
|
607
1843
|
})),
|
|
608
|
-
|
|
1844
|
+
_sanity.defineField.call(void 0, _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {
|
|
609
1845
|
name: "title",
|
|
610
1846
|
type: "string"
|
|
611
1847
|
}, getFieldInfo("twitterTitle", config.fieldOverrides)), {
|
|
612
1848
|
hidden: getFieldHiddenFunction("twitterTitle", config),
|
|
613
1849
|
components: {
|
|
614
1850
|
input: twitterTitle_default
|
|
615
|
-
}
|
|
1851
|
+
},
|
|
1852
|
+
options: _chunkA57XNQC7cjs.__spreadValues.call(void 0, {}, config.ai ? { ai: withLicense(config.ai, config.licenseKey) } : {})
|
|
616
1853
|
})),
|
|
617
|
-
|
|
1854
|
+
_sanity.defineField.call(void 0, _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {
|
|
618
1855
|
name: "description",
|
|
619
1856
|
type: "text",
|
|
620
1857
|
rows: 3
|
|
@@ -622,9 +1859,10 @@ function twitter(config = {}) {
|
|
|
622
1859
|
hidden: getFieldHiddenFunction("twitterDescription", config),
|
|
623
1860
|
components: {
|
|
624
1861
|
input: twitterDescription_default
|
|
625
|
-
}
|
|
1862
|
+
},
|
|
1863
|
+
options: _chunkA57XNQC7cjs.__spreadValues.call(void 0, {}, config.ai ? { ai: withLicense(config.ai, config.licenseKey) } : {})
|
|
626
1864
|
})),
|
|
627
|
-
|
|
1865
|
+
_sanity.defineField.call(void 0, _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {
|
|
628
1866
|
name: "imageType"
|
|
629
1867
|
}, getFieldInfo("twitterImageType", config.fieldOverrides)), {
|
|
630
1868
|
type: "string",
|
|
@@ -637,7 +1875,7 @@ function twitter(config = {}) {
|
|
|
637
1875
|
hidden: getFieldHiddenFunction("twitterImage", config),
|
|
638
1876
|
initialValue: "upload"
|
|
639
1877
|
})),
|
|
640
|
-
|
|
1878
|
+
_sanity.defineField.call(void 0, _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {
|
|
641
1879
|
name: "image"
|
|
642
1880
|
}, getFieldInfo("twitterImage", config.fieldOverrides)), {
|
|
643
1881
|
type: "image",
|
|
@@ -648,7 +1886,7 @@ function twitter(config = {}) {
|
|
|
648
1886
|
input: TwitterImage_default
|
|
649
1887
|
},
|
|
650
1888
|
fields: [
|
|
651
|
-
|
|
1889
|
+
_sanity.defineField.call(void 0, {
|
|
652
1890
|
name: "alt",
|
|
653
1891
|
title: "Image Alt Text",
|
|
654
1892
|
type: "string",
|
|
@@ -662,7 +1900,7 @@ function twitter(config = {}) {
|
|
|
662
1900
|
return typeof hiddenFn === "function" ? hiddenFn(context) : hiddenFn;
|
|
663
1901
|
}
|
|
664
1902
|
})),
|
|
665
|
-
|
|
1903
|
+
_sanity.defineField.call(void 0, _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {
|
|
666
1904
|
name: "imageUrl"
|
|
667
1905
|
}, getFieldInfo("twitterImageUrl", config.fieldOverrides)), {
|
|
668
1906
|
type: "url",
|
|
@@ -681,8 +1919,8 @@ function twitter(config = {}) {
|
|
|
681
1919
|
}
|
|
682
1920
|
|
|
683
1921
|
// src/schemas/index.ts
|
|
684
|
-
var LazySeoPreview =
|
|
685
|
-
var SeoPreviewWrapper = (props) =>
|
|
1922
|
+
var LazySeoPreview = _react.lazy.call(void 0, () => Promise.resolve().then(() => _interopRequireWildcard(require("./SeoPreview-LMZAWWOE.cjs"))));
|
|
1923
|
+
var SeoPreviewWrapper = (props) => _react.createElement.call(void 0, _react.Suspense, { fallback: null }, _react.createElement.call(void 0, LazySeoPreview, props));
|
|
686
1924
|
function buildFieldGroupMap(groups) {
|
|
687
1925
|
const map = /* @__PURE__ */ new Map();
|
|
688
1926
|
for (const g of groups) {
|
|
@@ -714,20 +1952,88 @@ function withGroup(field, fieldGroupMap) {
|
|
|
714
1952
|
if (!fieldGroupMap) return field;
|
|
715
1953
|
const groups = fieldGroupMap.get(field.name);
|
|
716
1954
|
if (!groups || groups.length === 0) return field;
|
|
717
|
-
return
|
|
1955
|
+
return _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {}, field), { group: groups.length === 1 ? groups[0] : groups });
|
|
1956
|
+
}
|
|
1957
|
+
function shouldShowPreviewField(seoPreview) {
|
|
1958
|
+
if (typeof seoPreview === "boolean") return seoPreview;
|
|
1959
|
+
if (typeof seoPreview === "object") return !isEmpty(seoPreview);
|
|
1960
|
+
return false;
|
|
1961
|
+
}
|
|
1962
|
+
function getSeoPreviewSuffixOptions(seoPreview) {
|
|
1963
|
+
if (typeof seoPreview !== "object" || !seoPreview) return {};
|
|
1964
|
+
const extra = {};
|
|
1965
|
+
if (seoPreview.titleSuffix) extra.titleSuffix = seoPreview.titleSuffix;
|
|
1966
|
+
if (seoPreview.titleSuffixQuery) extra.titleSuffixQuery = seoPreview.titleSuffixQuery;
|
|
1967
|
+
return extra;
|
|
1968
|
+
}
|
|
1969
|
+
function getPreviewFieldOptions(config) {
|
|
1970
|
+
const seoPreview = config.seoPreview;
|
|
1971
|
+
const extra = {};
|
|
1972
|
+
if (typeof seoPreview === "object" && seoPreview) {
|
|
1973
|
+
if (seoPreview.prefix) extra.prefix = seoPreview.prefix;
|
|
1974
|
+
if (seoPreview.titleSuffixInheritColor) {
|
|
1975
|
+
extra.titleSuffixInheritColor = seoPreview.titleSuffixInheritColor;
|
|
1976
|
+
}
|
|
1977
|
+
}
|
|
1978
|
+
return _chunkA57XNQC7cjs.__spreadValues.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {
|
|
1979
|
+
baseUrl: config.baseUrl || "https://www.example.com"
|
|
1980
|
+
}, config.apiVersion ? { apiVersion: config.apiVersion } : {}), getSeoPreviewSuffixOptions(seoPreview)), extra);
|
|
1981
|
+
}
|
|
1982
|
+
function getAiOption(config) {
|
|
1983
|
+
return config.ai ? { ai: withLicense(config.ai, config.licenseKey) } : {};
|
|
1984
|
+
}
|
|
1985
|
+
function getTitleFieldOptions(config) {
|
|
1986
|
+
return _chunkA57XNQC7cjs.__spreadValues.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {}, config.apiVersion ? { apiVersion: config.apiVersion } : {}), getSeoPreviewSuffixOptions(config.seoPreview)), getAiOption(config));
|
|
1987
|
+
}
|
|
1988
|
+
function buildGeoChecklistField(config, fieldGroupMap) {
|
|
1989
|
+
if (config.geo === false) return [];
|
|
1990
|
+
return [
|
|
1991
|
+
withGroup(
|
|
1992
|
+
_sanity.defineField.call(void 0, _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {
|
|
1993
|
+
name: "geoChecklist"
|
|
1994
|
+
}, getFieldInfo("geoChecklist", config.fieldOverrides)), {
|
|
1995
|
+
type: "string",
|
|
1996
|
+
readOnly: true,
|
|
1997
|
+
components: {
|
|
1998
|
+
input: GEOChecklist_default
|
|
1999
|
+
},
|
|
2000
|
+
options: _chunkA57XNQC7cjs.__spreadValues.call(void 0, {}, config.licenseKey ? { licenseKey: config.licenseKey } : {}),
|
|
2001
|
+
hidden: getFieldHiddenFunction("geoChecklist", config)
|
|
2002
|
+
})),
|
|
2003
|
+
fieldGroupMap
|
|
2004
|
+
)
|
|
2005
|
+
];
|
|
2006
|
+
}
|
|
2007
|
+
function buildMetaTagsPreviewField(config, fieldGroupMap) {
|
|
2008
|
+
if (config.metaTagsPreview === false) return [];
|
|
2009
|
+
return [
|
|
2010
|
+
withGroup(
|
|
2011
|
+
_sanity.defineField.call(void 0, _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {
|
|
2012
|
+
name: "metaTagsPreview"
|
|
2013
|
+
}, getFieldInfo("metaTagsPreview", config.fieldOverrides)), {
|
|
2014
|
+
type: "string",
|
|
2015
|
+
readOnly: true,
|
|
2016
|
+
components: {
|
|
2017
|
+
input: MetaTagsPreview_default
|
|
2018
|
+
},
|
|
2019
|
+
hidden: getFieldHiddenFunction("metaTagsPreview", config)
|
|
2020
|
+
})),
|
|
2021
|
+
fieldGroupMap
|
|
2022
|
+
)
|
|
2023
|
+
];
|
|
718
2024
|
}
|
|
719
2025
|
function seoFieldsSchema(config = {}) {
|
|
720
2026
|
const groupsCfg = config.fieldGroups;
|
|
721
2027
|
const fieldGroupMap = (groupsCfg == null ? void 0 : groupsCfg.length) ? buildFieldGroupMap(groupsCfg) : void 0;
|
|
722
2028
|
const sanityGroups = (groupsCfg == null ? void 0 : groupsCfg.length) ? toSanityGroups(groupsCfg) : void 0;
|
|
723
|
-
return
|
|
2029
|
+
return _sanity.defineType.call(void 0, _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {
|
|
724
2030
|
name: "seoFields",
|
|
725
2031
|
title: "SEO Fields",
|
|
726
2032
|
type: "object"
|
|
727
2033
|
}, sanityGroups ? { groups: sanityGroups } : {}), {
|
|
728
2034
|
fields: [
|
|
729
2035
|
withGroup(
|
|
730
|
-
|
|
2036
|
+
_sanity.defineField.call(void 0, {
|
|
731
2037
|
name: "robots",
|
|
732
2038
|
title: "Robots Settings",
|
|
733
2039
|
type: "robots",
|
|
@@ -736,16 +2042,14 @@ function seoFieldsSchema(config = {}) {
|
|
|
736
2042
|
fieldGroupMap
|
|
737
2043
|
),
|
|
738
2044
|
// 👇 conditionally spread preview field
|
|
739
|
-
...
|
|
2045
|
+
...shouldShowPreviewField(config.seoPreview) ? [
|
|
740
2046
|
withGroup(
|
|
741
|
-
|
|
2047
|
+
_sanity.defineField.call(void 0, {
|
|
742
2048
|
name: "preview",
|
|
743
2049
|
title: "SEO Preview",
|
|
744
2050
|
type: "string",
|
|
745
2051
|
components: { input: SeoPreviewWrapper },
|
|
746
|
-
options:
|
|
747
|
-
baseUrl: config.baseUrl || "https://www.example.com"
|
|
748
|
-
}, config.apiVersion ? { apiVersion: config.apiVersion } : {}), typeof config.seoPreview === "object" && config.seoPreview && config.seoPreview.prefix ? { prefix: config.seoPreview.prefix } : {}), typeof config.seoPreview === "object" && config.seoPreview && config.seoPreview.titleSuffix ? { titleSuffix: config.seoPreview.titleSuffix } : {}), typeof config.seoPreview === "object" && config.seoPreview && config.seoPreview.titleSuffixInheritColor ? { titleSuffixInheritColor: config.seoPreview.titleSuffixInheritColor } : {}), typeof config.seoPreview === "object" && config.seoPreview && config.seoPreview.titleSuffixQuery ? { titleSuffixQuery: config.seoPreview.titleSuffixQuery } : {}),
|
|
2052
|
+
options: getPreviewFieldOptions(config),
|
|
749
2053
|
initialValue: "",
|
|
750
2054
|
readOnly: true
|
|
751
2055
|
}),
|
|
@@ -753,20 +2057,20 @@ function seoFieldsSchema(config = {}) {
|
|
|
753
2057
|
)
|
|
754
2058
|
] : [],
|
|
755
2059
|
withGroup(
|
|
756
|
-
|
|
2060
|
+
_sanity.defineField.call(void 0, _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {
|
|
757
2061
|
name: "title"
|
|
758
2062
|
}, getFieldInfo("title", config.fieldOverrides)), {
|
|
759
2063
|
type: "string",
|
|
760
2064
|
components: {
|
|
761
2065
|
input: MetaTitle_default
|
|
762
2066
|
},
|
|
763
|
-
options:
|
|
2067
|
+
options: getTitleFieldOptions(config),
|
|
764
2068
|
hidden: getFieldHiddenFunction("title", config)
|
|
765
2069
|
})),
|
|
766
2070
|
fieldGroupMap
|
|
767
2071
|
),
|
|
768
2072
|
withGroup(
|
|
769
|
-
|
|
2073
|
+
_sanity.defineField.call(void 0, _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {
|
|
770
2074
|
name: "description"
|
|
771
2075
|
}, getFieldInfo("description", config.fieldOverrides)), {
|
|
772
2076
|
type: "text",
|
|
@@ -774,12 +2078,13 @@ function seoFieldsSchema(config = {}) {
|
|
|
774
2078
|
components: {
|
|
775
2079
|
input: MetaDescription_default
|
|
776
2080
|
},
|
|
2081
|
+
options: getAiOption(config),
|
|
777
2082
|
hidden: getFieldHiddenFunction("description", config)
|
|
778
2083
|
})),
|
|
779
2084
|
fieldGroupMap
|
|
780
2085
|
),
|
|
781
2086
|
withGroup(
|
|
782
|
-
|
|
2087
|
+
_sanity.defineField.call(void 0, _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {
|
|
783
2088
|
name: "metaImage"
|
|
784
2089
|
}, getFieldInfo("metaImage", config.fieldOverrides)), {
|
|
785
2090
|
type: "image",
|
|
@@ -794,7 +2099,7 @@ function seoFieldsSchema(config = {}) {
|
|
|
794
2099
|
fieldGroupMap
|
|
795
2100
|
),
|
|
796
2101
|
withGroup(
|
|
797
|
-
|
|
2102
|
+
_sanity.defineField.call(void 0, _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {
|
|
798
2103
|
name: "metaAttributes"
|
|
799
2104
|
}, getFieldInfo("metaAttributes", config.fieldOverrides)), {
|
|
800
2105
|
type: "array",
|
|
@@ -804,19 +2109,21 @@ function seoFieldsSchema(config = {}) {
|
|
|
804
2109
|
fieldGroupMap
|
|
805
2110
|
),
|
|
806
2111
|
withGroup(
|
|
807
|
-
|
|
2112
|
+
_sanity.defineField.call(void 0, _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {
|
|
808
2113
|
name: "keywords"
|
|
809
2114
|
}, getFieldInfo("keywords", config.fieldOverrides)), {
|
|
810
2115
|
title: "Keywords",
|
|
811
2116
|
type: "array",
|
|
812
2117
|
of: [{ type: "string" }],
|
|
813
2118
|
description: "Add relevant keywords for this page. These keywords will be used for SEO purposes.",
|
|
2119
|
+
components: config.ai ? { input: KeywordsInput_default } : void 0,
|
|
2120
|
+
options: getAiOption(config),
|
|
814
2121
|
hidden: getFieldHiddenFunction("keywords", config)
|
|
815
2122
|
})),
|
|
816
2123
|
fieldGroupMap
|
|
817
2124
|
),
|
|
818
2125
|
withGroup(
|
|
819
|
-
|
|
2126
|
+
_sanity.defineField.call(void 0, _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {
|
|
820
2127
|
name: "canonicalUrl"
|
|
821
2128
|
}, getFieldInfo("canonicalUrl", config.fieldOverrides)), {
|
|
822
2129
|
title: "Canonical URL",
|
|
@@ -826,18 +2133,47 @@ function seoFieldsSchema(config = {}) {
|
|
|
826
2133
|
})),
|
|
827
2134
|
fieldGroupMap
|
|
828
2135
|
),
|
|
2136
|
+
withGroup(
|
|
2137
|
+
_sanity.defineField.call(void 0, _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {
|
|
2138
|
+
name: "focusKeyword"
|
|
2139
|
+
}, getFieldInfo("focusKeyword", config.fieldOverrides)), {
|
|
2140
|
+
type: "string",
|
|
2141
|
+
components: {
|
|
2142
|
+
input: FocusKeywordInput_default
|
|
2143
|
+
},
|
|
2144
|
+
options: getAiOption(config),
|
|
2145
|
+
hidden: getFieldHiddenFunction("focusKeyword", config)
|
|
2146
|
+
})),
|
|
2147
|
+
fieldGroupMap
|
|
2148
|
+
),
|
|
2149
|
+
withGroup(
|
|
2150
|
+
_sanity.defineField.call(void 0, _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {
|
|
2151
|
+
name: "hreflangs"
|
|
2152
|
+
}, getFieldInfo("hreflangs", config.fieldOverrides)), {
|
|
2153
|
+
type: "array",
|
|
2154
|
+
of: [{ type: "hreflangEntry" }],
|
|
2155
|
+
description: "Add alternate language/region versions. Include x-default for the fallback URL.",
|
|
2156
|
+
hidden: getFieldHiddenFunction("hreflangs", config)
|
|
2157
|
+
})),
|
|
2158
|
+
fieldGroupMap
|
|
2159
|
+
),
|
|
2160
|
+
...buildGeoChecklistField(config, fieldGroupMap),
|
|
2161
|
+
...buildMetaTagsPreviewField(config, fieldGroupMap),
|
|
829
2162
|
withGroup(openGraph(config), fieldGroupMap),
|
|
830
2163
|
withGroup(twitter(config), fieldGroupMap)
|
|
831
2164
|
]
|
|
832
2165
|
}));
|
|
833
2166
|
}
|
|
2167
|
+
|
|
2168
|
+
// src/schemas/types/baseMeta/index.ts
|
|
2169
|
+
|
|
834
2170
|
function baseMeta(config = {}) {
|
|
835
|
-
return
|
|
2171
|
+
return _sanity.defineType.call(void 0, {
|
|
836
2172
|
name: "baseMeta",
|
|
837
2173
|
title: "Basic Meta Settings",
|
|
838
2174
|
type: "object",
|
|
839
2175
|
fields: [
|
|
840
|
-
|
|
2176
|
+
_sanity.defineField.call(void 0, _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {
|
|
841
2177
|
name: "title"
|
|
842
2178
|
}, getFieldInfo("title", config.fieldOverrides)), {
|
|
843
2179
|
type: "string",
|
|
@@ -846,7 +2182,7 @@ function baseMeta(config = {}) {
|
|
|
846
2182
|
},
|
|
847
2183
|
hidden: getFieldHiddenFunction("title", config)
|
|
848
2184
|
})),
|
|
849
|
-
|
|
2185
|
+
_sanity.defineField.call(void 0, _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {
|
|
850
2186
|
name: "description"
|
|
851
2187
|
}, getFieldInfo("description", config.fieldOverrides)), {
|
|
852
2188
|
type: "text",
|
|
@@ -856,7 +2192,7 @@ function baseMeta(config = {}) {
|
|
|
856
2192
|
},
|
|
857
2193
|
hidden: getFieldHiddenFunction("description", config)
|
|
858
2194
|
})),
|
|
859
|
-
|
|
2195
|
+
_sanity.defineField.call(void 0, _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {
|
|
860
2196
|
name: "metaImage"
|
|
861
2197
|
}, getFieldInfo("metaImage", config.fieldOverrides)), {
|
|
862
2198
|
type: "image",
|
|
@@ -868,7 +2204,7 @@ function baseMeta(config = {}) {
|
|
|
868
2204
|
},
|
|
869
2205
|
hidden: getFieldHiddenFunction("metaImage", config)
|
|
870
2206
|
})),
|
|
871
|
-
|
|
2207
|
+
_sanity.defineField.call(void 0, _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {
|
|
872
2208
|
name: "keywords"
|
|
873
2209
|
}, getFieldInfo("keywords", config.fieldOverrides)), {
|
|
874
2210
|
title: "Keywords",
|
|
@@ -877,7 +2213,7 @@ function baseMeta(config = {}) {
|
|
|
877
2213
|
description: "Add relevant keywords for this page. These keywords will be used for SEO purposes.",
|
|
878
2214
|
hidden: getFieldHiddenFunction("keywords", config)
|
|
879
2215
|
})),
|
|
880
|
-
|
|
2216
|
+
_sanity.defineField.call(void 0, _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {
|
|
881
2217
|
name: "canonicalUrl"
|
|
882
2218
|
}, getFieldInfo("canonicalUrl", config.fieldOverrides)), {
|
|
883
2219
|
title: "Canonical URL",
|
|
@@ -885,7 +2221,7 @@ function baseMeta(config = {}) {
|
|
|
885
2221
|
description: "Specify the canonical URL for this page. This helps prevent duplicate content issues by indicating the preferred version of a page.",
|
|
886
2222
|
hidden: getFieldHiddenFunction("canonicalUrl", config)
|
|
887
2223
|
})),
|
|
888
|
-
|
|
2224
|
+
_sanity.defineField.call(void 0, _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {
|
|
889
2225
|
name: "metaAttributes"
|
|
890
2226
|
}, getFieldInfo("metaAttributes", config.fieldOverrides)), {
|
|
891
2227
|
type: "array",
|
|
@@ -895,17 +2231,55 @@ function baseMeta(config = {}) {
|
|
|
895
2231
|
]
|
|
896
2232
|
});
|
|
897
2233
|
}
|
|
898
|
-
|
|
2234
|
+
|
|
2235
|
+
// src/schemas/types/hreflang/index.ts
|
|
2236
|
+
|
|
2237
|
+
var hreflang_default = _sanity.defineType.call(void 0, {
|
|
2238
|
+
name: "hreflangEntry",
|
|
2239
|
+
title: "Hreflang Entry",
|
|
2240
|
+
type: "object",
|
|
2241
|
+
fields: [
|
|
2242
|
+
_sanity.defineField.call(void 0, {
|
|
2243
|
+
name: "locale",
|
|
2244
|
+
title: "Language / Region",
|
|
2245
|
+
type: "string",
|
|
2246
|
+
description: "BCP 47 tag \u2014 e.g. en, fr-FR, x-default",
|
|
2247
|
+
validation: (Rule) => Rule.required().custom((value) => {
|
|
2248
|
+
if (!value) return "Required";
|
|
2249
|
+
if (!/^(x-default|[a-z]{2,3}(-[A-Z]{2,3})?)$/.test(value)) {
|
|
2250
|
+
return "Must be a valid BCP 47 tag (e.g. en, fr-FR, x-default)";
|
|
2251
|
+
}
|
|
2252
|
+
return true;
|
|
2253
|
+
})
|
|
2254
|
+
}),
|
|
2255
|
+
_sanity.defineField.call(void 0, {
|
|
2256
|
+
name: "url",
|
|
2257
|
+
title: "URL",
|
|
2258
|
+
type: "url",
|
|
2259
|
+
validation: (Rule) => Rule.required().uri({ scheme: ["http", "https"] })
|
|
2260
|
+
})
|
|
2261
|
+
],
|
|
2262
|
+
preview: {
|
|
2263
|
+
select: {
|
|
2264
|
+
title: "locale",
|
|
2265
|
+
subtitle: "url"
|
|
2266
|
+
}
|
|
2267
|
+
}
|
|
2268
|
+
});
|
|
2269
|
+
|
|
2270
|
+
// src/schemas/types/metaAttribute/index.ts
|
|
2271
|
+
|
|
2272
|
+
var metaAttribute_default = _sanity.defineType.call(void 0, {
|
|
899
2273
|
name: "metaAttribute",
|
|
900
2274
|
title: "Meta Attribute",
|
|
901
2275
|
type: "object",
|
|
902
2276
|
fields: [
|
|
903
|
-
|
|
2277
|
+
_sanity.defineField.call(void 0, {
|
|
904
2278
|
name: "key",
|
|
905
2279
|
title: "Attribute Name",
|
|
906
2280
|
type: "string"
|
|
907
2281
|
}),
|
|
908
|
-
|
|
2282
|
+
_sanity.defineField.call(void 0, {
|
|
909
2283
|
name: "type",
|
|
910
2284
|
title: "Attribute Value Type",
|
|
911
2285
|
type: "string",
|
|
@@ -917,13 +2291,13 @@ var metaAttribute_default = sanity.defineType({
|
|
|
917
2291
|
},
|
|
918
2292
|
initialValue: "string"
|
|
919
2293
|
}),
|
|
920
|
-
|
|
2294
|
+
_sanity.defineField.call(void 0, {
|
|
921
2295
|
name: "value",
|
|
922
2296
|
title: "Attribute Value",
|
|
923
2297
|
type: "string",
|
|
924
2298
|
hidden: ({ parent }) => (parent == null ? void 0 : parent.type) === "image"
|
|
925
2299
|
}),
|
|
926
|
-
|
|
2300
|
+
_sanity.defineField.call(void 0, {
|
|
927
2301
|
name: "image",
|
|
928
2302
|
title: "Attribute Image Value",
|
|
929
2303
|
type: "image",
|
|
@@ -953,7 +2327,10 @@ var metaAttribute_default = sanity.defineType({
|
|
|
953
2327
|
}
|
|
954
2328
|
}
|
|
955
2329
|
});
|
|
956
|
-
|
|
2330
|
+
|
|
2331
|
+
// src/schemas/types/metaTag/index.ts
|
|
2332
|
+
|
|
2333
|
+
var metaTag_default = _sanity.defineType.call(void 0, {
|
|
957
2334
|
name: "metaTag",
|
|
958
2335
|
title: "Meta Tag",
|
|
959
2336
|
type: "object",
|
|
@@ -967,27 +2344,44 @@ var metaTag_default = sanity.defineType({
|
|
|
967
2344
|
}
|
|
968
2345
|
]
|
|
969
2346
|
});
|
|
970
|
-
|
|
2347
|
+
|
|
2348
|
+
// src/schemas/types/robots/index.ts
|
|
2349
|
+
|
|
2350
|
+
var robots_default = _sanity.defineType.call(void 0, {
|
|
971
2351
|
name: "robots",
|
|
972
2352
|
title: "Robots Settings",
|
|
973
2353
|
type: "object",
|
|
974
2354
|
fields: [
|
|
975
|
-
|
|
2355
|
+
_sanity.defineField.call(void 0, {
|
|
976
2356
|
name: "noIndex",
|
|
977
2357
|
title: "No Index",
|
|
978
2358
|
type: "boolean",
|
|
979
2359
|
initialValue: false,
|
|
980
2360
|
description: "Enable this to prevent search engines from indexing this page. The page will not appear in search results."
|
|
981
2361
|
}),
|
|
982
|
-
|
|
2362
|
+
_sanity.defineField.call(void 0, {
|
|
983
2363
|
name: "noFollow",
|
|
984
2364
|
title: "No Follow",
|
|
985
2365
|
type: "boolean",
|
|
986
2366
|
initialValue: false,
|
|
987
2367
|
description: "Enable this to prevent search engines from following links on this page. Links will not pass SEO value."
|
|
2368
|
+
}),
|
|
2369
|
+
_sanity.defineField.call(void 0, {
|
|
2370
|
+
name: "noTranslate",
|
|
2371
|
+
title: "No Translate",
|
|
2372
|
+
type: "boolean",
|
|
2373
|
+
initialValue: false,
|
|
2374
|
+
description: "Enable this to prevent search engines from offering a translated version of this page in search results."
|
|
2375
|
+
}),
|
|
2376
|
+
_sanity.defineField.call(void 0, {
|
|
2377
|
+
name: "noImageIndex",
|
|
2378
|
+
title: "No Image Index",
|
|
2379
|
+
type: "boolean",
|
|
2380
|
+
initialValue: false,
|
|
2381
|
+
description: "Enable this to prevent images on this page from appearing in image search results."
|
|
988
2382
|
})
|
|
989
2383
|
],
|
|
990
|
-
description: "Select how search engines should index
|
|
2384
|
+
description: "Select how search engines should index, follow links, translate content, and index images on this page."
|
|
991
2385
|
});
|
|
992
2386
|
|
|
993
2387
|
// src/schemas/types/index.ts
|
|
@@ -1003,13 +2397,14 @@ function types(config = {}) {
|
|
|
1003
2397
|
// pass config here
|
|
1004
2398
|
metaAttribute_default,
|
|
1005
2399
|
metaTag_default,
|
|
1006
|
-
robots_default
|
|
2400
|
+
robots_default,
|
|
2401
|
+
hreflang_default
|
|
1007
2402
|
];
|
|
1008
2403
|
}
|
|
1009
2404
|
|
|
1010
2405
|
// src/plugin.ts
|
|
1011
|
-
var resolveDashboardConfig = (healthDashboard, rootApiVersion) => {
|
|
1012
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o;
|
|
2406
|
+
var resolveDashboardConfig = (healthDashboard, rootApiVersion, rootLicenseKey) => {
|
|
2407
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p;
|
|
1013
2408
|
const cfg = typeof healthDashboard === "object" ? healthDashboard : void 0;
|
|
1014
2409
|
const deprecationWarnings = [];
|
|
1015
2410
|
if ((cfg == null ? void 0 : cfg.apiVersion) !== void 0) {
|
|
@@ -1022,27 +2417,37 @@ var resolveDashboardConfig = (healthDashboard, rootApiVersion) => {
|
|
|
1022
2417
|
'[sanity-plugin-seofields] "healthDashboard.apiVersion" is deprecated. Move it to the root "apiVersion" option instead.'
|
|
1023
2418
|
);
|
|
1024
2419
|
}
|
|
2420
|
+
if ((cfg == null ? void 0 : cfg.licenseKey) !== void 0 && !rootLicenseKey) {
|
|
2421
|
+
deprecationWarnings.push({
|
|
2422
|
+
key: "healthDashboard.licenseKey \u2192 licenseKey",
|
|
2423
|
+
version: "v1.8.0",
|
|
2424
|
+
changelogUrl: "https://github.com/hardik-143/sanity-plugin-seofields/blob/main/CHANGELOG.md"
|
|
2425
|
+
});
|
|
2426
|
+
console.warn(
|
|
2427
|
+
'[sanity-plugin-seofields] "healthDashboard.licenseKey" is deprecated. Move it to the root "licenseKey" option instead.'
|
|
2428
|
+
);
|
|
2429
|
+
}
|
|
1025
2430
|
return {
|
|
1026
2431
|
enabled: healthDashboard !== false,
|
|
1027
|
-
toolTitle: (_b = (_a = cfg == null ? void 0 : cfg.tool) == null ? void 0 : _a.title) != null ? _b : "SEO Health",
|
|
1028
|
-
toolName: (
|
|
1029
|
-
icon: (
|
|
1030
|
-
title: (
|
|
1031
|
-
description: (
|
|
2432
|
+
toolTitle: (_c = (_b = (_a = cfg == null ? void 0 : cfg.tool) == null ? void 0 : _a.title) != null ? _b : cfg == null ? void 0 : cfg.toolTitle) != null ? _c : "SEO Health",
|
|
2433
|
+
toolName: (_e = (_d = cfg == null ? void 0 : cfg.tool) == null ? void 0 : _d.name) != null ? _e : "seo-health-dashboard",
|
|
2434
|
+
icon: (_f = cfg == null ? void 0 : cfg.content) == null ? void 0 : _f.icon,
|
|
2435
|
+
title: (_g = cfg == null ? void 0 : cfg.content) == null ? void 0 : _g.title,
|
|
2436
|
+
description: (_h = cfg == null ? void 0 : cfg.content) == null ? void 0 : _h.description,
|
|
1032
2437
|
showTypeColumn: cfg == null ? void 0 : cfg.showTypeColumn,
|
|
1033
2438
|
showDocumentId: cfg == null ? void 0 : cfg.showDocumentId,
|
|
1034
|
-
queryTypes: (
|
|
1035
|
-
queryRequireSeo: (
|
|
1036
|
-
queryGroq: (
|
|
1037
|
-
apiVersion: (
|
|
1038
|
-
licenseKey: cfg == null ? void 0 : cfg.licenseKey,
|
|
2439
|
+
queryTypes: (_i = cfg == null ? void 0 : cfg.query) == null ? void 0 : _i.types,
|
|
2440
|
+
queryRequireSeo: (_j = cfg == null ? void 0 : cfg.query) == null ? void 0 : _j.requireSeo,
|
|
2441
|
+
queryGroq: (_k = cfg == null ? void 0 : cfg.query) == null ? void 0 : _k.groq,
|
|
2442
|
+
apiVersion: (_l = cfg == null ? void 0 : cfg.apiVersion) != null ? _l : rootApiVersion,
|
|
2443
|
+
licenseKey: rootLicenseKey != null ? rootLicenseKey : cfg == null ? void 0 : cfg.licenseKey,
|
|
1039
2444
|
typeDisplayLabels: cfg == null ? void 0 : cfg.typeDisplayLabels,
|
|
1040
2445
|
typeColumnMode: cfg == null ? void 0 : cfg.typeColumnMode,
|
|
1041
2446
|
titleField: cfg == null ? void 0 : cfg.titleField,
|
|
1042
2447
|
getDocumentBadge: cfg == null ? void 0 : cfg.getDocumentBadge,
|
|
1043
|
-
loadingLicense: (
|
|
1044
|
-
loadingDocuments: (
|
|
1045
|
-
noDocuments: (
|
|
2448
|
+
loadingLicense: (_m = cfg == null ? void 0 : cfg.content) == null ? void 0 : _m.loadingLicense,
|
|
2449
|
+
loadingDocuments: (_n = cfg == null ? void 0 : cfg.content) == null ? void 0 : _n.loadingDocuments,
|
|
2450
|
+
noDocuments: (_o = cfg == null ? void 0 : cfg.content) == null ? void 0 : _o.noDocuments,
|
|
1046
2451
|
previewMode: cfg == null ? void 0 : cfg.previewMode,
|
|
1047
2452
|
structureTool: cfg == null ? void 0 : cfg.structureTool,
|
|
1048
2453
|
exportEnabled: (() => {
|
|
@@ -1057,18 +2462,19 @@ var resolveDashboardConfig = (healthDashboard, rootApiVersion) => {
|
|
|
1057
2462
|
if (typeof exportCfg === "object" && exportCfg.formats) return exportCfg.formats;
|
|
1058
2463
|
return ["csv", "json"];
|
|
1059
2464
|
})(),
|
|
1060
|
-
compactStats: (
|
|
2465
|
+
compactStats: (_p = cfg == null ? void 0 : cfg.compactStats) != null ? _p : false,
|
|
1061
2466
|
deprecationWarnings
|
|
1062
2467
|
};
|
|
1063
2468
|
};
|
|
1064
|
-
var seofields =
|
|
1065
|
-
const
|
|
1066
|
-
const
|
|
1067
|
-
const
|
|
1068
|
-
const
|
|
1069
|
-
|
|
2469
|
+
var seofields = _sanity.definePlugin.call(void 0, (config = {}) => {
|
|
2470
|
+
const cfg = config;
|
|
2471
|
+
const { healthDashboard = true, licenseKey, publishGate } = cfg;
|
|
2472
|
+
const dash = resolveDashboardConfig(healthDashboard, cfg.apiVersion, licenseKey);
|
|
2473
|
+
const LazySeoHealthTool = _react.lazy.call(void 0, () => Promise.resolve().then(() => _interopRequireWildcard(require("./SeoHealthTool-2COI27KI.cjs"))));
|
|
2474
|
+
const BoundSeoHealthTool = () => _react.createElement.call(void 0,
|
|
2475
|
+
_react.Suspense,
|
|
1070
2476
|
{ fallback: null },
|
|
1071
|
-
|
|
2477
|
+
_react.createElement.call(void 0, LazySeoHealthTool, {
|
|
1072
2478
|
icon: dash.icon,
|
|
1073
2479
|
title: dash.title,
|
|
1074
2480
|
description: dash.description,
|
|
@@ -1094,12 +2500,23 @@ var seofields = sanity.definePlugin((config = {}) => {
|
|
|
1094
2500
|
_deprecationWarnings: dash.deprecationWarnings
|
|
1095
2501
|
})
|
|
1096
2502
|
);
|
|
1097
|
-
return
|
|
2503
|
+
return _chunkA57XNQC7cjs.__spreadValues.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {
|
|
1098
2504
|
name: "sanity-plugin-seofields",
|
|
1099
2505
|
schema: {
|
|
1100
|
-
types: types(
|
|
2506
|
+
types: types(cfg)
|
|
2507
|
+
}
|
|
2508
|
+
}, publishGate && licenseKey && {
|
|
2509
|
+
document: {
|
|
2510
|
+
actions: (prev, context) => {
|
|
2511
|
+
var _a;
|
|
2512
|
+
if (((_a = publishGate.types) == null ? void 0 : _a.length) && !publishGate.types.includes(context.schemaType))
|
|
2513
|
+
return prev;
|
|
2514
|
+
return prev.map(
|
|
2515
|
+
(Action) => Action.action === "publish" ? _seofieldspro.createSeoPublishGateAction.call(void 0, Action, _chunkA57XNQC7cjs.__spreadProps.call(void 0, _chunkA57XNQC7cjs.__spreadValues.call(void 0, {}, publishGate), { licenseKey })) : Action
|
|
2516
|
+
);
|
|
2517
|
+
}
|
|
1101
2518
|
}
|
|
1102
|
-
}, dash.enabled && {
|
|
2519
|
+
}), dash.enabled && {
|
|
1103
2520
|
tools: [
|
|
1104
2521
|
{
|
|
1105
2522
|
name: dash.toolName,
|
|
@@ -1111,37 +2528,187 @@ var seofields = sanity.definePlugin((config = {}) => {
|
|
|
1111
2528
|
});
|
|
1112
2529
|
});
|
|
1113
2530
|
var plugin_default = seofields;
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
2531
|
+
|
|
2532
|
+
// src/components/SeoHealthPane.tsx
|
|
2533
|
+
|
|
2534
|
+
|
|
2535
|
+
|
|
2536
|
+
// src/utils/scoring.ts
|
|
2537
|
+
var getStatusCategory = (score) => {
|
|
2538
|
+
if (score >= 80) return "excellent";
|
|
2539
|
+
if (score >= 60) return "good";
|
|
2540
|
+
if (score >= 40) return "fair";
|
|
2541
|
+
if (score > 0) return "poor";
|
|
2542
|
+
return "missing";
|
|
2543
|
+
};
|
|
2544
|
+
var scoreMetaTitle = (title) => {
|
|
2545
|
+
const issues = [];
|
|
2546
|
+
let score = 0;
|
|
2547
|
+
if (title && title.length >= 50 && title.length <= 60) {
|
|
2548
|
+
score = 15;
|
|
2549
|
+
} else if (title && title.length > 0) {
|
|
2550
|
+
score = 10;
|
|
2551
|
+
if (title.length < 50) issues.push("Meta title too short (< 50 chars)");
|
|
2552
|
+
if (title.length > 60) issues.push("Meta title too long (> 60 chars)");
|
|
2553
|
+
} else {
|
|
2554
|
+
issues.push("Missing meta title");
|
|
2555
|
+
}
|
|
2556
|
+
return { score, issues };
|
|
2557
|
+
};
|
|
2558
|
+
var scoreMetaDescription = (description) => {
|
|
2559
|
+
const issues = [];
|
|
2560
|
+
let score = 0;
|
|
2561
|
+
if (description && description.length >= 120 && description.length <= 160) {
|
|
2562
|
+
score = 15;
|
|
2563
|
+
} else if (description && description.length > 0) {
|
|
2564
|
+
score = 10;
|
|
2565
|
+
if (description.length < 120) issues.push("Meta description too short (< 120 chars)");
|
|
2566
|
+
if (description.length > 160) issues.push("Meta description too long (> 160 chars)");
|
|
2567
|
+
} else {
|
|
2568
|
+
issues.push("Missing meta description");
|
|
2569
|
+
}
|
|
2570
|
+
return { score, issues };
|
|
2571
|
+
};
|
|
2572
|
+
var scoreOpenGraph = (openGraph2) => {
|
|
2573
|
+
const issues = [];
|
|
2574
|
+
let score = 0;
|
|
2575
|
+
if (openGraph2) {
|
|
2576
|
+
if (openGraph2.title) score += 6;
|
|
2577
|
+
else issues.push("Missing OG title");
|
|
2578
|
+
if (openGraph2.description) score += 6;
|
|
2579
|
+
else issues.push("Missing OG description");
|
|
2580
|
+
if (openGraph2.image) score += 6;
|
|
2581
|
+
else issues.push("Missing OG image");
|
|
2582
|
+
if (openGraph2.type) score += 7;
|
|
2583
|
+
else issues.push("Missing OG type");
|
|
2584
|
+
} else {
|
|
2585
|
+
issues.push("Open Graph not configured");
|
|
2586
|
+
}
|
|
2587
|
+
return { score, issues };
|
|
2588
|
+
};
|
|
2589
|
+
var scoreTwitterCard = (twitter2) => {
|
|
2590
|
+
const issues = [];
|
|
2591
|
+
let score = 0;
|
|
2592
|
+
if (twitter2) {
|
|
2593
|
+
if (twitter2.title) score += 5;
|
|
2594
|
+
else issues.push("Missing Twitter title");
|
|
2595
|
+
if (twitter2.description) score += 5;
|
|
2596
|
+
else issues.push("Missing Twitter description");
|
|
2597
|
+
if (twitter2.image) score += 5;
|
|
2598
|
+
else issues.push("Missing Twitter image");
|
|
2599
|
+
} else {
|
|
2600
|
+
issues.push("Twitter Card not configured");
|
|
2601
|
+
}
|
|
2602
|
+
return { score, issues };
|
|
2603
|
+
};
|
|
2604
|
+
var scoreKeywordArray = (keywords, title, description) => {
|
|
2605
|
+
if (!keywords || keywords.length === 0) {
|
|
2606
|
+
return { score: 0, issues: ["No keywords defined"], stuffed: false };
|
|
2607
|
+
}
|
|
2608
|
+
const issues = [];
|
|
2609
|
+
let score = 2;
|
|
2610
|
+
if (_chunkY46ACXM4cjs.hasMatchingKeyword.call(void 0, title || "", keywords) || _chunkY46ACXM4cjs.hasMatchingKeyword.call(void 0, description || "", keywords)) {
|
|
2611
|
+
score += 3;
|
|
2612
|
+
} else {
|
|
2613
|
+
issues.push("Keywords defined but not used in title or description");
|
|
2614
|
+
}
|
|
2615
|
+
const stuffed = _chunkY46ACXM4cjs.hasKeywordOveruse.call(void 0, title || "", keywords) || _chunkY46ACXM4cjs.hasKeywordOveruse.call(void 0, description || "", keywords);
|
|
2616
|
+
if (stuffed) issues.push("Keyword stuffing detected \u2014 reduce repeated keyword usage");
|
|
2617
|
+
return { score, issues, stuffed };
|
|
2618
|
+
};
|
|
2619
|
+
var scoreFocusKeyword = (focusKeyword, title, description) => {
|
|
2620
|
+
const placement = _chunkY46ACXM4cjs.getFocusKeywordPlacement.call(void 0, focusKeyword, title, description);
|
|
2621
|
+
if (!placement.hasFocusKeyword) {
|
|
2622
|
+
return { score: 0, issues: ["No focus keyword defined"], stuffed: false };
|
|
2623
|
+
}
|
|
2624
|
+
const issues = [];
|
|
2625
|
+
let score = 1;
|
|
2626
|
+
if (placement.atStartOfTitle) {
|
|
2627
|
+
score += 4;
|
|
2628
|
+
} else if (placement.inTitle) {
|
|
2629
|
+
score += 2;
|
|
2630
|
+
issues.push("Focus keyword is in the title but not at the start");
|
|
2631
|
+
} else if (placement.inDescription) {
|
|
2632
|
+
score += 1;
|
|
2633
|
+
issues.push("Focus keyword missing from meta title");
|
|
2634
|
+
} else {
|
|
2635
|
+
issues.push("Focus keyword missing from meta title and description");
|
|
2636
|
+
}
|
|
2637
|
+
if (placement.isStuffed)
|
|
2638
|
+
issues.push("Focus keyword appears too many times in title \u2014 avoid stuffing");
|
|
2639
|
+
return { score, issues, stuffed: placement.isStuffed };
|
|
2640
|
+
};
|
|
2641
|
+
var scoreKeywordOptimization = (keywords, focusKeyword, title, description) => {
|
|
2642
|
+
const arrayResult = scoreKeywordArray(keywords, title, description);
|
|
2643
|
+
const focusResult = scoreFocusKeyword(focusKeyword, title, description);
|
|
2644
|
+
let score = arrayResult.score + focusResult.score;
|
|
2645
|
+
if (arrayResult.stuffed || focusResult.stuffed) score = Math.max(0, score - 2);
|
|
2646
|
+
return { score: Math.min(score, 10), issues: [...arrayResult.issues, ...focusResult.issues] };
|
|
2647
|
+
};
|
|
2648
|
+
var calculateHealthScore = (doc) => {
|
|
2649
|
+
if (!doc.seo) {
|
|
2650
|
+
return { score: 0, status: "missing", issues: ["SEO fields not configured"] };
|
|
2651
|
+
}
|
|
2652
|
+
const seo = doc.seo;
|
|
2653
|
+
const title = seo.title;
|
|
2654
|
+
const description = seo.description;
|
|
2655
|
+
const keywords = seo.keywords;
|
|
2656
|
+
const focusKeyword = seo.focusKeyword;
|
|
2657
|
+
const robots = seo.robots;
|
|
2658
|
+
const openGraph2 = seo.openGraph;
|
|
2659
|
+
const twitter2 = seo.twitter;
|
|
2660
|
+
let score = 0;
|
|
2661
|
+
const issues = [];
|
|
2662
|
+
const titleResult = scoreMetaTitle(title);
|
|
2663
|
+
score += titleResult.score;
|
|
2664
|
+
issues.push(...titleResult.issues);
|
|
2665
|
+
const descResult = scoreMetaDescription(description);
|
|
2666
|
+
score += descResult.score;
|
|
2667
|
+
issues.push(...descResult.issues);
|
|
2668
|
+
if (seo.metaImage) score += 10;
|
|
2669
|
+
else issues.push("Missing meta image");
|
|
2670
|
+
const keywordResult = scoreKeywordOptimization(keywords, focusKeyword, title, description);
|
|
2671
|
+
score += keywordResult.score;
|
|
2672
|
+
issues.push(...keywordResult.issues);
|
|
2673
|
+
if (robots && !robots.noIndex) score += 5;
|
|
2674
|
+
else if (!robots) score += 5;
|
|
2675
|
+
const ogResult = scoreOpenGraph(openGraph2);
|
|
2676
|
+
score += ogResult.score;
|
|
2677
|
+
issues.push(...ogResult.issues);
|
|
2678
|
+
const twResult = scoreTwitterCard(twitter2);
|
|
2679
|
+
score += twResult.score;
|
|
2680
|
+
issues.push(...twResult.issues);
|
|
2681
|
+
const hasMetaImage = !!seo.metaImage;
|
|
2682
|
+
const hasOgImage = !!(openGraph2 && openGraph2.image);
|
|
2683
|
+
const hasTwitterImage = !!(twitter2 && twitter2.image);
|
|
2684
|
+
if (hasMetaImage && hasOgImage && hasTwitterImage) {
|
|
2685
|
+
score += 5;
|
|
2686
|
+
} else {
|
|
2687
|
+
const missingImages = [];
|
|
2688
|
+
if (!hasMetaImage) missingImages.push("meta image");
|
|
2689
|
+
if (!hasOgImage) missingImages.push("OG image");
|
|
2690
|
+
if (!hasTwitterImage) missingImages.push("Twitter image");
|
|
2691
|
+
issues.push(`Missing images for full score: ${missingImages.join(", ")}`);
|
|
2692
|
+
}
|
|
2693
|
+
const status = getStatusCategory(score);
|
|
2694
|
+
return { score, status, issues };
|
|
2695
|
+
};
|
|
1132
2696
|
|
|
1133
2697
|
// src/index.ts
|
|
1134
2698
|
var src_default = plugin_default;
|
|
1135
2699
|
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
2700
|
+
|
|
2701
|
+
|
|
2702
|
+
|
|
2703
|
+
|
|
2704
|
+
|
|
2705
|
+
|
|
2706
|
+
|
|
2707
|
+
|
|
2708
|
+
|
|
2709
|
+
|
|
2710
|
+
|
|
2711
|
+
|
|
2712
|
+
|
|
2713
|
+
exports.SchemaOrgDocumentJsonLdPreview = _chunk5XTQRILLcjs.SchemaOrgJsonLdPreview; exports.SchemaOrgJsonLdPreview = _chunk5XTQRILLcjs.SchemaOrgJsonLdPreview; exports.allSchemas = types; exports.baseMetaSchema = baseMeta; exports.calculateHealthScore = calculateHealthScore; exports.createSeoHealthPane = _seofieldspro.createSeoHealthPane; exports.default = src_default; exports.metaAttributeSchema = metaAttribute_default; exports.metaTagSchema = metaTag_default; exports.openGraphSchema = openGraph; exports.robotsSchema = robots_default; exports.seoFieldsSchema = seoFieldsSchema; exports.twitterSchema = twitter;
|
|
1147
2714
|
//# sourceMappingURL=index.cjs.map
|