sanity-plugin-seofields 1.9.0 → 1.10.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.
- package/README.md +71 -0
- package/dist/{SeoPreview-LMZAWWOE.cjs → SeoPreview-A2XZVMT2.cjs} +4 -4
- package/dist/{SeoPreview-LMZAWWOE.cjs.map → SeoPreview-A2XZVMT2.cjs.map} +1 -1
- package/dist/{SeoPreview-UNQBKTQO.js → SeoPreview-TATJQFMP.js} +2 -2
- package/dist/chunk-CRCXC45D.js +56 -0
- package/dist/chunk-CRCXC45D.js.map +1 -0
- package/dist/{chunk-HHO2AKAP.js → chunk-DB5MBPRK.js} +13 -13
- package/dist/chunk-DB5MBPRK.js.map +1 -0
- package/dist/{chunk-3OK3S2F7.cjs → chunk-EUG4MNRC.cjs} +60 -20
- package/dist/chunk-EUG4MNRC.cjs.map +1 -0
- package/dist/{chunk-Y46ACXM4.cjs → chunk-LHUFL5LS.cjs} +13 -13
- package/dist/chunk-LHUFL5LS.cjs.map +1 -0
- package/dist/{chunk-Z5AOUU4H.js → chunk-NLEB47UV.js} +60 -20
- package/dist/chunk-NLEB47UV.js.map +1 -0
- package/dist/{chunk-FUUWBQE2.cjs → chunk-OULUDJPI.cjs} +66 -7
- package/dist/chunk-OULUDJPI.cjs.map +1 -0
- package/dist/{chunk-KIEO6QG3.js → chunk-XD4HKLEA.js} +66 -7
- package/dist/chunk-XD4HKLEA.js.map +1 -0
- package/dist/chunk-XYAZJ3WX.cjs +56 -0
- package/dist/chunk-XYAZJ3WX.cjs.map +1 -0
- package/dist/cli.js +1 -1
- package/dist/head.cjs +10 -2
- package/dist/head.cjs.map +1 -1
- package/dist/head.d.cts +61 -1
- package/dist/head.d.ts +61 -1
- package/dist/head.js +9 -1
- package/dist/hreflang-_VbSuWYD.d.cts +29 -0
- package/dist/hreflang-_VbSuWYD.d.ts +29 -0
- package/dist/index.cjs +173 -38
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -2
- package/dist/index.d.ts +3 -2
- package/dist/index.js +336 -201
- package/dist/index.js.map +1 -1
- package/dist/next.cjs +11 -3
- package/dist/next.cjs.map +1 -1
- package/dist/next.d.cts +2 -1
- package/dist/next.d.ts +2 -1
- package/dist/next.js +9 -1
- package/dist/next.js.map +1 -1
- package/dist/{plugin-DoGeZP79.d.cts → plugin-HFuWZsJu.d.cts} +68 -1
- package/dist/{plugin-DQdThyxG.d.ts → plugin-oQUCim56.d.ts} +68 -1
- package/dist/server.cjs +2 -2
- package/dist/server.cjs.map +1 -1
- package/dist/server.d.cts +6 -8
- package/dist/server.d.ts +6 -8
- package/dist/server.js +1 -1
- package/dist/server.js.map +1 -1
- package/package.json +2 -2
- package/dist/chunk-3OK3S2F7.cjs.map +0 -1
- package/dist/chunk-FUUWBQE2.cjs.map +0 -1
- package/dist/chunk-HHO2AKAP.js.map +0 -1
- package/dist/chunk-KIEO6QG3.js.map +0 -1
- package/dist/chunk-Y46ACXM4.cjs.map +0 -1
- package/dist/chunk-Z5AOUU4H.js.map +0 -1
- /package/dist/{SeoPreview-UNQBKTQO.js.map → SeoPreview-TATJQFMP.js.map} +0 -0
package/dist/next.cjs
CHANGED
|
@@ -3,7 +3,12 @@
|
|
|
3
3
|
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
var _chunkOULUDJPIcjs = require('./chunk-OULUDJPI.cjs');
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
var _chunkXYAZJ3WXcjs = require('./chunk-XYAZJ3WX.cjs');
|
|
7
12
|
|
|
8
13
|
|
|
9
14
|
|
|
@@ -100,7 +105,7 @@ function SeoMetaTags({
|
|
|
100
105
|
imageUrlResolver
|
|
101
106
|
}) {
|
|
102
107
|
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t;
|
|
103
|
-
const meta =
|
|
108
|
+
const meta = _chunkOULUDJPIcjs.buildSeoMeta.call(void 0, { seo: data, baseUrl, path, defaults, imageUrlResolver });
|
|
104
109
|
const robotsContent = [
|
|
105
110
|
((_a = meta.robots) == null ? void 0 : _a.index) === false ? "noindex" : "index",
|
|
106
111
|
((_b = meta.robots) == null ? void 0 : _b.follow) === false ? "nofollow" : "follow",
|
|
@@ -222,5 +227,8 @@ function SeoMetaTags({
|
|
|
222
227
|
|
|
223
228
|
|
|
224
229
|
|
|
225
|
-
|
|
230
|
+
|
|
231
|
+
|
|
232
|
+
|
|
233
|
+
exports.AggregateRatingSchema = _chunkR2U7JF7Ucjs.AggregateRatingSchema; exports.ArticleSchema = _chunkR2U7JF7Ucjs.ArticleSchema; exports.BlogPostingSchema = _chunkR2U7JF7Ucjs.BlogPostingSchema; exports.BookSchema = _chunkR2U7JF7Ucjs.BookSchema; exports.BrandSchema = _chunkR2U7JF7Ucjs.BrandSchema; exports.BreadcrumbListSchema = _chunkR2U7JF7Ucjs.BreadcrumbListSchema; exports.ContactPointSchema = _chunkR2U7JF7Ucjs.ContactPointSchema; exports.CountrySchema = _chunkR2U7JF7Ucjs.CountrySchema; exports.CourseSchema = _chunkR2U7JF7Ucjs.CourseSchema; exports.EventSchema = _chunkR2U7JF7Ucjs.EventSchema; exports.FAQPageSchema = _chunkR2U7JF7Ucjs.FAQPageSchema; exports.HowToSchema = _chunkR2U7JF7Ucjs.HowToSchema; exports.ImageObjectSchema = _chunkR2U7JF7Ucjs.ImageObjectSchema; exports.ItemListSchema = _chunkR2U7JF7Ucjs.ItemListSchema; exports.JobPostingSchema = _chunkR2U7JF7Ucjs.JobPostingSchema; exports.LegalServiceSchema = _chunkR2U7JF7Ucjs.LegalServiceSchema; exports.LocalBusinessSchema = _chunkR2U7JF7Ucjs.LocalBusinessSchema; exports.MovieSchema = _chunkR2U7JF7Ucjs.MovieSchema; exports.MusicAlbumSchema = _chunkR2U7JF7Ucjs.MusicAlbumSchema; exports.MusicRecordingSchema = _chunkR2U7JF7Ucjs.MusicRecordingSchema; exports.NewsArticleSchema = _chunkR2U7JF7Ucjs.NewsArticleSchema; exports.OfferSchema = _chunkR2U7JF7Ucjs.OfferSchema; exports.OpinionNewsArticleSchema = _chunkR2U7JF7Ucjs.OpinionNewsArticleSchema; exports.OrganizationSchema = _chunk5XTQRILLcjs.OrganizationSchema; exports.PersonSchema = _chunkR2U7JF7Ucjs.PersonSchema; exports.PlaceSchema = _chunkR2U7JF7Ucjs.PlaceSchema; exports.PostalAddressSchema = _chunkR2U7JF7Ucjs.PostalAddressSchema; exports.ProductSchema = _chunkR2U7JF7Ucjs.ProductSchema; exports.ProfilePageSchema = _chunkR2U7JF7Ucjs.ProfilePageSchema; exports.RecipeSchema = _chunkR2U7JF7Ucjs.RecipeSchema; exports.RestaurantSchema = _chunkR2U7JF7Ucjs.RestaurantSchema; exports.ReviewSchema = _chunkR2U7JF7Ucjs.ReviewSchema; exports.SchemaOrgScripts = _chunk5XTQRILLcjs.SchemaOrgScripts; exports.SeoMetaTags = SeoMetaTags; exports.ServiceSchema = _chunkR2U7JF7Ucjs.ServiceSchema; exports.SoftwareApplicationSchema = _chunkR2U7JF7Ucjs.SoftwareApplicationSchema; exports.VideoObjectSchema = _chunkR2U7JF7Ucjs.VideoObjectSchema; exports.WebApplicationSchema = _chunkR2U7JF7Ucjs.WebApplicationSchema; exports.WebPageSchema = _chunkR2U7JF7Ucjs.WebPageSchema; exports.WebsiteSchema = _chunk5XTQRILLcjs.WebsiteSchema; exports.buildAggregateRatingJsonLd = _chunkR2U7JF7Ucjs.buildAggregateRatingJsonLd; exports.buildArticleJsonLd = _chunkR2U7JF7Ucjs.buildArticleJsonLd; exports.buildBlogPostingJsonLd = _chunkR2U7JF7Ucjs.buildBlogPostingJsonLd; exports.buildBookJsonLd = _chunkR2U7JF7Ucjs.buildBookJsonLd; exports.buildBrandJsonLd = _chunkR2U7JF7Ucjs.buildBrandJsonLd; exports.buildBreadcrumbListJsonLd = _chunkR2U7JF7Ucjs.buildBreadcrumbListJsonLd; exports.buildContactPointJsonLd = _chunkR2U7JF7Ucjs.buildContactPointJsonLd; exports.buildCountryJsonLd = _chunkR2U7JF7Ucjs.buildCountryJsonLd; exports.buildCourseJsonLd = _chunkR2U7JF7Ucjs.buildCourseJsonLd; exports.buildEventJsonLd = _chunkR2U7JF7Ucjs.buildEventJsonLd; exports.buildFAQPageJsonLd = _chunkR2U7JF7Ucjs.buildFAQPageJsonLd; exports.buildHowToJsonLd = _chunkR2U7JF7Ucjs.buildHowToJsonLd; exports.buildHreflangs = _chunkXYAZJ3WXcjs.buildHreflangs; exports.buildImageObjectJsonLd = _chunkR2U7JF7Ucjs.buildImageObjectJsonLd; exports.buildItemListJsonLd = _chunkR2U7JF7Ucjs.buildItemListJsonLd; exports.buildJobPostingJsonLd = _chunkR2U7JF7Ucjs.buildJobPostingJsonLd; exports.buildLegalServiceJsonLd = _chunkR2U7JF7Ucjs.buildLegalServiceJsonLd; exports.buildLlmsTxt = _chunkOULUDJPIcjs.buildLlmsTxt; exports.buildLocalBusinessJsonLd = _chunkR2U7JF7Ucjs.buildLocalBusinessJsonLd; exports.buildMovieJsonLd = _chunkR2U7JF7Ucjs.buildMovieJsonLd; exports.buildMusicAlbumJsonLd = _chunkR2U7JF7Ucjs.buildMusicAlbumJsonLd; exports.buildMusicRecordingJsonLd = _chunkR2U7JF7Ucjs.buildMusicRecordingJsonLd; exports.buildNewsArticleJsonLd = _chunkR2U7JF7Ucjs.buildNewsArticleJsonLd; exports.buildOfferJsonLd = _chunkR2U7JF7Ucjs.buildOfferJsonLd; exports.buildOpinionNewsArticleJsonLd = _chunkR2U7JF7Ucjs.buildOpinionNewsArticleJsonLd; exports.buildOrganizationJsonLd = _chunk5XTQRILLcjs.buildOrganizationJsonLd; exports.buildPersonJsonLd = _chunkR2U7JF7Ucjs.buildPersonJsonLd; exports.buildPlaceJsonLd = _chunkR2U7JF7Ucjs.buildPlaceJsonLd; exports.buildPostalAddressJsonLd = _chunkR2U7JF7Ucjs.buildPostalAddressJsonLd; exports.buildProductJsonLd = _chunkR2U7JF7Ucjs.buildProductJsonLd; exports.buildProfilePageJsonLd = _chunkR2U7JF7Ucjs.buildProfilePageJsonLd; exports.buildRecipeJsonLd = _chunkR2U7JF7Ucjs.buildRecipeJsonLd; exports.buildRestaurantJsonLd = _chunkR2U7JF7Ucjs.buildRestaurantJsonLd; exports.buildReviewJsonLd = _chunkR2U7JF7Ucjs.buildReviewJsonLd; exports.buildSchemaOrgJsonLd = _chunk5XTQRILLcjs.buildSchemaOrgJsonLd; exports.buildSchemaOrgJsonLds = _chunk5XTQRILLcjs.buildSchemaOrgJsonLds; exports.buildSeoHead = _chunkOULUDJPIcjs.buildSeoHead; exports.buildSeoMeta = _chunkOULUDJPIcjs.buildSeoMeta; exports.buildServiceJsonLd = _chunkR2U7JF7Ucjs.buildServiceJsonLd; exports.buildSoftwareApplicationJsonLd = _chunkR2U7JF7Ucjs.buildSoftwareApplicationJsonLd; exports.buildVideoObjectJsonLd = _chunkR2U7JF7Ucjs.buildVideoObjectJsonLd; exports.buildWebApplicationJsonLd = _chunkR2U7JF7Ucjs.buildWebApplicationJsonLd; exports.buildWebPageJsonLd = _chunkR2U7JF7Ucjs.buildWebPageJsonLd; exports.buildWebsiteJsonLd = _chunk5XTQRILLcjs.buildWebsiteJsonLd; exports.docsToLlmsSection = _chunkOULUDJPIcjs.docsToLlmsSection; exports.sanitizeOGType = _chunkOULUDJPIcjs.sanitizeOGType; exports.sanitizeTwitterCard = _chunkOULUDJPIcjs.sanitizeTwitterCard;
|
|
226
234
|
//# sourceMappingURL=next.cjs.map
|
package/dist/next.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/hardik/GITHUB/sanity-plugin-seofields/npm/dist/next.cjs","../src/helpers/SeoMetaTags.tsx"],"names":["Fragment"],"mappings":"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,OAAA,mBAAU,6BAAA,MAAC,EAAA,EAAK,QAAA,EAAS,iBAAA,EAAkB,OAAA,EAAS,MAAA,CAAO,GAAA,CAAI,MAAM,EAAA,CAAG,CAAA;AAAA,QAC5E,GAAA,CAAI,IAAA,mBAAO,6BAAA,MAAC,EAAA,EAAK,QAAA,EAAS,cAAA,EAAe,OAAA,EAAS,GAAA,CAAI,IAAA,CAAK;AAAA,MAAA,EAAA,CAAA,EAJ/C,CAAA,OAAA,EAAU,CAAC,CAAA,CAAA;AAK1B,IAAA;AAII,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AAGA,IAAA;AAMJ,IAAA;AAKI,IAAA;AACR,EAAA;AAEJ;ADvBuB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA","file":"/Users/hardik/GITHUB/sanity-plugin-seofields/npm/dist/next.cjs","sourcesContent":[null,"/**\n * <SeoMetaTags> — Framework-agnostic React SEO meta tag renderer.\n *\n * Renders all SEO meta tags as plain React elements.\n * Place it inside your framework's <Head> component:\n *\n * @example Next.js Pages Router\n * ```tsx\n * import Head from 'next/head'\n * import { SeoMetaTags } from 'sanity-plugin-seofields/next'\n *\n * export default function Page({ seo }) {\n * return (\n * <>\n * <Head>\n * <SeoMetaTags\n * data={seo}\n * baseUrl=\"https://example.com\"\n * path=\"/about\"\n * defaults={{ title: 'My Site', siteName: 'My Site' }}\n * imageUrlResolver={(img) => urlFor(img).width(1200).url()}\n * />\n * </Head>\n * <main>...</main>\n * </>\n * )\n * }\n * ```\n *\n * @example React SSR (inside a framework <Head> slot)\n * ```tsx\n * <Head>\n * <SeoMetaTags data={seo} baseUrl=\"https://example.com\" path=\"/\" />\n * </Head>\n * ```\n */\nimport {Fragment, type JSX} from 'react'\n\nimport type {SanityImage, SanityImageWithAlt, SeoFields} from '../types'\nimport {buildSeoMeta, type BuildSeoMetaOptions} from './seoMeta'\n\n// ─── Props ────────────────────────────────────────────────────────────────────\n\nexport interface SeoMetaTagsProps {\n /**\n * The raw SEO object from Sanity.\n * Pass `null` / `undefined` to render only the defaults.\n */\n data?: Partial<SeoFields> | null\n\n /**\n * Base URL of your site, e.g. \"https://example.com\".\n * Used for canonical link, og:url fallback.\n */\n baseUrl?: string\n\n /**\n * Current page path, e.g. \"/about\".\n * Defaults to \"\".\n */\n path?: string\n\n /**\n * Default values used when SEO fields are missing.\n */\n defaults?: BuildSeoMetaOptions['defaults']\n\n /**\n * Resolve a Sanity image asset reference to a full URL string.\n *\n * @example\n * imageUrlResolver={(img) => urlFor(img).width(1200).url()}\n */\n imageUrlResolver?: (image: SanityImage | SanityImageWithAlt) => string | null | undefined\n}\n\n// ─── Component ────────────────────────────────────────────────────────────────\n\n/**\n * Renders all SEO meta tags for a page as plain React elements.\n * Intended to be placed inside your framework's <Head> / <head> component.\n *\n * Renders:\n * - `<title>`\n * - `<meta name=\"description\">`\n * - `<meta name=\"keywords\">`\n * - `<meta name=\"robots\">`\n * - OpenGraph meta tags (`og:*`)\n * - Twitter Card meta tags (`twitter:*`)\n * - Any custom `seo.metaAttributes` as `<meta name=\"...\" content=\"...\">`\n */\nexport function SeoMetaTags({\n data,\n baseUrl,\n path,\n defaults,\n imageUrlResolver,\n}: SeoMetaTagsProps): JSX.Element {\n const meta = buildSeoMeta({seo: data, baseUrl, path, defaults, imageUrlResolver})\n\n const robotsContent = [\n meta.robots?.index === false ? 'noindex' : 'index',\n meta.robots?.follow === false ? 'nofollow' : 'follow',\n meta.robots?.notranslate ? 'notranslate' : null,\n meta.robots?.noimageindex ? 'noimageindex' : null,\n ]\n .filter(Boolean)\n .join(', ')\n\n return (\n <>\n {/* ── Title ── */}\n {meta.title && <title>{meta.title}</title>}\n\n {/* ── Basic meta ── */}\n {meta.description && <meta name=\"description\" content={meta.description} />}\n {meta.keywords?.length ? <meta name=\"keywords\" content={meta.keywords.join(', ')} /> : null}\n <meta name=\"robots\" content={robotsContent} />\n <meta name=\"googlebot\" content={robotsContent} />\n\n {/* ── Open Graph ── */}\n {meta.openGraph?.type && <meta property=\"og:type\" content={meta.openGraph.type} />}\n {meta.openGraph?.url && <meta property=\"og:url\" content={meta.openGraph.url} />}\n {meta.openGraph?.title && <meta property=\"og:title\" content={meta.openGraph.title} />}\n {meta.openGraph?.description && (\n <meta property=\"og:description\" content={meta.openGraph.description} />\n )}\n {meta.openGraph?.siteName && (\n <meta property=\"og:site_name\" content={meta.openGraph.siteName} />\n )}\n {meta.openGraph?.images?.map((img, i) => (\n // eslint-disable-next-line react/no-array-index-key\n <Fragment key={`og-img-${i}`}>\n <meta property=\"og:image\" content={img.url} />\n {img.width && <meta property=\"og:image:width\" content={String(img.width)} />}\n {img.height && <meta property=\"og:image:height\" content={String(img.height)} />}\n {img.alt && <meta property=\"og:image:alt\" content={img.alt} />}\n </Fragment>\n ))}\n\n {/* ── Twitter Card ── */}\n {meta.twitter?.card && <meta name=\"twitter:card\" content={meta.twitter.card} />}\n {meta.twitter?.site && <meta name=\"twitter:site\" content={meta.twitter.site} />}\n {meta.twitter?.creator && <meta name=\"twitter:creator\" content={meta.twitter.creator} />}\n {meta.twitter?.title && <meta name=\"twitter:title\" content={meta.twitter.title} />}\n {meta.twitter?.description && (\n <meta name=\"twitter:description\" content={meta.twitter.description} />\n )}\n {meta.twitter?.images?.map((url, i) => (\n <meta key={`tw-img-${i}`} name=\"twitter:image\" content={url} />\n ))}\n\n {/* ── Custom meta attributes ── */}\n {meta.other &&\n Object.entries(meta.other).map(([name, content]) => (\n <meta key={`custom-${name}`} name={name} content={content} />\n ))}\n\n {/* ── Canonical URL ── */}\n {meta.alternates?.canonical && <link rel=\"canonical\" href={meta.alternates.canonical} />}\n </>\n )\n}\n\nexport default SeoMetaTags\n"]}
|
|
1
|
+
{"version":3,"sources":["/Users/hardik/GITHUB/sanity-plugin-seofields/npm/dist/next.cjs","../src/helpers/SeoMetaTags.tsx"],"names":["Fragment"],"mappings":"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AA,CAAG,CAAA;AAAA,QACzE,GAAA,CAAI,OAAA,mBAAU,6BAAA,MAAC,EAAA,EAAK,QAAA,EAAS,iBAAA,EAAkB,OAAA,EAAS,MAAA,CAAO,GAAA,CAAI,MAAM,EAAA,CAAG,CAAA;AAAA,QAC5E,GAAA,CAAI,IAAA,mBAAO,6BAAA,MAAC,EAAA,EAAK,QAAA,EAAS,cAAA,EAAe,OAAA,EAAS,GAAA,CAAI,IAAA,CAAK;AAAA,MAAA,EAAA,CAAA,EAJ/C,CAAA,OAAA,EAAU,CAAC,CAAA,CAAA;AAK1B,IAAA;AAII,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AAGA,IAAA;AAMJ,IAAA;AAKI,IAAA;AACR,EAAA;AAEJ;ADlBuB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA","file":"/Users/hardik/GITHUB/sanity-plugin-seofields/npm/dist/next.cjs","sourcesContent":[null,"/**\n * <SeoMetaTags> — Framework-agnostic React SEO meta tag renderer.\n *\n * Renders all SEO meta tags as plain React elements.\n * Place it inside your framework's <Head> component:\n *\n * @example Next.js Pages Router\n * ```tsx\n * import Head from 'next/head'\n * import { SeoMetaTags } from 'sanity-plugin-seofields/next'\n *\n * export default function Page({ seo }) {\n * return (\n * <>\n * <Head>\n * <SeoMetaTags\n * data={seo}\n * baseUrl=\"https://example.com\"\n * path=\"/about\"\n * defaults={{ title: 'My Site', siteName: 'My Site' }}\n * imageUrlResolver={(img) => urlFor(img).width(1200).url()}\n * />\n * </Head>\n * <main>...</main>\n * </>\n * )\n * }\n * ```\n *\n * @example React SSR (inside a framework <Head> slot)\n * ```tsx\n * <Head>\n * <SeoMetaTags data={seo} baseUrl=\"https://example.com\" path=\"/\" />\n * </Head>\n * ```\n */\nimport {Fragment, type JSX} from 'react'\n\nimport type {SanityImage, SanityImageWithAlt, SeoFields} from '../types'\nimport {buildSeoMeta, type BuildSeoMetaOptions} from './seoMeta'\n\n// ─── Props ────────────────────────────────────────────────────────────────────\n\nexport interface SeoMetaTagsProps {\n /**\n * The raw SEO object from Sanity.\n * Pass `null` / `undefined` to render only the defaults.\n */\n data?: Partial<SeoFields> | null\n\n /**\n * Base URL of your site, e.g. \"https://example.com\".\n * Used for canonical link, og:url fallback.\n */\n baseUrl?: string\n\n /**\n * Current page path, e.g. \"/about\".\n * Defaults to \"\".\n */\n path?: string\n\n /**\n * Default values used when SEO fields are missing.\n */\n defaults?: BuildSeoMetaOptions['defaults']\n\n /**\n * Resolve a Sanity image asset reference to a full URL string.\n *\n * @example\n * imageUrlResolver={(img) => urlFor(img).width(1200).url()}\n */\n imageUrlResolver?: (image: SanityImage | SanityImageWithAlt) => string | null | undefined\n}\n\n// ─── Component ────────────────────────────────────────────────────────────────\n\n/**\n * Renders all SEO meta tags for a page as plain React elements.\n * Intended to be placed inside your framework's <Head> / <head> component.\n *\n * Renders:\n * - `<title>`\n * - `<meta name=\"description\">`\n * - `<meta name=\"keywords\">`\n * - `<meta name=\"robots\">`\n * - OpenGraph meta tags (`og:*`)\n * - Twitter Card meta tags (`twitter:*`)\n * - Any custom `seo.metaAttributes` as `<meta name=\"...\" content=\"...\">`\n */\nexport function SeoMetaTags({\n data,\n baseUrl,\n path,\n defaults,\n imageUrlResolver,\n}: SeoMetaTagsProps): JSX.Element {\n const meta = buildSeoMeta({seo: data, baseUrl, path, defaults, imageUrlResolver})\n\n const robotsContent = [\n meta.robots?.index === false ? 'noindex' : 'index',\n meta.robots?.follow === false ? 'nofollow' : 'follow',\n meta.robots?.notranslate ? 'notranslate' : null,\n meta.robots?.noimageindex ? 'noimageindex' : null,\n ]\n .filter(Boolean)\n .join(', ')\n\n return (\n <>\n {/* ── Title ── */}\n {meta.title && <title>{meta.title}</title>}\n\n {/* ── Basic meta ── */}\n {meta.description && <meta name=\"description\" content={meta.description} />}\n {meta.keywords?.length ? <meta name=\"keywords\" content={meta.keywords.join(', ')} /> : null}\n <meta name=\"robots\" content={robotsContent} />\n <meta name=\"googlebot\" content={robotsContent} />\n\n {/* ── Open Graph ── */}\n {meta.openGraph?.type && <meta property=\"og:type\" content={meta.openGraph.type} />}\n {meta.openGraph?.url && <meta property=\"og:url\" content={meta.openGraph.url} />}\n {meta.openGraph?.title && <meta property=\"og:title\" content={meta.openGraph.title} />}\n {meta.openGraph?.description && (\n <meta property=\"og:description\" content={meta.openGraph.description} />\n )}\n {meta.openGraph?.siteName && (\n <meta property=\"og:site_name\" content={meta.openGraph.siteName} />\n )}\n {meta.openGraph?.images?.map((img, i) => (\n // eslint-disable-next-line react/no-array-index-key\n <Fragment key={`og-img-${i}`}>\n <meta property=\"og:image\" content={img.url} />\n {img.width && <meta property=\"og:image:width\" content={String(img.width)} />}\n {img.height && <meta property=\"og:image:height\" content={String(img.height)} />}\n {img.alt && <meta property=\"og:image:alt\" content={img.alt} />}\n </Fragment>\n ))}\n\n {/* ── Twitter Card ── */}\n {meta.twitter?.card && <meta name=\"twitter:card\" content={meta.twitter.card} />}\n {meta.twitter?.site && <meta name=\"twitter:site\" content={meta.twitter.site} />}\n {meta.twitter?.creator && <meta name=\"twitter:creator\" content={meta.twitter.creator} />}\n {meta.twitter?.title && <meta name=\"twitter:title\" content={meta.twitter.title} />}\n {meta.twitter?.description && (\n <meta name=\"twitter:description\" content={meta.twitter.description} />\n )}\n {meta.twitter?.images?.map((url, i) => (\n <meta key={`tw-img-${i}`} name=\"twitter:image\" content={url} />\n ))}\n\n {/* ── Custom meta attributes ── */}\n {meta.other &&\n Object.entries(meta.other).map(([name, content]) => (\n <meta key={`custom-${name}`} name={name} content={content} />\n ))}\n\n {/* ── Canonical URL ── */}\n {meta.alternates?.canonical && <link rel=\"canonical\" href={meta.alternates.canonical} />}\n </>\n )\n}\n\nexport default SeoMetaTags\n"]}
|
package/dist/next.d.cts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { BuildSeoMetaOptions } from './head.cjs';
|
|
2
|
-
export { SeoFieldsInput, SeoHead, SeoHeadLinkTag, SeoHeadMetaTag, SeoMetaDefaults, SeoMetadata, buildSeoHead, buildSeoMeta, sanitizeOGType, sanitizeTwitterCard } from './head.cjs';
|
|
2
|
+
export { BuildLlmsTxtOptions, DocsToLlmsSectionOptions, LlmsDoc, LlmsLink, LlmsSection, SeoFieldsInput, SeoHead, SeoHeadLinkTag, SeoHeadMetaTag, SeoMetaDefaults, SeoMetadata, buildLlmsTxt, buildSeoHead, buildSeoMeta, docsToLlmsSection, sanitizeOGType, sanitizeTwitterCard } from './head.cjs';
|
|
3
3
|
import { JSX } from 'react';
|
|
4
4
|
import { S as SeoFields, a as SanityImage, b as SanityImageWithAlt } from './types-DxlPXihz.cjs';
|
|
5
|
+
export { B as BuildHreflangsOptions, H as HreflangLinkEntry, a as HreflangTranslation, b as buildHreflangs } from './hreflang-_VbSuWYD.cjs';
|
|
5
6
|
export { S as SchemaOrgScripts, a as SchemaOrgScriptsProps, b as buildSchemaOrgJsonLd, c as buildSchemaOrgJsonLds } from './types-DP-DiW6f.cjs';
|
|
6
7
|
export { A as AggregateRatingSchema, a as AggregateRatingSchemaProps, b as ArticleSchema, c as ArticleSchemaProps, B as BlogPostingSchema, d as BlogPostingSchemaProps, e as BookSchema, f as BookSchemaProps, g as BrandSchema, h as BrandSchemaProps, i as BreadcrumbListSchema, j as BreadcrumbListSchemaProps, C as ContactPointSchema, k as ContactPointSchemaProps, l as CountrySchema, m as CountrySchemaProps, n as CourseSchema, o as CourseSchemaProps, E as EventSchema, p as EventSchemaProps, F as FAQPageSchema, q as FAQPageSchemaProps, H as HowToSchema, r as HowToSchemaProps, I as ImageObjectSchema, s as ImageObjectSchemaProps, t as ItemListSchema, u as ItemListSchemaProps, J as JobPostingSchema, v as JobPostingSchemaProps, L as LegalServiceSchema, w as LegalServiceSchemaProps, x as LocalBusinessSchema, y as LocalBusinessSchemaProps, M as MovieSchema, z as MovieSchemaProps, D as MusicAlbumSchema, G as MusicAlbumSchemaProps, K as MusicRecordingSchema, N as MusicRecordingSchemaProps, O as NewsArticleSchema, P as NewsArticleSchemaProps, Q as OfferSchema, R as OfferSchemaProps, S as OpinionNewsArticleSchema, T as OpinionNewsArticleSchemaProps, U as OrganizationSchema, V as OrganizationSchemaProps, W as PersonSchema, X as PersonSchemaProps, Y as PlaceSchema, Z as PlaceSchemaProps, _ as PostalAddressSchema, $ as PostalAddressSchemaProps, a0 as ProductSchema, a1 as ProductSchemaProps, a2 as ProfilePageSchema, a3 as ProfilePageSchemaProps, a4 as RecipeSchema, a5 as RecipeSchemaProps, a6 as RestaurantSchema, a7 as RestaurantSchemaProps, a8 as ReviewSchema, a9 as ReviewSchemaProps, aa as ServiceSchema, ab as ServiceSchemaProps, ac as SoftwareApplicationSchema, ad as SoftwareApplicationSchemaProps, ae as VideoObjectSchema, af as VideoObjectSchemaProps, ag as WebApplicationSchema, ah as WebApplicationSchemaProps, ai as WebPageSchema, aj as WebPageSchemaProps, ak as WebsiteSchema, al as WebsiteSchemaProps, am as buildAggregateRatingJsonLd, an as buildArticleJsonLd, ao as buildBlogPostingJsonLd, ap as buildBookJsonLd, aq as buildBrandJsonLd, ar as buildBreadcrumbListJsonLd, as as buildContactPointJsonLd, at as buildCountryJsonLd, au as buildCourseJsonLd, av as buildEventJsonLd, aw as buildFAQPageJsonLd, ax as buildHowToJsonLd, ay as buildImageObjectJsonLd, az as buildItemListJsonLd, aA as buildJobPostingJsonLd, aB as buildLegalServiceJsonLd, aC as buildLocalBusinessJsonLd, aD as buildMovieJsonLd, aE as buildMusicAlbumJsonLd, aF as buildMusicRecordingJsonLd, aG as buildNewsArticleJsonLd, aH as buildOfferJsonLd, aI as buildOpinionNewsArticleJsonLd, aJ as buildOrganizationJsonLd, aK as buildPersonJsonLd, aL as buildPlaceJsonLd, aM as buildPostalAddressJsonLd, aN as buildProductJsonLd, aO as buildProfilePageJsonLd, aP as buildRecipeJsonLd, aQ as buildRestaurantJsonLd, aR as buildReviewJsonLd, aS as buildServiceJsonLd, aT as buildSoftwareApplicationJsonLd, aU as buildVideoObjectJsonLd, aV as buildWebApplicationJsonLd, aW as buildWebPageJsonLd, aX as buildWebsiteJsonLd } from './component-WYh0z8as.cjs';
|
|
7
8
|
|
package/dist/next.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { BuildSeoMetaOptions } from './head.js';
|
|
2
|
-
export { SeoFieldsInput, SeoHead, SeoHeadLinkTag, SeoHeadMetaTag, SeoMetaDefaults, SeoMetadata, buildSeoHead, buildSeoMeta, sanitizeOGType, sanitizeTwitterCard } from './head.js';
|
|
2
|
+
export { BuildLlmsTxtOptions, DocsToLlmsSectionOptions, LlmsDoc, LlmsLink, LlmsSection, SeoFieldsInput, SeoHead, SeoHeadLinkTag, SeoHeadMetaTag, SeoMetaDefaults, SeoMetadata, buildLlmsTxt, buildSeoHead, buildSeoMeta, docsToLlmsSection, sanitizeOGType, sanitizeTwitterCard } from './head.js';
|
|
3
3
|
import { JSX } from 'react';
|
|
4
4
|
import { S as SeoFields, a as SanityImage, b as SanityImageWithAlt } from './types-DxlPXihz.js';
|
|
5
|
+
export { B as BuildHreflangsOptions, H as HreflangLinkEntry, a as HreflangTranslation, b as buildHreflangs } from './hreflang-_VbSuWYD.js';
|
|
5
6
|
export { S as SchemaOrgScripts, a as SchemaOrgScriptsProps, b as buildSchemaOrgJsonLd, c as buildSchemaOrgJsonLds } from './types-DRLUGLtX.js';
|
|
6
7
|
export { A as AggregateRatingSchema, a as AggregateRatingSchemaProps, b as ArticleSchema, c as ArticleSchemaProps, B as BlogPostingSchema, d as BlogPostingSchemaProps, e as BookSchema, f as BookSchemaProps, g as BrandSchema, h as BrandSchemaProps, i as BreadcrumbListSchema, j as BreadcrumbListSchemaProps, C as ContactPointSchema, k as ContactPointSchemaProps, l as CountrySchema, m as CountrySchemaProps, n as CourseSchema, o as CourseSchemaProps, E as EventSchema, p as EventSchemaProps, F as FAQPageSchema, q as FAQPageSchemaProps, H as HowToSchema, r as HowToSchemaProps, I as ImageObjectSchema, s as ImageObjectSchemaProps, t as ItemListSchema, u as ItemListSchemaProps, J as JobPostingSchema, v as JobPostingSchemaProps, L as LegalServiceSchema, w as LegalServiceSchemaProps, x as LocalBusinessSchema, y as LocalBusinessSchemaProps, M as MovieSchema, z as MovieSchemaProps, D as MusicAlbumSchema, G as MusicAlbumSchemaProps, K as MusicRecordingSchema, N as MusicRecordingSchemaProps, O as NewsArticleSchema, P as NewsArticleSchemaProps, Q as OfferSchema, R as OfferSchemaProps, S as OpinionNewsArticleSchema, T as OpinionNewsArticleSchemaProps, U as OrganizationSchema, V as OrganizationSchemaProps, W as PersonSchema, X as PersonSchemaProps, Y as PlaceSchema, Z as PlaceSchemaProps, _ as PostalAddressSchema, $ as PostalAddressSchemaProps, a0 as ProductSchema, a1 as ProductSchemaProps, a2 as ProfilePageSchema, a3 as ProfilePageSchemaProps, a4 as RecipeSchema, a5 as RecipeSchemaProps, a6 as RestaurantSchema, a7 as RestaurantSchemaProps, a8 as ReviewSchema, a9 as ReviewSchemaProps, aa as ServiceSchema, ab as ServiceSchemaProps, ac as SoftwareApplicationSchema, ad as SoftwareApplicationSchemaProps, ae as VideoObjectSchema, af as VideoObjectSchemaProps, ag as WebApplicationSchema, ah as WebApplicationSchemaProps, ai as WebPageSchema, aj as WebPageSchemaProps, ak as WebsiteSchema, al as WebsiteSchemaProps, am as buildAggregateRatingJsonLd, an as buildArticleJsonLd, ao as buildBlogPostingJsonLd, ap as buildBookJsonLd, aq as buildBrandJsonLd, ar as buildBreadcrumbListJsonLd, as as buildContactPointJsonLd, at as buildCountryJsonLd, au as buildCourseJsonLd, av as buildEventJsonLd, aw as buildFAQPageJsonLd, ax as buildHowToJsonLd, ay as buildImageObjectJsonLd, az as buildItemListJsonLd, aA as buildJobPostingJsonLd, aB as buildLegalServiceJsonLd, aC as buildLocalBusinessJsonLd, aD as buildMovieJsonLd, aE as buildMusicAlbumJsonLd, aF as buildMusicRecordingJsonLd, aG as buildNewsArticleJsonLd, aH as buildOfferJsonLd, aI as buildOpinionNewsArticleJsonLd, aJ as buildOrganizationJsonLd, aK as buildPersonJsonLd, aL as buildPlaceJsonLd, aM as buildPostalAddressJsonLd, aN as buildProductJsonLd, aO as buildProfilePageJsonLd, aP as buildRecipeJsonLd, aQ as buildRestaurantJsonLd, aR as buildReviewJsonLd, aS as buildServiceJsonLd, aT as buildSoftwareApplicationJsonLd, aU as buildVideoObjectJsonLd, aV as buildWebApplicationJsonLd, aW as buildWebPageJsonLd, aX as buildWebsiteJsonLd } from './component-CjT1hvxh.js';
|
|
7
8
|
|
package/dist/next.js
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
import {
|
|
2
|
+
buildLlmsTxt,
|
|
2
3
|
buildSeoHead,
|
|
3
4
|
buildSeoMeta,
|
|
5
|
+
docsToLlmsSection,
|
|
4
6
|
sanitizeOGType,
|
|
5
7
|
sanitizeTwitterCard
|
|
6
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-XD4HKLEA.js";
|
|
9
|
+
import {
|
|
10
|
+
buildHreflangs
|
|
11
|
+
} from "./chunk-CRCXC45D.js";
|
|
7
12
|
import {
|
|
8
13
|
AggregateRatingSchema,
|
|
9
14
|
ArticleSchema,
|
|
@@ -190,10 +195,12 @@ export {
|
|
|
190
195
|
buildEventJsonLd,
|
|
191
196
|
buildFAQPageJsonLd,
|
|
192
197
|
buildHowToJsonLd,
|
|
198
|
+
buildHreflangs,
|
|
193
199
|
buildImageObjectJsonLd,
|
|
194
200
|
buildItemListJsonLd,
|
|
195
201
|
buildJobPostingJsonLd,
|
|
196
202
|
buildLegalServiceJsonLd,
|
|
203
|
+
buildLlmsTxt,
|
|
197
204
|
buildLocalBusinessJsonLd,
|
|
198
205
|
buildMovieJsonLd,
|
|
199
206
|
buildMusicAlbumJsonLd,
|
|
@@ -220,6 +227,7 @@ export {
|
|
|
220
227
|
buildWebApplicationJsonLd,
|
|
221
228
|
buildWebPageJsonLd,
|
|
222
229
|
buildWebsiteJsonLd,
|
|
230
|
+
docsToLlmsSection,
|
|
223
231
|
sanitizeOGType,
|
|
224
232
|
sanitizeTwitterCard
|
|
225
233
|
};
|
package/dist/next.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/helpers/SeoMetaTags.tsx"],"sourcesContent":["/**\n * <SeoMetaTags> — Framework-agnostic React SEO meta tag renderer.\n *\n * Renders all SEO meta tags as plain React elements.\n * Place it inside your framework's <Head> component:\n *\n * @example Next.js Pages Router\n * ```tsx\n * import Head from 'next/head'\n * import { SeoMetaTags } from 'sanity-plugin-seofields/next'\n *\n * export default function Page({ seo }) {\n * return (\n * <>\n * <Head>\n * <SeoMetaTags\n * data={seo}\n * baseUrl=\"https://example.com\"\n * path=\"/about\"\n * defaults={{ title: 'My Site', siteName: 'My Site' }}\n * imageUrlResolver={(img) => urlFor(img).width(1200).url()}\n * />\n * </Head>\n * <main>...</main>\n * </>\n * )\n * }\n * ```\n *\n * @example React SSR (inside a framework <Head> slot)\n * ```tsx\n * <Head>\n * <SeoMetaTags data={seo} baseUrl=\"https://example.com\" path=\"/\" />\n * </Head>\n * ```\n */\nimport {Fragment, type JSX} from 'react'\n\nimport type {SanityImage, SanityImageWithAlt, SeoFields} from '../types'\nimport {buildSeoMeta, type BuildSeoMetaOptions} from './seoMeta'\n\n// ─── Props ────────────────────────────────────────────────────────────────────\n\nexport interface SeoMetaTagsProps {\n /**\n * The raw SEO object from Sanity.\n * Pass `null` / `undefined` to render only the defaults.\n */\n data?: Partial<SeoFields> | null\n\n /**\n * Base URL of your site, e.g. \"https://example.com\".\n * Used for canonical link, og:url fallback.\n */\n baseUrl?: string\n\n /**\n * Current page path, e.g. \"/about\".\n * Defaults to \"\".\n */\n path?: string\n\n /**\n * Default values used when SEO fields are missing.\n */\n defaults?: BuildSeoMetaOptions['defaults']\n\n /**\n * Resolve a Sanity image asset reference to a full URL string.\n *\n * @example\n * imageUrlResolver={(img) => urlFor(img).width(1200).url()}\n */\n imageUrlResolver?: (image: SanityImage | SanityImageWithAlt) => string | null | undefined\n}\n\n// ─── Component ────────────────────────────────────────────────────────────────\n\n/**\n * Renders all SEO meta tags for a page as plain React elements.\n * Intended to be placed inside your framework's <Head> / <head> component.\n *\n * Renders:\n * - `<title>`\n * - `<meta name=\"description\">`\n * - `<meta name=\"keywords\">`\n * - `<meta name=\"robots\">`\n * - OpenGraph meta tags (`og:*`)\n * - Twitter Card meta tags (`twitter:*`)\n * - Any custom `seo.metaAttributes` as `<meta name=\"...\" content=\"...\">`\n */\nexport function SeoMetaTags({\n data,\n baseUrl,\n path,\n defaults,\n imageUrlResolver,\n}: SeoMetaTagsProps): JSX.Element {\n const meta = buildSeoMeta({seo: data, baseUrl, path, defaults, imageUrlResolver})\n\n const robotsContent = [\n meta.robots?.index === false ? 'noindex' : 'index',\n meta.robots?.follow === false ? 'nofollow' : 'follow',\n meta.robots?.notranslate ? 'notranslate' : null,\n meta.robots?.noimageindex ? 'noimageindex' : null,\n ]\n .filter(Boolean)\n .join(', ')\n\n return (\n <>\n {/* ── Title ── */}\n {meta.title && <title>{meta.title}</title>}\n\n {/* ── Basic meta ── */}\n {meta.description && <meta name=\"description\" content={meta.description} />}\n {meta.keywords?.length ? <meta name=\"keywords\" content={meta.keywords.join(', ')} /> : null}\n <meta name=\"robots\" content={robotsContent} />\n <meta name=\"googlebot\" content={robotsContent} />\n\n {/* ── Open Graph ── */}\n {meta.openGraph?.type && <meta property=\"og:type\" content={meta.openGraph.type} />}\n {meta.openGraph?.url && <meta property=\"og:url\" content={meta.openGraph.url} />}\n {meta.openGraph?.title && <meta property=\"og:title\" content={meta.openGraph.title} />}\n {meta.openGraph?.description && (\n <meta property=\"og:description\" content={meta.openGraph.description} />\n )}\n {meta.openGraph?.siteName && (\n <meta property=\"og:site_name\" content={meta.openGraph.siteName} />\n )}\n {meta.openGraph?.images?.map((img, i) => (\n // eslint-disable-next-line react/no-array-index-key\n <Fragment key={`og-img-${i}`}>\n <meta property=\"og:image\" content={img.url} />\n {img.width && <meta property=\"og:image:width\" content={String(img.width)} />}\n {img.height && <meta property=\"og:image:height\" content={String(img.height)} />}\n {img.alt && <meta property=\"og:image:alt\" content={img.alt} />}\n </Fragment>\n ))}\n\n {/* ── Twitter Card ── */}\n {meta.twitter?.card && <meta name=\"twitter:card\" content={meta.twitter.card} />}\n {meta.twitter?.site && <meta name=\"twitter:site\" content={meta.twitter.site} />}\n {meta.twitter?.creator && <meta name=\"twitter:creator\" content={meta.twitter.creator} />}\n {meta.twitter?.title && <meta name=\"twitter:title\" content={meta.twitter.title} />}\n {meta.twitter?.description && (\n <meta name=\"twitter:description\" content={meta.twitter.description} />\n )}\n {meta.twitter?.images?.map((url, i) => (\n <meta key={`tw-img-${i}`} name=\"twitter:image\" content={url} />\n ))}\n\n {/* ── Custom meta attributes ── */}\n {meta.other &&\n Object.entries(meta.other).map(([name, content]) => (\n <meta key={`custom-${name}`} name={name} content={content} />\n ))}\n\n {/* ── Canonical URL ── */}\n {meta.alternates?.canonical && <link rel=\"canonical\" href={meta.alternates.canonical} />}\n </>\n )\n}\n\nexport default SeoMetaTags\n"],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../src/helpers/SeoMetaTags.tsx"],"sourcesContent":["/**\n * <SeoMetaTags> — Framework-agnostic React SEO meta tag renderer.\n *\n * Renders all SEO meta tags as plain React elements.\n * Place it inside your framework's <Head> component:\n *\n * @example Next.js Pages Router\n * ```tsx\n * import Head from 'next/head'\n * import { SeoMetaTags } from 'sanity-plugin-seofields/next'\n *\n * export default function Page({ seo }) {\n * return (\n * <>\n * <Head>\n * <SeoMetaTags\n * data={seo}\n * baseUrl=\"https://example.com\"\n * path=\"/about\"\n * defaults={{ title: 'My Site', siteName: 'My Site' }}\n * imageUrlResolver={(img) => urlFor(img).width(1200).url()}\n * />\n * </Head>\n * <main>...</main>\n * </>\n * )\n * }\n * ```\n *\n * @example React SSR (inside a framework <Head> slot)\n * ```tsx\n * <Head>\n * <SeoMetaTags data={seo} baseUrl=\"https://example.com\" path=\"/\" />\n * </Head>\n * ```\n */\nimport {Fragment, type JSX} from 'react'\n\nimport type {SanityImage, SanityImageWithAlt, SeoFields} from '../types'\nimport {buildSeoMeta, type BuildSeoMetaOptions} from './seoMeta'\n\n// ─── Props ────────────────────────────────────────────────────────────────────\n\nexport interface SeoMetaTagsProps {\n /**\n * The raw SEO object from Sanity.\n * Pass `null` / `undefined` to render only the defaults.\n */\n data?: Partial<SeoFields> | null\n\n /**\n * Base URL of your site, e.g. \"https://example.com\".\n * Used for canonical link, og:url fallback.\n */\n baseUrl?: string\n\n /**\n * Current page path, e.g. \"/about\".\n * Defaults to \"\".\n */\n path?: string\n\n /**\n * Default values used when SEO fields are missing.\n */\n defaults?: BuildSeoMetaOptions['defaults']\n\n /**\n * Resolve a Sanity image asset reference to a full URL string.\n *\n * @example\n * imageUrlResolver={(img) => urlFor(img).width(1200).url()}\n */\n imageUrlResolver?: (image: SanityImage | SanityImageWithAlt) => string | null | undefined\n}\n\n// ─── Component ────────────────────────────────────────────────────────────────\n\n/**\n * Renders all SEO meta tags for a page as plain React elements.\n * Intended to be placed inside your framework's <Head> / <head> component.\n *\n * Renders:\n * - `<title>`\n * - `<meta name=\"description\">`\n * - `<meta name=\"keywords\">`\n * - `<meta name=\"robots\">`\n * - OpenGraph meta tags (`og:*`)\n * - Twitter Card meta tags (`twitter:*`)\n * - Any custom `seo.metaAttributes` as `<meta name=\"...\" content=\"...\">`\n */\nexport function SeoMetaTags({\n data,\n baseUrl,\n path,\n defaults,\n imageUrlResolver,\n}: SeoMetaTagsProps): JSX.Element {\n const meta = buildSeoMeta({seo: data, baseUrl, path, defaults, imageUrlResolver})\n\n const robotsContent = [\n meta.robots?.index === false ? 'noindex' : 'index',\n meta.robots?.follow === false ? 'nofollow' : 'follow',\n meta.robots?.notranslate ? 'notranslate' : null,\n meta.robots?.noimageindex ? 'noimageindex' : null,\n ]\n .filter(Boolean)\n .join(', ')\n\n return (\n <>\n {/* ── Title ── */}\n {meta.title && <title>{meta.title}</title>}\n\n {/* ── Basic meta ── */}\n {meta.description && <meta name=\"description\" content={meta.description} />}\n {meta.keywords?.length ? <meta name=\"keywords\" content={meta.keywords.join(', ')} /> : null}\n <meta name=\"robots\" content={robotsContent} />\n <meta name=\"googlebot\" content={robotsContent} />\n\n {/* ── Open Graph ── */}\n {meta.openGraph?.type && <meta property=\"og:type\" content={meta.openGraph.type} />}\n {meta.openGraph?.url && <meta property=\"og:url\" content={meta.openGraph.url} />}\n {meta.openGraph?.title && <meta property=\"og:title\" content={meta.openGraph.title} />}\n {meta.openGraph?.description && (\n <meta property=\"og:description\" content={meta.openGraph.description} />\n )}\n {meta.openGraph?.siteName && (\n <meta property=\"og:site_name\" content={meta.openGraph.siteName} />\n )}\n {meta.openGraph?.images?.map((img, i) => (\n // eslint-disable-next-line react/no-array-index-key\n <Fragment key={`og-img-${i}`}>\n <meta property=\"og:image\" content={img.url} />\n {img.width && <meta property=\"og:image:width\" content={String(img.width)} />}\n {img.height && <meta property=\"og:image:height\" content={String(img.height)} />}\n {img.alt && <meta property=\"og:image:alt\" content={img.alt} />}\n </Fragment>\n ))}\n\n {/* ── Twitter Card ── */}\n {meta.twitter?.card && <meta name=\"twitter:card\" content={meta.twitter.card} />}\n {meta.twitter?.site && <meta name=\"twitter:site\" content={meta.twitter.site} />}\n {meta.twitter?.creator && <meta name=\"twitter:creator\" content={meta.twitter.creator} />}\n {meta.twitter?.title && <meta name=\"twitter:title\" content={meta.twitter.title} />}\n {meta.twitter?.description && (\n <meta name=\"twitter:description\" content={meta.twitter.description} />\n )}\n {meta.twitter?.images?.map((url, i) => (\n <meta key={`tw-img-${i}`} name=\"twitter:image\" content={url} />\n ))}\n\n {/* ── Custom meta attributes ── */}\n {meta.other &&\n Object.entries(meta.other).map(([name, content]) => (\n <meta key={`custom-${name}`} name={name} content={content} />\n ))}\n\n {/* ── Canonical URL ── */}\n {meta.alternates?.canonical && <link rel=\"canonical\" href={meta.alternates.canonical} />}\n </>\n )\n}\n\nexport default SeoMetaTags\n"],"mappings":"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","names":["Fragment"]}
|
|
@@ -1,8 +1,40 @@
|
|
|
1
1
|
import * as sanity from 'sanity';
|
|
2
|
+
import { a as HreflangTranslation } from './hreflang-_VbSuWYD.cjs';
|
|
2
3
|
import { ComponentType } from 'react';
|
|
3
4
|
import { D as DocumentWithSeoHealth } from './types-DxlPXihz.cjs';
|
|
4
5
|
|
|
6
|
+
type SeoGenField = 'title' | 'description' | 'focusKeyword' | 'keywords' | 'ogTitle' | 'ogDescription' | 'twitterTitle' | 'twitterDescription';
|
|
7
|
+
type MetaContext = {
|
|
8
|
+
title?: string;
|
|
9
|
+
description?: string;
|
|
10
|
+
slug?: string;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
/** Auto-populate configuration for the `hreflangs` field. */
|
|
14
|
+
interface HreflangConfig {
|
|
15
|
+
/** Show the "Sync from translations" button on the hreflangs field. */
|
|
16
|
+
autoFill?: boolean;
|
|
17
|
+
/** Field holding the language tag on translated documents. Defaults to 'language'. */
|
|
18
|
+
localeField?: string;
|
|
19
|
+
/** Build the path for a translation. Defaults to `/${slug}`. */
|
|
20
|
+
resolvePath?: (t: HreflangTranslation) => string;
|
|
21
|
+
}
|
|
5
22
|
type AiIndustry = 'blog' | 'ecommerce' | 'healthcare' | 'pharmacy' | 'saas' | 'finance' | 'realestate' | 'education' | 'restaurant' | 'travel' | 'fitness' | 'hospitality' | 'nonprofit' | 'legal' | 'insurance' | 'automotive' | 'homeServices';
|
|
23
|
+
/**
|
|
24
|
+
* All the generic document values the plugin extracts, handed to a custom prompt function so you can
|
|
25
|
+
* template your own prompt exactly the way the built-in prompts are built. `content` is the extracted
|
|
26
|
+
* document text (same output as the plugin's own content extraction).
|
|
27
|
+
*/
|
|
28
|
+
type CustomPromptValues = {
|
|
29
|
+
field: SeoGenField;
|
|
30
|
+
content: string;
|
|
31
|
+
focusKeyword: string;
|
|
32
|
+
keywords: string[];
|
|
33
|
+
meta?: MetaContext;
|
|
34
|
+
industry?: AiIndustry;
|
|
35
|
+
};
|
|
36
|
+
/** Receives all generic document values, returns the prompt string sent to the AI provider. */
|
|
37
|
+
type CustomPromptFn = (values: CustomPromptValues) => string;
|
|
6
38
|
interface AiConfig {
|
|
7
39
|
/** AI provider to use for text generation. */
|
|
8
40
|
provider?: 'openai' | 'anthropic' | 'groq' | 'gemini' | 'ollama';
|
|
@@ -48,6 +80,31 @@ interface AiConfig {
|
|
|
48
80
|
content?: string | string[] | Record<string, string | string[]>;
|
|
49
81
|
/** Industry context for prompts. When set, uses domain-specific vocabulary. Omit for generic prompts. */
|
|
50
82
|
industry?: AiIndustry;
|
|
83
|
+
/**
|
|
84
|
+
* FREE tier: a single custom prompt (generic or industry-specific — the function decides based on the
|
|
85
|
+
* `field`/`industry` it receives). Ignored if `customPrompts` is also set.
|
|
86
|
+
*
|
|
87
|
+
* In proxy mode (`endpoint`), custom prompts must be set on the **server** handler config
|
|
88
|
+
* (`createSeoAiHandler`) — a function cannot be sent over HTTP.
|
|
89
|
+
*
|
|
90
|
+
* @example
|
|
91
|
+
* customPrompt: (v) => `Write a 55-char SEO ${v.field} about: ${v.content.slice(0, 200)}`
|
|
92
|
+
*/
|
|
93
|
+
customPrompt?: CustomPromptFn;
|
|
94
|
+
/**
|
|
95
|
+
* PAID tier: up to 5 generic + up to 5 per-industry custom prompts. The count and per-industry
|
|
96
|
+
* pools are unlocked only behind a validated license via `seofields-pro`; without a valid license
|
|
97
|
+
* this collapses to a single prompt (same as the free `customPrompt`).
|
|
98
|
+
*
|
|
99
|
+
* By default custom prompts **replace** the built-in angle pool for a field. Set `merge: true` to
|
|
100
|
+
* mix them into the built-in pool instead.
|
|
101
|
+
*/
|
|
102
|
+
customPrompts?: {
|
|
103
|
+
generic?: CustomPromptFn[];
|
|
104
|
+
byIndustry?: Partial<Record<AiIndustry, CustomPromptFn[]>>;
|
|
105
|
+
/** Mix custom prompts with the built-in angle pool. Default false = replace. */
|
|
106
|
+
merge?: boolean;
|
|
107
|
+
};
|
|
51
108
|
/** Enable test mode — uses static pre-written outputs without any API call. Shows test warning in UI. */
|
|
52
109
|
testMode?: boolean;
|
|
53
110
|
/** Number of full generation attempts before giving up. Defaults to 2. */
|
|
@@ -223,6 +280,16 @@ interface SeoFieldsPluginConfig {
|
|
|
223
280
|
* @example '2024-01-01'
|
|
224
281
|
*/
|
|
225
282
|
apiVersion?: string;
|
|
283
|
+
/**
|
|
284
|
+
* Auto-populate the `hreflangs` field from document translations. Designed for
|
|
285
|
+
* `@sanity/document-internationalization` — adds a "Sync from translations" button to the field
|
|
286
|
+
* that reads the `translation.metadata` references and fills alternate entries (still editable).
|
|
287
|
+
* URLs are built from the root `baseUrl` + each translation's slug.
|
|
288
|
+
*
|
|
289
|
+
* @example
|
|
290
|
+
* hreflang: { autoFill: true, resolvePath: (t) => `/${t.language}/${t.slug}` }
|
|
291
|
+
*/
|
|
292
|
+
hreflang?: HreflangConfig;
|
|
226
293
|
/**
|
|
227
294
|
* Enable or configure the SEO Health Dashboard tool.
|
|
228
295
|
* If set to `true`, the dashboard is enabled with all defaults.
|
|
@@ -446,4 +513,4 @@ interface SeoFieldsPluginConfig {
|
|
|
446
513
|
}
|
|
447
514
|
declare const seofields: sanity.Plugin<void | SeoFieldsPluginConfig>;
|
|
448
515
|
|
|
449
|
-
export { type AiConfig as A, type FieldVisibilityConfig as F, type PublishGateRequiredField as P, type
|
|
516
|
+
export { type AiConfig as A, type CustomPromptFn as C, type FieldVisibilityConfig as F, type HreflangConfig as H, type MetaContext as M, type PublishGateRequiredField as P, type SeoGenField as S, type ValidHiddenFieldKeys as V, type AiIndustry as a, type SeoFieldsPluginConfig as b, type AllFieldKeys as c, type CustomPromptValues as d, type SeoFieldConfig as e, type SeoFieldGroup as f, type SeoFieldKeys as g, type SeoObjectFieldName as h, type openGraphFieldKeys as o, seofields as s, type twitterFieldKeys as t };
|
|
@@ -1,8 +1,40 @@
|
|
|
1
1
|
import * as sanity from 'sanity';
|
|
2
|
+
import { a as HreflangTranslation } from './hreflang-_VbSuWYD.js';
|
|
2
3
|
import { ComponentType } from 'react';
|
|
3
4
|
import { D as DocumentWithSeoHealth } from './types-DxlPXihz.js';
|
|
4
5
|
|
|
6
|
+
type SeoGenField = 'title' | 'description' | 'focusKeyword' | 'keywords' | 'ogTitle' | 'ogDescription' | 'twitterTitle' | 'twitterDescription';
|
|
7
|
+
type MetaContext = {
|
|
8
|
+
title?: string;
|
|
9
|
+
description?: string;
|
|
10
|
+
slug?: string;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
/** Auto-populate configuration for the `hreflangs` field. */
|
|
14
|
+
interface HreflangConfig {
|
|
15
|
+
/** Show the "Sync from translations" button on the hreflangs field. */
|
|
16
|
+
autoFill?: boolean;
|
|
17
|
+
/** Field holding the language tag on translated documents. Defaults to 'language'. */
|
|
18
|
+
localeField?: string;
|
|
19
|
+
/** Build the path for a translation. Defaults to `/${slug}`. */
|
|
20
|
+
resolvePath?: (t: HreflangTranslation) => string;
|
|
21
|
+
}
|
|
5
22
|
type AiIndustry = 'blog' | 'ecommerce' | 'healthcare' | 'pharmacy' | 'saas' | 'finance' | 'realestate' | 'education' | 'restaurant' | 'travel' | 'fitness' | 'hospitality' | 'nonprofit' | 'legal' | 'insurance' | 'automotive' | 'homeServices';
|
|
23
|
+
/**
|
|
24
|
+
* All the generic document values the plugin extracts, handed to a custom prompt function so you can
|
|
25
|
+
* template your own prompt exactly the way the built-in prompts are built. `content` is the extracted
|
|
26
|
+
* document text (same output as the plugin's own content extraction).
|
|
27
|
+
*/
|
|
28
|
+
type CustomPromptValues = {
|
|
29
|
+
field: SeoGenField;
|
|
30
|
+
content: string;
|
|
31
|
+
focusKeyword: string;
|
|
32
|
+
keywords: string[];
|
|
33
|
+
meta?: MetaContext;
|
|
34
|
+
industry?: AiIndustry;
|
|
35
|
+
};
|
|
36
|
+
/** Receives all generic document values, returns the prompt string sent to the AI provider. */
|
|
37
|
+
type CustomPromptFn = (values: CustomPromptValues) => string;
|
|
6
38
|
interface AiConfig {
|
|
7
39
|
/** AI provider to use for text generation. */
|
|
8
40
|
provider?: 'openai' | 'anthropic' | 'groq' | 'gemini' | 'ollama';
|
|
@@ -48,6 +80,31 @@ interface AiConfig {
|
|
|
48
80
|
content?: string | string[] | Record<string, string | string[]>;
|
|
49
81
|
/** Industry context for prompts. When set, uses domain-specific vocabulary. Omit for generic prompts. */
|
|
50
82
|
industry?: AiIndustry;
|
|
83
|
+
/**
|
|
84
|
+
* FREE tier: a single custom prompt (generic or industry-specific — the function decides based on the
|
|
85
|
+
* `field`/`industry` it receives). Ignored if `customPrompts` is also set.
|
|
86
|
+
*
|
|
87
|
+
* In proxy mode (`endpoint`), custom prompts must be set on the **server** handler config
|
|
88
|
+
* (`createSeoAiHandler`) — a function cannot be sent over HTTP.
|
|
89
|
+
*
|
|
90
|
+
* @example
|
|
91
|
+
* customPrompt: (v) => `Write a 55-char SEO ${v.field} about: ${v.content.slice(0, 200)}`
|
|
92
|
+
*/
|
|
93
|
+
customPrompt?: CustomPromptFn;
|
|
94
|
+
/**
|
|
95
|
+
* PAID tier: up to 5 generic + up to 5 per-industry custom prompts. The count and per-industry
|
|
96
|
+
* pools are unlocked only behind a validated license via `seofields-pro`; without a valid license
|
|
97
|
+
* this collapses to a single prompt (same as the free `customPrompt`).
|
|
98
|
+
*
|
|
99
|
+
* By default custom prompts **replace** the built-in angle pool for a field. Set `merge: true` to
|
|
100
|
+
* mix them into the built-in pool instead.
|
|
101
|
+
*/
|
|
102
|
+
customPrompts?: {
|
|
103
|
+
generic?: CustomPromptFn[];
|
|
104
|
+
byIndustry?: Partial<Record<AiIndustry, CustomPromptFn[]>>;
|
|
105
|
+
/** Mix custom prompts with the built-in angle pool. Default false = replace. */
|
|
106
|
+
merge?: boolean;
|
|
107
|
+
};
|
|
51
108
|
/** Enable test mode — uses static pre-written outputs without any API call. Shows test warning in UI. */
|
|
52
109
|
testMode?: boolean;
|
|
53
110
|
/** Number of full generation attempts before giving up. Defaults to 2. */
|
|
@@ -223,6 +280,16 @@ interface SeoFieldsPluginConfig {
|
|
|
223
280
|
* @example '2024-01-01'
|
|
224
281
|
*/
|
|
225
282
|
apiVersion?: string;
|
|
283
|
+
/**
|
|
284
|
+
* Auto-populate the `hreflangs` field from document translations. Designed for
|
|
285
|
+
* `@sanity/document-internationalization` — adds a "Sync from translations" button to the field
|
|
286
|
+
* that reads the `translation.metadata` references and fills alternate entries (still editable).
|
|
287
|
+
* URLs are built from the root `baseUrl` + each translation's slug.
|
|
288
|
+
*
|
|
289
|
+
* @example
|
|
290
|
+
* hreflang: { autoFill: true, resolvePath: (t) => `/${t.language}/${t.slug}` }
|
|
291
|
+
*/
|
|
292
|
+
hreflang?: HreflangConfig;
|
|
226
293
|
/**
|
|
227
294
|
* Enable or configure the SEO Health Dashboard tool.
|
|
228
295
|
* If set to `true`, the dashboard is enabled with all defaults.
|
|
@@ -446,4 +513,4 @@ interface SeoFieldsPluginConfig {
|
|
|
446
513
|
}
|
|
447
514
|
declare const seofields: sanity.Plugin<void | SeoFieldsPluginConfig>;
|
|
448
515
|
|
|
449
|
-
export { type AiConfig as A, type FieldVisibilityConfig as F, type PublishGateRequiredField as P, type
|
|
516
|
+
export { type AiConfig as A, type CustomPromptFn as C, type FieldVisibilityConfig as F, type HreflangConfig as H, type MetaContext as M, type PublishGateRequiredField as P, type SeoGenField as S, type ValidHiddenFieldKeys as V, type AiIndustry as a, type SeoFieldsPluginConfig as b, type AllFieldKeys as c, type CustomPromptValues as d, type SeoFieldConfig as e, type SeoFieldGroup as f, type SeoFieldKeys as g, type SeoObjectFieldName as h, type openGraphFieldKeys as o, seofields as s, type twitterFieldKeys as t };
|
package/dist/server.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";Object.defineProperty(exports, "__esModule", {value: true});
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var _chunkEUG4MNRCcjs = require('./chunk-EUG4MNRC.cjs');
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
|
|
@@ -23,7 +23,7 @@ function createSeoAiHandler(config) {
|
|
|
23
23
|
industry: industry != null ? industry : config.industry,
|
|
24
24
|
_licenseKey: licenseKey != null ? licenseKey : config._licenseKey
|
|
25
25
|
});
|
|
26
|
-
const result = await
|
|
26
|
+
const result = await _chunkEUG4MNRCcjs.generateSeoText.call(void 0, field, content, focusKeyword, keywords, {
|
|
27
27
|
config: mergedConfig,
|
|
28
28
|
meta
|
|
29
29
|
});
|
package/dist/server.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/hardik/GITHUB/sanity-plugin-seofields/npm/dist/server.cjs","../src/server/aiHandler.ts","../src/server/adapters/express.ts","../src/server/adapters/fetch.ts","../src/server/adapters/nextjs.ts","../src/server/adapters/node.ts"],"names":[],"mappings":"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","file":"/Users/hardik/GITHUB/sanity-plugin-seofields/npm/dist/server.cjs","sourcesContent":[null,"import type {AiConfig, AiIndustry} from '../plugin'\nimport {generateSeoText} from '../utils/seoContentGen'\nimport type {MetaContext, SeoGenField} from '../utils/seoPrompts'\n\nexport interface SeoAiRequestBody {\n field: SeoGenField\n content: string\n focusKeyword?: string\n keywords?: string[]\n meta?: MetaContext\n /** Industry chosen in the Studio's `ai.industry` config — forwarded so proxy mode matches direct-provider mode. */\n industry?: AiIndustry\n /** License key forwarded from the Studio's `ai._licenseKey` — determines which prompt pool proxy mode uses. */\n licenseKey?: string\n}\n\nexport interface SeoAiHandler {\n (body: SeoAiRequestBody): Promise<{result: string}>\n}\n\nfunction isValidBody(body: unknown): body is SeoAiRequestBody {\n if (!body || typeof body !== 'object') return false\n const {field, content} = body as Record<string, unknown>\n return typeof field === 'string' && typeof content === 'string'\n}\n\n/**\n * Runs the full SEO text generation pipeline (prompting, retries, validation) server-side using\n * a real `AiConfig` — including `apiKey` — which never has to be sent to the browser. Pair with\n * `endpoint` in the Studio's `ai` config, and one of the framework adapters in\n * `sanity-plugin-seofields/server` to expose it over HTTP.\n */\nexport function createSeoAiHandler(config: AiConfig): SeoAiHandler {\n return async function handleSeoAiRequest(body: SeoAiRequestBody): Promise<{result: string}> {\n if (!isValidBody(body)) {\n throw new Error('Invalid request body: \"field\" and \"content\" are required.')\n }\n\n const {field, content, focusKeyword = '', keywords = [], meta, industry, licenseKey} = body\n const mergedConfig: AiConfig = {\n ...config,\n industry: industry ?? config.industry,\n _licenseKey: licenseKey ?? config._licenseKey,\n }\n const result = await generateSeoText(field, content, focusKeyword, keywords, {\n config: mergedConfig,\n meta,\n })\n return {result}\n }\n}\n","import type {AiConfig} from '../../plugin'\nimport {createSeoAiHandler, type SeoAiRequestBody} from '../aiHandler'\n\n// Duck-typed instead of importing `express` types, so the package has no dependency on Express.\nexport interface MinimalRequest {\n method?: string\n body?: unknown\n}\n\nexport interface MinimalResponse {\n status(code: number): MinimalResponse\n json(body: unknown): void\n setHeader(name: string, value: string): void\n end(): void\n}\n\nexport interface ExpressAdapterOptions {\n cors?: string\n}\n\n/**\n * Express (or Express-compatible) request handler. Requires a JSON body parser\n * (e.g. `app.use(express.json())`) mounted before this route.\n *\n * @example\n * import { createExpressHandler } from 'sanity-plugin-seofields/server'\n * app.post('/api/seo-ai', createExpressHandler({ provider: 'openai', apiKey: process.env.OPENAI_API_KEY }))\n */\nexport function createExpressHandler(\n config: AiConfig,\n options: ExpressAdapterOptions = {},\n): (req: MinimalRequest, res: MinimalResponse) => Promise<void> {\n const handle = createSeoAiHandler(config)\n\n return async function seoAiExpressHandler(\n req: MinimalRequest,\n res: MinimalResponse,\n ): Promise<void> {\n if (options.cors) res.setHeader('Access-Control-Allow-Origin', options.cors)\n\n if (req.method === 'OPTIONS') {\n res.status(204).end()\n return\n }\n\n if (req.method !== 'POST') {\n res.status(405).json({error: 'Method not allowed'})\n return\n }\n\n try {\n const result = await handle(req.body as SeoAiRequestBody)\n res.status(200).json(result)\n } catch (err) {\n const message = err instanceof Error ? err.message : 'AI generation failed.'\n res.status(500).json({error: message})\n }\n }\n}\n","import type {AiConfig} from '../../plugin'\nimport {createSeoAiHandler, type SeoAiRequestBody} from '../aiHandler'\n\nexport interface FetchAdapterOptions {\n /** Origin allowed to call this endpoint. Only needed when the proxy is deployed on a\n * different origin than the Studio (same-app routes don't hit CORS at all). */\n cors?: string\n}\n\nfunction corsHeaders(options: FetchAdapterOptions): Record<string, string> {\n return options.cors ? {'Access-Control-Allow-Origin': options.cors} : {}\n}\n\n/**\n * Standard `Request -> Response` handler. Works as-is for Next.js App Router route handlers,\n * Cloudflare Workers, Deno, Bun, Remix, and SvelteKit — anything built on the Fetch API.\n */\nexport function createFetchHandler(\n config: AiConfig,\n options: FetchAdapterOptions = {},\n): (request: Request) => Promise<Response> {\n const handle = createSeoAiHandler(config)\n const headers = {'Content-Type': 'application/json', ...corsHeaders(options)}\n\n return async function seoAiFetchHandler(request: Request): Promise<Response> {\n if (request.method === 'OPTIONS') {\n return new Response(null, {\n status: 204,\n headers: {\n ...headers,\n 'Access-Control-Allow-Methods': 'POST, OPTIONS',\n 'Access-Control-Allow-Headers': 'Content-Type',\n },\n })\n }\n\n if (request.method !== 'POST') {\n return new Response(JSON.stringify({error: 'Method not allowed'}), {status: 405, headers})\n }\n\n try {\n const body = (await request.json()) as SeoAiRequestBody\n const result = await handle(body)\n return new Response(JSON.stringify(result), {status: 200, headers})\n } catch (err) {\n const message = err instanceof Error ? err.message : 'AI generation failed.'\n return new Response(JSON.stringify({error: message}), {status: 500, headers})\n }\n }\n}\n","import type {AiConfig} from '../../plugin'\nimport {createFetchHandler, type FetchAdapterOptions} from './fetch'\n\n/**\n * Next.js App Router route handler.\n *\n * @example\n * // app/api/seo-ai/route.ts\n * import { createNextRouteHandler } from 'sanity-plugin-seofields/server'\n *\n * export const { POST, OPTIONS } = createNextRouteHandler({\n * provider: 'openai',\n * apiKey: process.env.OPENAI_API_KEY,\n * })\n */\nexport function createNextRouteHandler(\n config: AiConfig,\n options?: FetchAdapterOptions,\n): {\n POST: (request: Request) => Promise<Response>\n OPTIONS: (request: Request) => Promise<Response>\n} {\n const handler = createFetchHandler(config, options)\n return {POST: handler, OPTIONS: handler}\n}\n","import type {IncomingMessage, ServerResponse} from 'node:http'\n\nimport type {AiConfig} from '../../plugin'\nimport {createSeoAiHandler, type SeoAiRequestBody} from '../aiHandler'\n\nexport interface NodeAdapterOptions {\n cors?: string\n}\n\nasync function readJsonBody(req: IncomingMessage): Promise<unknown> {\n const chunks: Buffer[] = []\n for await (const chunk of req) chunks.push(chunk as Buffer)\n const raw = Buffer.concat(chunks).toString('utf8')\n return raw ? JSON.parse(raw) : {}\n}\n\n/**\n * Raw Node `http`/`https` request handler.\n *\n * @example\n * import { createServer } from 'node:http'\n * import { createNodeHandler } from 'sanity-plugin-seofields/server'\n * createServer(createNodeHandler({ provider: 'openai', apiKey: process.env.OPENAI_API_KEY })).listen(3000)\n */\nexport function createNodeHandler(\n config: AiConfig,\n options: NodeAdapterOptions = {},\n): (req: IncomingMessage, res: ServerResponse) => Promise<void> {\n const handle = createSeoAiHandler(config)\n\n return async function seoAiNodeHandler(req: IncomingMessage, res: ServerResponse): Promise<void> {\n if (options.cors) res.setHeader('Access-Control-Allow-Origin', options.cors)\n res.setHeader('Content-Type', 'application/json')\n\n if (req.method === 'OPTIONS') {\n res.writeHead(204)\n res.end()\n return\n }\n\n if (req.method !== 'POST') {\n res.writeHead(405)\n res.end(JSON.stringify({error: 'Method not allowed'}))\n return\n }\n\n try {\n const body = (await readJsonBody(req)) as SeoAiRequestBody\n const result = await handle(body)\n res.writeHead(200)\n res.end(JSON.stringify(result))\n } catch (err) {\n const message = err instanceof Error ? err.message : 'AI generation failed.'\n res.writeHead(500)\n res.end(JSON.stringify({error: message}))\n }\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["/Users/hardik/GITHUB/sanity-plugin-seofields/npm/dist/server.cjs","../src/server/aiHandler.ts","../src/server/adapters/express.ts","../src/server/adapters/fetch.ts","../src/server/adapters/nextjs.ts","../src/server/adapters/node.ts"],"names":[],"mappings":"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","file":"/Users/hardik/GITHUB/sanity-plugin-seofields/npm/dist/server.cjs","sourcesContent":[null,"import type {AiConfig, AiIndustry} from '../plugin'\nimport {generateSeoText} from '../utils/seoContentGen'\nimport type {MetaContext, SeoGenField} from '../utils/seoPrompts'\n\nexport interface SeoAiRequestBody {\n field: SeoGenField\n content: string\n focusKeyword?: string\n keywords?: string[]\n meta?: MetaContext\n /** Industry chosen in the Studio's `ai.industry` config — forwarded so proxy mode matches direct-provider mode. */\n industry?: AiIndustry\n /** License key forwarded from the Studio's `ai._licenseKey` — determines which prompt pool proxy mode uses. */\n licenseKey?: string\n}\n\nexport interface SeoAiHandler {\n (body: SeoAiRequestBody): Promise<{result: string}>\n}\n\nfunction isValidBody(body: unknown): body is SeoAiRequestBody {\n if (!body || typeof body !== 'object') return false\n const {field, content} = body as Record<string, unknown>\n return typeof field === 'string' && typeof content === 'string'\n}\n\n/**\n * Runs the full SEO text generation pipeline (prompting, retries, validation) server-side using\n * a real `AiConfig` — including `apiKey` — which never has to be sent to the browser. Pair with\n * `endpoint` in the Studio's `ai` config, and one of the framework adapters in\n * `sanity-plugin-seofields/server` to expose it over HTTP.\n *\n * NOTE: `customPrompt` / `customPrompts` are functions and cannot cross the HTTP boundary, so in\n * proxy mode they must be set on THIS server config (the `AiConfig` passed here), not on the Studio's\n * `ai` config. They apply automatically since this handler runs `generateSeoText` with `config`.\n */\nexport function createSeoAiHandler(config: AiConfig): SeoAiHandler {\n return async function handleSeoAiRequest(body: SeoAiRequestBody): Promise<{result: string}> {\n if (!isValidBody(body)) {\n throw new Error('Invalid request body: \"field\" and \"content\" are required.')\n }\n\n const {field, content, focusKeyword = '', keywords = [], meta, industry, licenseKey} = body\n const mergedConfig: AiConfig = {\n ...config,\n industry: industry ?? config.industry,\n _licenseKey: licenseKey ?? config._licenseKey,\n }\n const result = await generateSeoText(field, content, focusKeyword, keywords, {\n config: mergedConfig,\n meta,\n })\n return {result}\n }\n}\n","import type {AiConfig} from '../../plugin'\nimport {createSeoAiHandler, type SeoAiRequestBody} from '../aiHandler'\n\n// Duck-typed instead of importing `express` types, so the package has no dependency on Express.\nexport interface MinimalRequest {\n method?: string\n body?: unknown\n}\n\nexport interface MinimalResponse {\n status(code: number): MinimalResponse\n json(body: unknown): void\n setHeader(name: string, value: string): void\n end(): void\n}\n\nexport interface ExpressAdapterOptions {\n cors?: string\n}\n\n/**\n * Express (or Express-compatible) request handler. Requires a JSON body parser\n * (e.g. `app.use(express.json())`) mounted before this route.\n *\n * @example\n * import { createExpressHandler } from 'sanity-plugin-seofields/server'\n * app.post('/api/seo-ai', createExpressHandler({ provider: 'openai', apiKey: process.env.OPENAI_API_KEY }))\n */\nexport function createExpressHandler(\n config: AiConfig,\n options: ExpressAdapterOptions = {},\n): (req: MinimalRequest, res: MinimalResponse) => Promise<void> {\n const handle = createSeoAiHandler(config)\n\n return async function seoAiExpressHandler(\n req: MinimalRequest,\n res: MinimalResponse,\n ): Promise<void> {\n if (options.cors) res.setHeader('Access-Control-Allow-Origin', options.cors)\n\n if (req.method === 'OPTIONS') {\n res.status(204).end()\n return\n }\n\n if (req.method !== 'POST') {\n res.status(405).json({error: 'Method not allowed'})\n return\n }\n\n try {\n const result = await handle(req.body as SeoAiRequestBody)\n res.status(200).json(result)\n } catch (err) {\n const message = err instanceof Error ? err.message : 'AI generation failed.'\n res.status(500).json({error: message})\n }\n }\n}\n","import type {AiConfig} from '../../plugin'\nimport {createSeoAiHandler, type SeoAiRequestBody} from '../aiHandler'\n\nexport interface FetchAdapterOptions {\n /** Origin allowed to call this endpoint. Only needed when the proxy is deployed on a\n * different origin than the Studio (same-app routes don't hit CORS at all). */\n cors?: string\n}\n\nfunction corsHeaders(options: FetchAdapterOptions): Record<string, string> {\n return options.cors ? {'Access-Control-Allow-Origin': options.cors} : {}\n}\n\n/**\n * Standard `Request -> Response` handler. Works as-is for Next.js App Router route handlers,\n * Cloudflare Workers, Deno, Bun, Remix, and SvelteKit — anything built on the Fetch API.\n */\nexport function createFetchHandler(\n config: AiConfig,\n options: FetchAdapterOptions = {},\n): (request: Request) => Promise<Response> {\n const handle = createSeoAiHandler(config)\n const headers = {'Content-Type': 'application/json', ...corsHeaders(options)}\n\n return async function seoAiFetchHandler(request: Request): Promise<Response> {\n if (request.method === 'OPTIONS') {\n return new Response(null, {\n status: 204,\n headers: {\n ...headers,\n 'Access-Control-Allow-Methods': 'POST, OPTIONS',\n 'Access-Control-Allow-Headers': 'Content-Type',\n },\n })\n }\n\n if (request.method !== 'POST') {\n return new Response(JSON.stringify({error: 'Method not allowed'}), {status: 405, headers})\n }\n\n try {\n const body = (await request.json()) as SeoAiRequestBody\n const result = await handle(body)\n return new Response(JSON.stringify(result), {status: 200, headers})\n } catch (err) {\n const message = err instanceof Error ? err.message : 'AI generation failed.'\n return new Response(JSON.stringify({error: message}), {status: 500, headers})\n }\n }\n}\n","import type {AiConfig} from '../../plugin'\nimport {createFetchHandler, type FetchAdapterOptions} from './fetch'\n\n/**\n * Next.js App Router route handler.\n *\n * @example\n * // app/api/seo-ai/route.ts\n * import { createNextRouteHandler } from 'sanity-plugin-seofields/server'\n *\n * export const { POST, OPTIONS } = createNextRouteHandler({\n * provider: 'openai',\n * apiKey: process.env.OPENAI_API_KEY,\n * })\n */\nexport function createNextRouteHandler(\n config: AiConfig,\n options?: FetchAdapterOptions,\n): {\n POST: (request: Request) => Promise<Response>\n OPTIONS: (request: Request) => Promise<Response>\n} {\n const handler = createFetchHandler(config, options)\n return {POST: handler, OPTIONS: handler}\n}\n","import type {IncomingMessage, ServerResponse} from 'node:http'\n\nimport type {AiConfig} from '../../plugin'\nimport {createSeoAiHandler, type SeoAiRequestBody} from '../aiHandler'\n\nexport interface NodeAdapterOptions {\n cors?: string\n}\n\nasync function readJsonBody(req: IncomingMessage): Promise<unknown> {\n const chunks: Buffer[] = []\n for await (const chunk of req) chunks.push(chunk as Buffer)\n const raw = Buffer.concat(chunks).toString('utf8')\n return raw ? JSON.parse(raw) : {}\n}\n\n/**\n * Raw Node `http`/`https` request handler.\n *\n * @example\n * import { createServer } from 'node:http'\n * import { createNodeHandler } from 'sanity-plugin-seofields/server'\n * createServer(createNodeHandler({ provider: 'openai', apiKey: process.env.OPENAI_API_KEY })).listen(3000)\n */\nexport function createNodeHandler(\n config: AiConfig,\n options: NodeAdapterOptions = {},\n): (req: IncomingMessage, res: ServerResponse) => Promise<void> {\n const handle = createSeoAiHandler(config)\n\n return async function seoAiNodeHandler(req: IncomingMessage, res: ServerResponse): Promise<void> {\n if (options.cors) res.setHeader('Access-Control-Allow-Origin', options.cors)\n res.setHeader('Content-Type', 'application/json')\n\n if (req.method === 'OPTIONS') {\n res.writeHead(204)\n res.end()\n return\n }\n\n if (req.method !== 'POST') {\n res.writeHead(405)\n res.end(JSON.stringify({error: 'Method not allowed'}))\n return\n }\n\n try {\n const body = (await readJsonBody(req)) as SeoAiRequestBody\n const result = await handle(body)\n res.writeHead(200)\n res.end(JSON.stringify(result))\n } catch (err) {\n const message = err instanceof Error ? err.message : 'AI generation failed.'\n res.writeHead(500)\n res.end(JSON.stringify({error: message}))\n }\n }\n}\n"]}
|
package/dist/server.d.cts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { A as AiConfig, a as AiIndustry } from './plugin-
|
|
1
|
+
import { A as AiConfig, S as SeoGenField, M as MetaContext, a as AiIndustry } from './plugin-HFuWZsJu.cjs';
|
|
2
2
|
import { IncomingMessage, ServerResponse } from 'node:http';
|
|
3
3
|
import 'sanity';
|
|
4
|
+
import './hreflang-_VbSuWYD.cjs';
|
|
4
5
|
import 'react';
|
|
5
6
|
import './types-DxlPXihz.cjs';
|
|
6
7
|
|
|
@@ -68,13 +69,6 @@ interface NodeAdapterOptions {
|
|
|
68
69
|
*/
|
|
69
70
|
declare function createNodeHandler(config: AiConfig, options?: NodeAdapterOptions): (req: IncomingMessage, res: ServerResponse) => Promise<void>;
|
|
70
71
|
|
|
71
|
-
type SeoGenField = 'title' | 'description' | 'focusKeyword' | 'keywords' | 'ogTitle' | 'ogDescription' | 'twitterTitle' | 'twitterDescription';
|
|
72
|
-
type MetaContext = {
|
|
73
|
-
title?: string;
|
|
74
|
-
description?: string;
|
|
75
|
-
slug?: string;
|
|
76
|
-
};
|
|
77
|
-
|
|
78
72
|
interface SeoAiRequestBody {
|
|
79
73
|
field: SeoGenField;
|
|
80
74
|
content: string;
|
|
@@ -96,6 +90,10 @@ interface SeoAiHandler {
|
|
|
96
90
|
* a real `AiConfig` — including `apiKey` — which never has to be sent to the browser. Pair with
|
|
97
91
|
* `endpoint` in the Studio's `ai` config, and one of the framework adapters in
|
|
98
92
|
* `sanity-plugin-seofields/server` to expose it over HTTP.
|
|
93
|
+
*
|
|
94
|
+
* NOTE: `customPrompt` / `customPrompts` are functions and cannot cross the HTTP boundary, so in
|
|
95
|
+
* proxy mode they must be set on THIS server config (the `AiConfig` passed here), not on the Studio's
|
|
96
|
+
* `ai` config. They apply automatically since this handler runs `generateSeoText` with `config`.
|
|
99
97
|
*/
|
|
100
98
|
declare function createSeoAiHandler(config: AiConfig): SeoAiHandler;
|
|
101
99
|
|
package/dist/server.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { A as AiConfig, a as AiIndustry } from './plugin-
|
|
1
|
+
import { A as AiConfig, S as SeoGenField, M as MetaContext, a as AiIndustry } from './plugin-oQUCim56.js';
|
|
2
2
|
import { IncomingMessage, ServerResponse } from 'node:http';
|
|
3
3
|
import 'sanity';
|
|
4
|
+
import './hreflang-_VbSuWYD.js';
|
|
4
5
|
import 'react';
|
|
5
6
|
import './types-DxlPXihz.js';
|
|
6
7
|
|
|
@@ -68,13 +69,6 @@ interface NodeAdapterOptions {
|
|
|
68
69
|
*/
|
|
69
70
|
declare function createNodeHandler(config: AiConfig, options?: NodeAdapterOptions): (req: IncomingMessage, res: ServerResponse) => Promise<void>;
|
|
70
71
|
|
|
71
|
-
type SeoGenField = 'title' | 'description' | 'focusKeyword' | 'keywords' | 'ogTitle' | 'ogDescription' | 'twitterTitle' | 'twitterDescription';
|
|
72
|
-
type MetaContext = {
|
|
73
|
-
title?: string;
|
|
74
|
-
description?: string;
|
|
75
|
-
slug?: string;
|
|
76
|
-
};
|
|
77
|
-
|
|
78
72
|
interface SeoAiRequestBody {
|
|
79
73
|
field: SeoGenField;
|
|
80
74
|
content: string;
|
|
@@ -96,6 +90,10 @@ interface SeoAiHandler {
|
|
|
96
90
|
* a real `AiConfig` — including `apiKey` — which never has to be sent to the browser. Pair with
|
|
97
91
|
* `endpoint` in the Studio's `ai` config, and one of the framework adapters in
|
|
98
92
|
* `sanity-plugin-seofields/server` to expose it over HTTP.
|
|
93
|
+
*
|
|
94
|
+
* NOTE: `customPrompt` / `customPrompts` are functions and cannot cross the HTTP boundary, so in
|
|
95
|
+
* proxy mode they must be set on THIS server config (the `AiConfig` passed here), not on the Studio's
|
|
96
|
+
* `ai` config. They apply automatically since this handler runs `generateSeoText` with `config`.
|
|
99
97
|
*/
|
|
100
98
|
declare function createSeoAiHandler(config: AiConfig): SeoAiHandler;
|
|
101
99
|
|