sanity-plugin-seofields 1.6.0 → 1.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. package/dist/SeoHealthDashboard-FZTP4GS7.cjs +10 -0
  2. package/dist/{SeoHealthDashboard-7XMPVJRX.cjs.map → SeoHealthDashboard-FZTP4GS7.cjs.map} +1 -1
  3. package/dist/SeoHealthDashboard-PY5MKJCZ.js +4 -0
  4. package/dist/{SeoHealthDashboard-UWPLB5DM.js.map → SeoHealthDashboard-PY5MKJCZ.js.map} +1 -1
  5. package/dist/{SeoHealthTool-XCXINAQI.js → SeoHealthTool-SKY7FAKK.js} +3 -3
  6. package/dist/{SeoHealthTool-XCXINAQI.js.map → SeoHealthTool-SKY7FAKK.js.map} +1 -1
  7. package/dist/{SeoHealthTool-2H4XZR4I.cjs → SeoHealthTool-Z3O6NEKF.cjs} +4 -4
  8. package/dist/{SeoHealthTool-2H4XZR4I.cjs.map → SeoHealthTool-Z3O6NEKF.cjs.map} +1 -1
  9. package/dist/{SeoPreview-F6GGPZWI.js → SeoPreview-BQBKMYSG.js} +43 -8
  10. package/dist/SeoPreview-BQBKMYSG.js.map +1 -0
  11. package/dist/{SeoPreview-JDROKZLP.cjs → SeoPreview-LWSWTIF5.cjs} +41 -6
  12. package/dist/SeoPreview-LWSWTIF5.cjs.map +1 -0
  13. package/dist/{chunk-Z74QPO75.cjs → chunk-77U7CMJP.cjs} +12 -4
  14. package/dist/chunk-77U7CMJP.cjs.map +1 -0
  15. package/dist/{chunk-6NIHHOVS.js → chunk-IQG5JWVT.js} +2 -2
  16. package/dist/{chunk-6NIHHOVS.js.map → chunk-IQG5JWVT.js.map} +1 -1
  17. package/dist/{chunk-NHJBEV3A.js → chunk-KFFDQX22.js} +12 -4
  18. package/dist/chunk-KFFDQX22.js.map +1 -0
  19. package/dist/{chunk-KWUITSHS.js → chunk-ULFY5STC.js} +14 -14
  20. package/dist/chunk-ULFY5STC.js.map +1 -0
  21. package/dist/{chunk-WCLEWFAJ.cjs → chunk-XXQURVNE.cjs} +120 -120
  22. package/dist/chunk-XXQURVNE.cjs.map +1 -0
  23. package/dist/{chunk-7HCP5O62.cjs → chunk-YM3ZZ2HU.cjs} +2 -2
  24. package/dist/{chunk-7HCP5O62.cjs.map → chunk-YM3ZZ2HU.cjs.map} +1 -1
  25. package/dist/cli.js +1 -1
  26. package/dist/{component-7rqDvuy2.d.ts → component-CWZ0tlsq.d.ts} +7 -7
  27. package/dist/{component-J2nEQkOw.d.cts → component-DS-Ve_nw.d.cts} +7 -7
  28. package/dist/index.cjs +48 -41
  29. package/dist/index.cjs.map +1 -1
  30. package/dist/index.d.cts +55 -8
  31. package/dist/index.d.ts +55 -8
  32. package/dist/index.js +31 -20
  33. package/dist/index.js.map +1 -1
  34. package/dist/next.cjs +87 -88
  35. package/dist/next.cjs.map +1 -1
  36. package/dist/next.d.cts +4 -4
  37. package/dist/next.d.ts +4 -4
  38. package/dist/next.js +12 -9
  39. package/dist/next.js.map +1 -1
  40. package/dist/schema/next.cjs +80 -80
  41. package/dist/schema/next.d.cts +3 -3
  42. package/dist/schema/next.d.ts +3 -3
  43. package/dist/schema/next.js +3 -3
  44. package/dist/schema.cjs +153 -153
  45. package/dist/schema.cjs.map +1 -1
  46. package/dist/schema.d.cts +6 -6
  47. package/dist/schema.d.ts +6 -6
  48. package/dist/schema.js +2 -2
  49. package/dist/schema.js.map +1 -1
  50. package/dist/{types-BSgolLj3.d.cts → types-BjVpmBAX.d.cts} +1 -1
  51. package/dist/{types-BRn3hfQb.d.ts → types-Dy7r5det.d.ts} +1 -1
  52. package/package.json +1 -1
  53. package/dist/SeoHealthDashboard-7XMPVJRX.cjs +0 -10
  54. package/dist/SeoHealthDashboard-UWPLB5DM.js +0 -4
  55. package/dist/SeoPreview-F6GGPZWI.js.map +0 -1
  56. package/dist/SeoPreview-JDROKZLP.cjs.map +0 -1
  57. package/dist/chunk-KWUITSHS.js.map +0 -1
  58. package/dist/chunk-NHJBEV3A.js.map +0 -1
  59. package/dist/chunk-WCLEWFAJ.cjs.map +0 -1
  60. package/dist/chunk-Z74QPO75.cjs.map +0 -1
  61. package/dist/{types-DoUYMRVf.d.cts → types-BdaGoGQE.d.cts} +30 -30
  62. package/dist/{types-DnVvOp3o.d.ts → types-BwmZmt9I.d.ts} +30 -30
@@ -0,0 +1,10 @@
1
+ 'use strict';
2
+
3
+ var chunk77U7CMJP_cjs = require('./chunk-77U7CMJP.cjs');
4
+ require('./chunk-S367Y35J.cjs');
5
+
6
+
7
+
8
+ module.exports = chunk77U7CMJP_cjs.SeoHealthDashboard_default;
9
+ //# sourceMappingURL=SeoHealthDashboard-FZTP4GS7.cjs.map
10
+ //# sourceMappingURL=SeoHealthDashboard-FZTP4GS7.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":[],"names":[],"mappings":"","file":"SeoHealthDashboard-7XMPVJRX.cjs"}
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"SeoHealthDashboard-FZTP4GS7.cjs"}
@@ -0,0 +1,4 @@
1
+ export { SeoHealthDashboard_default as default } from './chunk-KFFDQX22.js';
2
+ import './chunk-2NMEKWO5.js';
3
+ //# sourceMappingURL=SeoHealthDashboard-PY5MKJCZ.js.map
4
+ //# sourceMappingURL=SeoHealthDashboard-PY5MKJCZ.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":[],"names":[],"mappings":"","file":"SeoHealthDashboard-UWPLB5DM.js"}
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"SeoHealthDashboard-PY5MKJCZ.js"}
@@ -1,4 +1,4 @@
1
- import { SeoHealthDashboard_default } from './chunk-NHJBEV3A.js';
1
+ import { SeoHealthDashboard_default } from './chunk-KFFDQX22.js';
2
2
  import { __spreadValues } from './chunk-2NMEKWO5.js';
3
3
  import { jsx } from 'react/jsx-runtime';
4
4
 
@@ -8,5 +8,5 @@ var SeoHealthTool = (props) => {
8
8
  var SeoHealthTool_default = SeoHealthTool;
9
9
 
10
10
  export { SeoHealthTool_default as default };
11
- //# sourceMappingURL=SeoHealthTool-XCXINAQI.js.map
12
- //# sourceMappingURL=SeoHealthTool-XCXINAQI.js.map
11
+ //# sourceMappingURL=SeoHealthTool-SKY7FAKK.js.map
12
+ //# sourceMappingURL=SeoHealthTool-SKY7FAKK.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/SeoHealthTool.tsx"],"names":[],"mappings":";;;;AAMA,IAAM,aAAA,GAAgB,CAAC,KAAA,KAAmC;AACxD,EAAA,uBAAO,GAAA,CAAC,+CAAuB,KAAA,CAAO,CAAA;AACxC,CAAA;AAEA,IAAO,qBAAA,GAAQ","file":"SeoHealthTool-XCXINAQI.js","sourcesContent":["import SeoHealthDashboard, {SeoHealthDashboardProps} from './SeoHealthDashboard'\n\n/**\n * Sanity Tool component for the SEO Health Dashboard\n * This component wraps the SeoHealthDashboard for use as a custom tool in Sanity Studio\n */\nconst SeoHealthTool = (props: SeoHealthDashboardProps) => {\n return <SeoHealthDashboard {...props} />\n}\n\nexport default SeoHealthTool\n"]}
1
+ {"version":3,"sources":["../src/components/SeoHealthTool.tsx"],"names":[],"mappings":";;;;AAMA,IAAM,aAAA,GAAgB,CAAC,KAAA,KAAmC;AACxD,EAAA,uBAAO,GAAA,CAAC,+CAAuB,KAAA,CAAO,CAAA;AACxC,CAAA;AAEA,IAAO,qBAAA,GAAQ","file":"SeoHealthTool-SKY7FAKK.js","sourcesContent":["import SeoHealthDashboard, {SeoHealthDashboardProps} from './SeoHealthDashboard'\n\n/**\n * Sanity Tool component for the SEO Health Dashboard\n * This component wraps the SeoHealthDashboard for use as a custom tool in Sanity Studio\n */\nconst SeoHealthTool = (props: SeoHealthDashboardProps) => {\n return <SeoHealthDashboard {...props} />\n}\n\nexport default SeoHealthTool\n"]}
@@ -1,14 +1,14 @@
1
1
  'use strict';
2
2
 
3
- var chunkZ74QPO75_cjs = require('./chunk-Z74QPO75.cjs');
3
+ var chunk77U7CMJP_cjs = require('./chunk-77U7CMJP.cjs');
4
4
  var chunkS367Y35J_cjs = require('./chunk-S367Y35J.cjs');
5
5
  var jsxRuntime = require('react/jsx-runtime');
6
6
 
7
7
  var SeoHealthTool = (props) => {
8
- return /* @__PURE__ */ jsxRuntime.jsx(chunkZ74QPO75_cjs.SeoHealthDashboard_default, chunkS367Y35J_cjs.__spreadValues({}, props));
8
+ return /* @__PURE__ */ jsxRuntime.jsx(chunk77U7CMJP_cjs.SeoHealthDashboard_default, chunkS367Y35J_cjs.__spreadValues({}, props));
9
9
  };
10
10
  var SeoHealthTool_default = SeoHealthTool;
11
11
 
12
12
  module.exports = SeoHealthTool_default;
13
- //# sourceMappingURL=SeoHealthTool-2H4XZR4I.cjs.map
14
- //# sourceMappingURL=SeoHealthTool-2H4XZR4I.cjs.map
13
+ //# sourceMappingURL=SeoHealthTool-Z3O6NEKF.cjs.map
14
+ //# sourceMappingURL=SeoHealthTool-Z3O6NEKF.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/SeoHealthTool.tsx"],"names":["jsx","SeoHealthDashboard_default"],"mappings":";;;;;;AAMA,IAAM,aAAA,GAAgB,CAAC,KAAA,KAAmC;AACxD,EAAA,uBAAOA,cAAA,CAACC,mFAAuB,KAAA,CAAO,CAAA;AACxC,CAAA;AAEA,IAAO,qBAAA,GAAQ","file":"SeoHealthTool-2H4XZR4I.cjs","sourcesContent":["import SeoHealthDashboard, {SeoHealthDashboardProps} from './SeoHealthDashboard'\n\n/**\n * Sanity Tool component for the SEO Health Dashboard\n * This component wraps the SeoHealthDashboard for use as a custom tool in Sanity Studio\n */\nconst SeoHealthTool = (props: SeoHealthDashboardProps) => {\n return <SeoHealthDashboard {...props} />\n}\n\nexport default SeoHealthTool\n"]}
1
+ {"version":3,"sources":["../src/components/SeoHealthTool.tsx"],"names":["jsx","SeoHealthDashboard_default"],"mappings":";;;;;;AAMA,IAAM,aAAA,GAAgB,CAAC,KAAA,KAAmC;AACxD,EAAA,uBAAOA,cAAA,CAACC,mFAAuB,KAAA,CAAO,CAAA;AACxC,CAAA;AAEA,IAAO,qBAAA,GAAQ","file":"SeoHealthTool-Z3O6NEKF.cjs","sourcesContent":["import SeoHealthDashboard, {SeoHealthDashboardProps} from './SeoHealthDashboard'\n\n/**\n * Sanity Tool component for the SEO Health Dashboard\n * This component wraps the SeoHealthDashboard for use as a custom tool in Sanity Studio\n */\nconst SeoHealthTool = (props: SeoHealthDashboardProps) => {\n return <SeoHealthDashboard {...props} />\n}\n\nexport default SeoHealthTool\n"]}
@@ -1,9 +1,10 @@
1
1
  import { truncate } from './chunk-25JLWVEU.js';
2
2
  import './chunk-2NMEKWO5.js';
3
3
  import { Box } from '@sanity/ui';
4
- import { useFormValue } from 'sanity';
4
+ import { useState, useEffect } from 'react';
5
+ import { useClient, useFormValue } from 'sanity';
5
6
  import styled from 'styled-components';
6
- import { jsx, jsxs } from 'react/jsx-runtime';
7
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
7
8
 
8
9
  var PreviewContainer = styled.div`
9
10
  max-width: 600px;
@@ -69,11 +70,24 @@ var LiveIndicator = styled.span`
69
70
  border-radius: 4px;
70
71
  `;
71
72
  var SeoPreview = (props) => {
72
- var _a, _b;
73
+ var _a, _b, _c, _d;
73
74
  const { path, schemaType } = props;
74
75
  const { options } = schemaType;
75
76
  const baseUrl = (options == null ? void 0 : options.baseUrl) || "https://www.example.com";
76
77
  const prefixFunction = options == null ? void 0 : options.prefix;
78
+ const titleSuffixOption = options == null ? void 0 : options.titleSuffix;
79
+ const titleSuffixInheritColor = (_a = options == null ? void 0 : options.titleSuffixInheritColor) != null ? _a : false;
80
+ const titleSuffixQuery = options == null ? void 0 : options.titleSuffixQuery;
81
+ const client = useClient({ apiVersion: (_b = options == null ? void 0 : options.apiVersion) != null ? _b : "2024-01-01" });
82
+ const [groqTitleSuffix, setGroqTitleSuffix] = useState("");
83
+ useEffect(() => {
84
+ if (!titleSuffixQuery) return;
85
+ client.fetch(titleSuffixQuery).then((result) => {
86
+ setGroqTitleSuffix(result === null || result === void 0 ? "" : String(result));
87
+ }).catch(() => {
88
+ setGroqTitleSuffix("");
89
+ });
90
+ }, [titleSuffixQuery, client]);
77
91
  const parent = useFormValue([path[0]]) || {
78
92
  title: "",
79
93
  description: "",
@@ -82,13 +96,22 @@ var SeoPreview = (props) => {
82
96
  const rootDoc = useFormValue([]) || {
83
97
  slug: { current: "" }
84
98
  };
85
- const slug = ((_a = rootDoc == null ? void 0 : rootDoc.slug) == null ? void 0 : _a.current) || "";
99
+ const slug = ((_c = rootDoc == null ? void 0 : rootDoc.slug) == null ? void 0 : _c.current) || "";
86
100
  const {
87
101
  title,
88
102
  description,
89
103
  canonicalUrl: url
90
104
  } = parent;
91
- const base = (_b = url || baseUrl) == null ? void 0 : _b.replace(/\/+$/, "");
105
+ const getTitleSuffix = () => {
106
+ if (titleSuffixQuery) return groqTitleSuffix;
107
+ if (!titleSuffixOption) return "";
108
+ if (typeof titleSuffixOption === "function") {
109
+ return titleSuffixOption(rootDoc);
110
+ }
111
+ return titleSuffixOption;
112
+ };
113
+ const titleSuffix = getTitleSuffix();
114
+ const base = (_d = url || baseUrl) == null ? void 0 : _d.replace(/\/+$/, "");
92
115
  const slugStr = String(slug || "").replace(/^\/+/, "");
93
116
  const pref = String(
94
117
  prefixFunction ? prefixFunction(rootDoc) : ""
@@ -136,7 +159,19 @@ var SeoPreview = (props) => {
136
159
  ] }),
137
160
  /* @__PURE__ */ jsxs(PreviewBody, { children: [
138
161
  /* @__PURE__ */ jsx(SerpUrl, { children: finalUrl ? urlDisplay : "example.com \u203A page-url" }),
139
- /* @__PURE__ */ jsx(SerpTitle, { children: title && title.length > 0 ? truncate(title, 60) : "Your SEO Title will appear here" }),
162
+ /* @__PURE__ */ jsx(SerpTitle, { children: title && title.length > 0 ? /* @__PURE__ */ jsxs(Fragment, { children: [
163
+ truncate(title, Math.max(1, 60 - titleSuffix.length)),
164
+ titleSuffix && /* @__PURE__ */ jsxs(
165
+ "span",
166
+ {
167
+ style: titleSuffixInheritColor ? void 0 : { color: "#70757a", fontWeight: 400 },
168
+ children: [
169
+ "| ",
170
+ titleSuffix
171
+ ]
172
+ }
173
+ )
174
+ ] }) : "Your SEO Title will appear here" }),
140
175
  /* @__PURE__ */ jsx(SerpDescription, { children: description && description.length > 0 ? truncate(description, 160) : "Your meta description will show up here. Make it compelling!" })
141
176
  ] })
142
177
  ] }) });
@@ -144,5 +179,5 @@ var SeoPreview = (props) => {
144
179
  var SeoPreview_default = SeoPreview;
145
180
 
146
181
  export { SeoPreview_default as default };
147
- //# sourceMappingURL=SeoPreview-F6GGPZWI.js.map
148
- //# sourceMappingURL=SeoPreview-F6GGPZWI.js.map
182
+ //# sourceMappingURL=SeoPreview-BQBKMYSG.js.map
183
+ //# sourceMappingURL=SeoPreview-BQBKMYSG.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/SeoPreview.tsx"],"names":[],"mappings":"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","file":"SeoPreview-BQBKMYSG.js","sourcesContent":["import {Box} from '@sanity/ui'\nimport {type ReactElement, useEffect, useState} from 'react'\nimport {StringInputProps, useClient, useFormValue} from 'sanity'\nimport styled from 'styled-components'\n\nimport {truncate} from '../utils/seoUtils'\n\nconst PreviewContainer = styled.div`\n max-width: 600px;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n background: #ffffff;\n border: 1px solid #dadce0;\n border-radius: 8px;\n overflow: hidden;\n`\n\nconst PreviewHeader = styled.div`\n background: #f8f9fa;\n padding: 12px 16px;\n border-bottom: 1px solid #dadce0;\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n`\n\nconst PreviewBody = styled.div`\n padding: 16px;\n`\n\nconst SerpUrl = styled.p`\n margin: 0 0 4px;\n color: #006621;\n font-size: 13px;\n line-height: 1.4;\n word-break: break-word;\n`\n\nconst SerpTitle = styled.h3`\n margin: 0 0 8px;\n color: #1a0dab;\n font-size: 18px;\n font-weight: 500;\n line-height: 1.4;\n word-break: break-word;\n\n &:hover {\n text-decoration: underline;\n }\n`\n\nconst SerpDescription = styled.p`\n margin: 0;\n color: #545454;\n font-size: 14px;\n line-height: 1.6;\n word-break: break-word;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n`\n\nconst LiveIndicator = styled.span`\n display: inline-flex;\n align-items: center;\n gap: 4px;\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n color: #4f46e5;\n background: #f0f4ff;\n padding: 4px 8px;\n border-radius: 4px;\n`\n\nconst SeoPreview = (props: StringInputProps): ReactElement => {\n const {path, schemaType} = props\n const {options} = schemaType as {\n options?: {\n baseUrl?: string\n apiVersion?: string\n prefix?: ((doc: {_type?: string} & Record<string, unknown>) => string) | string\n titleSuffix?: ((doc: {_type?: string} & Record<string, unknown>) => string) | string\n titleSuffixInheritColor?: boolean\n titleSuffixQuery?: string\n }\n }\n const baseUrl = options?.baseUrl || 'https://www.example.com'\n const prefixFunction = options?.prefix as\n | ((doc: {_type?: string} & Record<string, unknown>) => string)\n | undefined\n const titleSuffixOption = options?.titleSuffix\n const titleSuffixInheritColor = options?.titleSuffixInheritColor ?? false\n const titleSuffixQuery = options?.titleSuffixQuery\n\n const client = useClient({apiVersion: options?.apiVersion ?? '2024-01-01'})\n const [groqTitleSuffix, setGroqTitleSuffix] = useState<string>('')\n\n useEffect(() => {\n if (!titleSuffixQuery) return\n client\n .fetch<string>(titleSuffixQuery)\n .then((result) => {\n setGroqTitleSuffix(result === null || result === undefined ? '' : String(result))\n })\n .catch(() => {\n setGroqTitleSuffix('')\n })\n }, [titleSuffixQuery, client])\n const parent = useFormValue([path[0]]) || {\n title: '',\n description: '',\n canonicalUrl: '',\n }\n const rootDoc: {\n slug?: {current: string}\n } = useFormValue([]) || {\n slug: {current: ''},\n }\n const slug: string = rootDoc?.slug?.current || ''\n\n const {\n title,\n description,\n canonicalUrl: url,\n } = parent as {\n title?: string\n description?: string\n canonicalUrl?: string\n }\n\n const getTitleSuffix = (): string => {\n if (titleSuffixQuery) return groqTitleSuffix\n if (!titleSuffixOption) return ''\n if (typeof titleSuffixOption === 'function') {\n return titleSuffixOption(rootDoc as {_type?: string} & Record<string, unknown>)\n }\n return titleSuffixOption\n }\n const titleSuffix: string = getTitleSuffix()\n\n // Build full URL\n const base = (url || baseUrl)?.replace(/\\/+$/, '')\n const slugStr = String(slug || '').replace(/^\\/+/, '')\n const pref = String(\n prefixFunction ? prefixFunction(rootDoc as {slug?: {current: string}}) : '',\n ).replace(/^\\/+|\\/+$/g, '')\n const urlPath = [pref, slugStr].filter(Boolean).join('/')\n const finalUrl = urlPath ? `${base}/${urlPath}` : base\n\n // Extract domain for display\n const domain = (() => {\n try {\n const u = new URL(finalUrl || base)\n return u.hostname\n } catch {\n return 'example.com'\n }\n })()\n\n // Format URL display with › separator\n const urlDisplay = `${domain}${urlPath ? ` › ${urlPath.split('/').slice(-1)[0]}` : ''}`\n\n return (\n <Box padding={3}>\n <PreviewContainer>\n <PreviewHeader>\n <span\n style={{\n fontSize: '11px',\n color: '#5f6368',\n textTransform: 'uppercase',\n letterSpacing: '0.05em',\n }}\n >\n Search Preview\n </span>\n <LiveIndicator>\n <span\n style={{\n width: '4px',\n height: '4px',\n borderRadius: '50%',\n backgroundColor: '#4f46e5',\n display: 'inline-block',\n }}\n />\n Live\n </LiveIndicator>\n </PreviewHeader>\n\n <PreviewBody>\n <SerpUrl>{finalUrl ? urlDisplay : 'example.com › page-url'}</SerpUrl>\n <SerpTitle>\n {title && title.length > 0 ? (\n <>\n {truncate(title, Math.max(1, 60 - titleSuffix.length))}\n {titleSuffix && (\n <span\n style={\n titleSuffixInheritColor ? undefined : {color: '#70757a', fontWeight: 400}\n }\n >\n | {titleSuffix}\n </span>\n )}\n </>\n ) : (\n 'Your SEO Title will appear here'\n )}\n </SerpTitle>\n <SerpDescription>\n {description && description.length > 0\n ? truncate(description, 160)\n : 'Your meta description will show up here. Make it compelling!'}\n </SerpDescription>\n </PreviewBody>\n </PreviewContainer>\n </Box>\n )\n}\n\nexport default SeoPreview\n"]}
@@ -3,6 +3,7 @@
3
3
  var chunkIFDLKZET_cjs = require('./chunk-IFDLKZET.cjs');
4
4
  require('./chunk-S367Y35J.cjs');
5
5
  var ui = require('@sanity/ui');
6
+ var react = require('react');
6
7
  var sanity = require('sanity');
7
8
  var styled = require('styled-components');
8
9
  var jsxRuntime = require('react/jsx-runtime');
@@ -75,11 +76,24 @@ var LiveIndicator = styled__default.default.span`
75
76
  border-radius: 4px;
76
77
  `;
77
78
  var SeoPreview = (props) => {
78
- var _a, _b;
79
+ var _a, _b, _c, _d;
79
80
  const { path, schemaType } = props;
80
81
  const { options } = schemaType;
81
82
  const baseUrl = (options == null ? void 0 : options.baseUrl) || "https://www.example.com";
82
83
  const prefixFunction = options == null ? void 0 : options.prefix;
84
+ const titleSuffixOption = options == null ? void 0 : options.titleSuffix;
85
+ const titleSuffixInheritColor = (_a = options == null ? void 0 : options.titleSuffixInheritColor) != null ? _a : false;
86
+ const titleSuffixQuery = options == null ? void 0 : options.titleSuffixQuery;
87
+ const client = sanity.useClient({ apiVersion: (_b = options == null ? void 0 : options.apiVersion) != null ? _b : "2024-01-01" });
88
+ const [groqTitleSuffix, setGroqTitleSuffix] = react.useState("");
89
+ react.useEffect(() => {
90
+ if (!titleSuffixQuery) return;
91
+ client.fetch(titleSuffixQuery).then((result) => {
92
+ setGroqTitleSuffix(result === null || result === void 0 ? "" : String(result));
93
+ }).catch(() => {
94
+ setGroqTitleSuffix("");
95
+ });
96
+ }, [titleSuffixQuery, client]);
83
97
  const parent = sanity.useFormValue([path[0]]) || {
84
98
  title: "",
85
99
  description: "",
@@ -88,13 +102,22 @@ var SeoPreview = (props) => {
88
102
  const rootDoc = sanity.useFormValue([]) || {
89
103
  slug: { current: "" }
90
104
  };
91
- const slug = ((_a = rootDoc == null ? void 0 : rootDoc.slug) == null ? void 0 : _a.current) || "";
105
+ const slug = ((_c = rootDoc == null ? void 0 : rootDoc.slug) == null ? void 0 : _c.current) || "";
92
106
  const {
93
107
  title,
94
108
  description,
95
109
  canonicalUrl: url
96
110
  } = parent;
97
- const base = (_b = url || baseUrl) == null ? void 0 : _b.replace(/\/+$/, "");
111
+ const getTitleSuffix = () => {
112
+ if (titleSuffixQuery) return groqTitleSuffix;
113
+ if (!titleSuffixOption) return "";
114
+ if (typeof titleSuffixOption === "function") {
115
+ return titleSuffixOption(rootDoc);
116
+ }
117
+ return titleSuffixOption;
118
+ };
119
+ const titleSuffix = getTitleSuffix();
120
+ const base = (_d = url || baseUrl) == null ? void 0 : _d.replace(/\/+$/, "");
98
121
  const slugStr = String(slug || "").replace(/^\/+/, "");
99
122
  const pref = String(
100
123
  prefixFunction ? prefixFunction(rootDoc) : ""
@@ -142,7 +165,19 @@ var SeoPreview = (props) => {
142
165
  ] }),
143
166
  /* @__PURE__ */ jsxRuntime.jsxs(PreviewBody, { children: [
144
167
  /* @__PURE__ */ jsxRuntime.jsx(SerpUrl, { children: finalUrl ? urlDisplay : "example.com \u203A page-url" }),
145
- /* @__PURE__ */ jsxRuntime.jsx(SerpTitle, { children: title && title.length > 0 ? chunkIFDLKZET_cjs.truncate(title, 60) : "Your SEO Title will appear here" }),
168
+ /* @__PURE__ */ jsxRuntime.jsx(SerpTitle, { children: title && title.length > 0 ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
169
+ chunkIFDLKZET_cjs.truncate(title, Math.max(1, 60 - titleSuffix.length)),
170
+ titleSuffix && /* @__PURE__ */ jsxRuntime.jsxs(
171
+ "span",
172
+ {
173
+ style: titleSuffixInheritColor ? void 0 : { color: "#70757a", fontWeight: 400 },
174
+ children: [
175
+ "| ",
176
+ titleSuffix
177
+ ]
178
+ }
179
+ )
180
+ ] }) : "Your SEO Title will appear here" }),
146
181
  /* @__PURE__ */ jsxRuntime.jsx(SerpDescription, { children: description && description.length > 0 ? chunkIFDLKZET_cjs.truncate(description, 160) : "Your meta description will show up here. Make it compelling!" })
147
182
  ] })
148
183
  ] }) });
@@ -150,5 +185,5 @@ var SeoPreview = (props) => {
150
185
  var SeoPreview_default = SeoPreview;
151
186
 
152
187
  module.exports = SeoPreview_default;
153
- //# sourceMappingURL=SeoPreview-JDROKZLP.cjs.map
154
- //# sourceMappingURL=SeoPreview-JDROKZLP.cjs.map
188
+ //# sourceMappingURL=SeoPreview-LWSWTIF5.cjs.map
189
+ //# sourceMappingURL=SeoPreview-LWSWTIF5.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/SeoPreview.tsx"],"names":["styled","useClient","useState","useEffect","useFormValue","jsx","Box","jsxs","Fragment","truncate"],"mappings":"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","file":"SeoPreview-LWSWTIF5.cjs","sourcesContent":["import {Box} from '@sanity/ui'\nimport {type ReactElement, useEffect, useState} from 'react'\nimport {StringInputProps, useClient, useFormValue} from 'sanity'\nimport styled from 'styled-components'\n\nimport {truncate} from '../utils/seoUtils'\n\nconst PreviewContainer = styled.div`\n max-width: 600px;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n background: #ffffff;\n border: 1px solid #dadce0;\n border-radius: 8px;\n overflow: hidden;\n`\n\nconst PreviewHeader = styled.div`\n background: #f8f9fa;\n padding: 12px 16px;\n border-bottom: 1px solid #dadce0;\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n`\n\nconst PreviewBody = styled.div`\n padding: 16px;\n`\n\nconst SerpUrl = styled.p`\n margin: 0 0 4px;\n color: #006621;\n font-size: 13px;\n line-height: 1.4;\n word-break: break-word;\n`\n\nconst SerpTitle = styled.h3`\n margin: 0 0 8px;\n color: #1a0dab;\n font-size: 18px;\n font-weight: 500;\n line-height: 1.4;\n word-break: break-word;\n\n &:hover {\n text-decoration: underline;\n }\n`\n\nconst SerpDescription = styled.p`\n margin: 0;\n color: #545454;\n font-size: 14px;\n line-height: 1.6;\n word-break: break-word;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n`\n\nconst LiveIndicator = styled.span`\n display: inline-flex;\n align-items: center;\n gap: 4px;\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n color: #4f46e5;\n background: #f0f4ff;\n padding: 4px 8px;\n border-radius: 4px;\n`\n\nconst SeoPreview = (props: StringInputProps): ReactElement => {\n const {path, schemaType} = props\n const {options} = schemaType as {\n options?: {\n baseUrl?: string\n apiVersion?: string\n prefix?: ((doc: {_type?: string} & Record<string, unknown>) => string) | string\n titleSuffix?: ((doc: {_type?: string} & Record<string, unknown>) => string) | string\n titleSuffixInheritColor?: boolean\n titleSuffixQuery?: string\n }\n }\n const baseUrl = options?.baseUrl || 'https://www.example.com'\n const prefixFunction = options?.prefix as\n | ((doc: {_type?: string} & Record<string, unknown>) => string)\n | undefined\n const titleSuffixOption = options?.titleSuffix\n const titleSuffixInheritColor = options?.titleSuffixInheritColor ?? false\n const titleSuffixQuery = options?.titleSuffixQuery\n\n const client = useClient({apiVersion: options?.apiVersion ?? '2024-01-01'})\n const [groqTitleSuffix, setGroqTitleSuffix] = useState<string>('')\n\n useEffect(() => {\n if (!titleSuffixQuery) return\n client\n .fetch<string>(titleSuffixQuery)\n .then((result) => {\n setGroqTitleSuffix(result === null || result === undefined ? '' : String(result))\n })\n .catch(() => {\n setGroqTitleSuffix('')\n })\n }, [titleSuffixQuery, client])\n const parent = useFormValue([path[0]]) || {\n title: '',\n description: '',\n canonicalUrl: '',\n }\n const rootDoc: {\n slug?: {current: string}\n } = useFormValue([]) || {\n slug: {current: ''},\n }\n const slug: string = rootDoc?.slug?.current || ''\n\n const {\n title,\n description,\n canonicalUrl: url,\n } = parent as {\n title?: string\n description?: string\n canonicalUrl?: string\n }\n\n const getTitleSuffix = (): string => {\n if (titleSuffixQuery) return groqTitleSuffix\n if (!titleSuffixOption) return ''\n if (typeof titleSuffixOption === 'function') {\n return titleSuffixOption(rootDoc as {_type?: string} & Record<string, unknown>)\n }\n return titleSuffixOption\n }\n const titleSuffix: string = getTitleSuffix()\n\n // Build full URL\n const base = (url || baseUrl)?.replace(/\\/+$/, '')\n const slugStr = String(slug || '').replace(/^\\/+/, '')\n const pref = String(\n prefixFunction ? prefixFunction(rootDoc as {slug?: {current: string}}) : '',\n ).replace(/^\\/+|\\/+$/g, '')\n const urlPath = [pref, slugStr].filter(Boolean).join('/')\n const finalUrl = urlPath ? `${base}/${urlPath}` : base\n\n // Extract domain for display\n const domain = (() => {\n try {\n const u = new URL(finalUrl || base)\n return u.hostname\n } catch {\n return 'example.com'\n }\n })()\n\n // Format URL display with › separator\n const urlDisplay = `${domain}${urlPath ? ` › ${urlPath.split('/').slice(-1)[0]}` : ''}`\n\n return (\n <Box padding={3}>\n <PreviewContainer>\n <PreviewHeader>\n <span\n style={{\n fontSize: '11px',\n color: '#5f6368',\n textTransform: 'uppercase',\n letterSpacing: '0.05em',\n }}\n >\n Search Preview\n </span>\n <LiveIndicator>\n <span\n style={{\n width: '4px',\n height: '4px',\n borderRadius: '50%',\n backgroundColor: '#4f46e5',\n display: 'inline-block',\n }}\n />\n Live\n </LiveIndicator>\n </PreviewHeader>\n\n <PreviewBody>\n <SerpUrl>{finalUrl ? urlDisplay : 'example.com › page-url'}</SerpUrl>\n <SerpTitle>\n {title && title.length > 0 ? (\n <>\n {truncate(title, Math.max(1, 60 - titleSuffix.length))}\n {titleSuffix && (\n <span\n style={\n titleSuffixInheritColor ? undefined : {color: '#70757a', fontWeight: 400}\n }\n >\n | {titleSuffix}\n </span>\n )}\n </>\n ) : (\n 'Your SEO Title will appear here'\n )}\n </SerpTitle>\n <SerpDescription>\n {description && description.length > 0\n ? truncate(description, 160)\n : 'Your meta description will show up here. Make it compelling!'}\n </SerpDescription>\n </PreviewBody>\n </PreviewContainer>\n </Box>\n )\n}\n\nexport default SeoPreview\n"]}
@@ -769,7 +769,12 @@ var MonitorIcon = () => /* @__PURE__ */ jsxRuntime.jsxs(
769
769
  ]
770
770
  }
771
771
  );
772
- var DocTitleAnchor = ({ id, type, structureTool, children }) => {
772
+ var DocTitleAnchor = ({
773
+ id,
774
+ type,
775
+ structureTool,
776
+ children
777
+ }) => {
773
778
  const { basePath } = sanity.useWorkspace();
774
779
  const { onClick: intentOnClick, href: intentHref } = router.useIntentLink({
775
780
  intent: "edit",
@@ -809,7 +814,10 @@ var DocTitleAnchorPane = ({
809
814
  const { ChildLink } = structure.usePaneRouter();
810
815
  return /* @__PURE__ */ jsxRuntime.jsx(PaneLinkWrapper, { children: /* @__PURE__ */ jsxRuntime.jsx(ChildLink, { childId: id, childParameters: { type }, children }) });
811
816
  };
812
- var DocBadgeRenderer = ({ doc, docBadge }) => {
817
+ var DocBadgeRenderer = ({
818
+ doc,
819
+ docBadge
820
+ }) => {
813
821
  const badge = docBadge(doc);
814
822
  if (!badge) return null;
815
823
  return /* @__PURE__ */ jsxRuntime.jsx(CustomBadge, { $bgColor: badge.bgColor, $textColor: badge.textColor, $fontSize: badge.fontSize, children: badge.label });
@@ -2039,5 +2047,5 @@ var SeoHealthDashboard = ({
2039
2047
  var SeoHealthDashboard_default = SeoHealthDashboard;
2040
2048
 
2041
2049
  exports.SeoHealthDashboard_default = SeoHealthDashboard_default;
2042
- //# sourceMappingURL=chunk-Z74QPO75.cjs.map
2043
- //# sourceMappingURL=chunk-Z74QPO75.cjs.map
2050
+ //# sourceMappingURL=chunk-77U7CMJP.cjs.map
2051
+ //# sourceMappingURL=chunk-77U7CMJP.cjs.map