@flightdev/seo 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +403 -0
- package/dist/index.d.ts +282 -0
- package/dist/index.js +1239 -0
- package/dist/index.js.map +1 -0
- package/dist/json-ld/index.d.ts +341 -0
- package/dist/json-ld/index.js +82 -0
- package/dist/json-ld/index.js.map +1 -0
- package/dist/react/index.d.ts +161 -0
- package/dist/react/index.js +1300 -0
- package/dist/react/index.js.map +1 -0
- package/dist/robots/index.d.ts +105 -0
- package/dist/robots/index.js +186 -0
- package/dist/robots/index.js.map +1 -0
- package/dist/sitemap/index.d.ts +224 -0
- package/dist/sitemap/index.js +242 -0
- package/dist/sitemap/index.js.map +1 -0
- package/dist/solid/index.d.ts +50 -0
- package/dist/solid/index.js +1217 -0
- package/dist/solid/index.js.map +1 -0
- package/dist/svelte/index.d.ts +131 -0
- package/dist/svelte/index.js +1253 -0
- package/dist/svelte/index.js.map +1 -0
- package/dist/types-BBIMJIqz.d.ts +433 -0
- package/dist/vue/index.d.ts +130 -0
- package/dist/vue/index.js +1293 -0
- package/dist/vue/index.js.map +1 -0
- package/package.json +129 -0
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
// src/json-ld/index.ts
|
|
2
|
+
function createJsonLd(schema, options) {
|
|
3
|
+
const data = {
|
|
4
|
+
"@context": options?.context || "https://schema.org",
|
|
5
|
+
...schema
|
|
6
|
+
};
|
|
7
|
+
return JSON.stringify(data);
|
|
8
|
+
}
|
|
9
|
+
function createJsonLdGraph(schemas, options) {
|
|
10
|
+
const data = {
|
|
11
|
+
"@context": options?.context || "https://schema.org",
|
|
12
|
+
"@graph": schemas
|
|
13
|
+
};
|
|
14
|
+
return JSON.stringify(data);
|
|
15
|
+
}
|
|
16
|
+
function organizationJsonLd(data) {
|
|
17
|
+
return {
|
|
18
|
+
"@type": "Organization",
|
|
19
|
+
...data
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
function websiteJsonLd(data) {
|
|
23
|
+
return {
|
|
24
|
+
"@type": "WebSite",
|
|
25
|
+
...data
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
function articleJsonLd(data) {
|
|
29
|
+
const { type = "Article", ...rest } = data;
|
|
30
|
+
return {
|
|
31
|
+
"@type": type,
|
|
32
|
+
...rest
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
function productJsonLd(data) {
|
|
36
|
+
return {
|
|
37
|
+
"@type": "Product",
|
|
38
|
+
...data
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
function breadcrumbJsonLd(items) {
|
|
42
|
+
return {
|
|
43
|
+
"@type": "BreadcrumbList",
|
|
44
|
+
itemListElement: items.map((item, index) => ({
|
|
45
|
+
"@type": "ListItem",
|
|
46
|
+
position: index + 1,
|
|
47
|
+
name: item.name,
|
|
48
|
+
item: item.url
|
|
49
|
+
}))
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
function faqJsonLd(questions) {
|
|
53
|
+
return {
|
|
54
|
+
"@type": "FAQPage",
|
|
55
|
+
mainEntity: questions.map((q) => ({
|
|
56
|
+
"@type": "Question",
|
|
57
|
+
name: q.question,
|
|
58
|
+
acceptedAnswer: {
|
|
59
|
+
"@type": "Answer",
|
|
60
|
+
text: q.answer
|
|
61
|
+
}
|
|
62
|
+
}))
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
function localBusinessJsonLd(data) {
|
|
66
|
+
const { type = "LocalBusiness", ...rest } = data;
|
|
67
|
+
return {
|
|
68
|
+
"@type": type,
|
|
69
|
+
...rest
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
function eventJsonLd(data) {
|
|
73
|
+
const { type = "Event", ...rest } = data;
|
|
74
|
+
return {
|
|
75
|
+
"@type": type,
|
|
76
|
+
...rest
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export { articleJsonLd, breadcrumbJsonLd, createJsonLd, createJsonLdGraph, eventJsonLd, faqJsonLd, localBusinessJsonLd, organizationJsonLd, productJsonLd, websiteJsonLd };
|
|
81
|
+
//# sourceMappingURL=index.js.map
|
|
82
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/json-ld/index.ts"],"names":[],"mappings":";AA+WO,SAAS,YAAA,CACZ,QACA,OAAA,EACM;AACN,EAAA,MAAM,IAAA,GAAO;AAAA,IACT,UAAA,EAAY,SAAS,OAAA,IAAW,oBAAA;AAAA,IAChC,GAAG;AAAA,GACP;AAEA,EAAA,OAAO,IAAA,CAAK,UAAU,IAAI,CAAA;AAC9B;AAKO,SAAS,iBAAA,CACZ,SACA,OAAA,EACM;AACN,EAAA,MAAM,IAAA,GAAO;AAAA,IACT,UAAA,EAAY,SAAS,OAAA,IAAW,oBAAA;AAAA,IAChC,QAAA,EAAU;AAAA,GACd;AAEA,EAAA,OAAO,IAAA,CAAK,UAAU,IAAI,CAAA;AAC9B;AAKO,SAAS,mBAAmB,IAAA,EAAiD;AAChF,EAAA,OAAO;AAAA,IACH,OAAA,EAAS,cAAA;AAAA,IACT,GAAG;AAAA,GACP;AACJ;AAKO,SAAS,cAAc,IAAA,EAAuC;AACjE,EAAA,OAAO;AAAA,IACH,OAAA,EAAS,SAAA;AAAA,IACT,GAAG;AAAA,GACP;AACJ;AAKO,SAAS,cACZ,IAAA,EACO;AACP,EAAA,MAAM,EAAE,IAAA,GAAO,SAAA,EAAW,GAAG,MAAK,GAAI,IAAA;AACtC,EAAA,OAAO;AAAA,IACH,OAAA,EAAS,IAAA;AAAA,IACT,GAAG;AAAA,GACP;AACJ;AAKO,SAAS,cAAc,IAAA,EAAuC;AACjE,EAAA,OAAO;AAAA,IACH,OAAA,EAAS,SAAA;AAAA,IACT,GAAG;AAAA,GACP;AACJ;AAKO,SAAS,iBACZ,KAAA,EACc;AACd,EAAA,OAAO;AAAA,IACH,OAAA,EAAS,gBAAA;AAAA,IACT,eAAA,EAAiB,KAAA,CAAM,GAAA,CAAI,CAAC,MAAM,KAAA,MAAW;AAAA,MACzC,OAAA,EAAS,UAAA;AAAA,MACT,UAAU,KAAA,GAAQ,CAAA;AAAA,MAClB,MAAM,IAAA,CAAK,IAAA;AAAA,MACX,MAAM,IAAA,CAAK;AAAA,KACf,CAAE;AAAA,GACN;AACJ;AAKO,SAAS,UACZ,SAAA,EACO;AACP,EAAA,OAAO;AAAA,IACH,OAAA,EAAS,SAAA;AAAA,IACT,UAAA,EAAY,SAAA,CAAU,GAAA,CAAI,CAAA,CAAA,MAAM;AAAA,MAC5B,OAAA,EAAS,UAAA;AAAA,MACT,MAAM,CAAA,CAAE,QAAA;AAAA,MACR,cAAA,EAAgB;AAAA,QACZ,OAAA,EAAS,QAAA;AAAA,QACT,MAAM,CAAA,CAAE;AAAA;AACZ,KACJ,CAAE;AAAA,GACN;AACJ;AAKO,SAAS,oBACZ,IAAA,EACa;AACb,EAAA,MAAM,EAAE,IAAA,GAAO,eAAA,EAAiB,GAAG,MAAK,GAAI,IAAA;AAC5C,EAAA,OAAO;AAAA,IACH,OAAA,EAAS,IAAA;AAAA,IACT,GAAG;AAAA,GACP;AACJ;AAKO,SAAS,YACZ,IAAA,EACK;AACL,EAAA,MAAM,EAAE,IAAA,GAAO,OAAA,EAAS,GAAG,MAAK,GAAI,IAAA;AACpC,EAAA,OAAO;AAAA,IACH,OAAA,EAAS,IAAA;AAAA,IACT,GAAG;AAAA,GACP;AACJ","file":"index.js","sourcesContent":["/**\r\n * @flightdev/seo - JSON-LD Structured Data\r\n *\r\n * Type-safe JSON-LD generation for search engine rich results.\r\n * Supports Schema.org types: Organization, WebSite, Article, Product, etc.\r\n */\r\n\r\n// ============================================================================\r\n// Base Types\r\n// ============================================================================\r\n\r\n/**\r\n * Base JSON-LD thing\r\n */\r\nexport interface Thing {\r\n '@type': string;\r\n '@id'?: string;\r\n name?: string;\r\n description?: string;\r\n url?: string;\r\n image?: string | ImageObject | (string | ImageObject)[];\r\n sameAs?: string[];\r\n}\r\n\r\n/**\r\n * Image object for JSON-LD\r\n */\r\nexport interface ImageObject {\r\n '@type': 'ImageObject';\r\n url: string;\r\n width?: number;\r\n height?: number;\r\n caption?: string;\r\n}\r\n\r\n/**\r\n * Person for JSON-LD\r\n */\r\nexport interface Person extends Thing {\r\n '@type': 'Person';\r\n givenName?: string;\r\n familyName?: string;\r\n email?: string;\r\n jobTitle?: string;\r\n worksFor?: Organization;\r\n}\r\n\r\n/**\r\n * Organization for JSON-LD\r\n */\r\nexport interface Organization extends Thing {\r\n '@type': 'Organization';\r\n logo?: string | ImageObject;\r\n contactPoint?: ContactPoint[];\r\n address?: PostalAddress;\r\n founder?: Person;\r\n foundingDate?: string;\r\n}\r\n\r\n/**\r\n * Contact point\r\n */\r\nexport interface ContactPoint {\r\n '@type': 'ContactPoint';\r\n telephone?: string;\r\n contactType: string;\r\n email?: string;\r\n areaServed?: string | string[];\r\n availableLanguage?: string | string[];\r\n}\r\n\r\n/**\r\n * Postal address\r\n */\r\nexport interface PostalAddress {\r\n '@type': 'PostalAddress';\r\n streetAddress?: string;\r\n addressLocality?: string;\r\n addressRegion?: string;\r\n postalCode?: string;\r\n addressCountry?: string;\r\n}\r\n\r\n// ============================================================================\r\n// WebSite\r\n// ============================================================================\r\n\r\n/**\r\n * WebSite schema\r\n */\r\nexport interface WebSite extends Thing {\r\n '@type': 'WebSite';\r\n potentialAction?: SearchAction;\r\n publisher?: Organization | Person;\r\n}\r\n\r\n/**\r\n * Search action for site search\r\n */\r\nexport interface SearchAction {\r\n '@type': 'SearchAction';\r\n target: string | { '@type': 'EntryPoint'; urlTemplate: string };\r\n 'query-input': string;\r\n}\r\n\r\n// ============================================================================\r\n// WebPage\r\n// ============================================================================\r\n\r\n/**\r\n * WebPage schema\r\n */\r\nexport interface WebPage extends Thing {\r\n '@type': 'WebPage' | 'AboutPage' | 'ContactPage' | 'FAQPage' | 'ItemPage' | 'ProfilePage';\r\n breadcrumb?: BreadcrumbList;\r\n mainEntity?: Thing;\r\n datePublished?: string;\r\n dateModified?: string;\r\n author?: Person | Organization;\r\n publisher?: Organization;\r\n inLanguage?: string;\r\n}\r\n\r\n// ============================================================================\r\n// Article\r\n// ============================================================================\r\n\r\n/**\r\n * Article schema\r\n */\r\nexport interface Article extends Thing {\r\n '@type': 'Article' | 'NewsArticle' | 'BlogPosting' | 'TechArticle';\r\n headline: string;\r\n datePublished: string;\r\n dateModified?: string;\r\n author: Person | Organization | (Person | Organization)[];\r\n publisher: Organization;\r\n mainEntityOfPage?: string | WebPage;\r\n articleSection?: string;\r\n keywords?: string | string[];\r\n wordCount?: number;\r\n}\r\n\r\n// ============================================================================\r\n// Product\r\n// ============================================================================\r\n\r\n/**\r\n * Product schema\r\n */\r\nexport interface Product extends Thing {\r\n '@type': 'Product';\r\n sku?: string;\r\n gtin?: string;\r\n mpn?: string;\r\n brand?: Brand;\r\n offers?: Offer | Offer[];\r\n aggregateRating?: AggregateRating;\r\n review?: Review[];\r\n}\r\n\r\n/**\r\n * Brand\r\n */\r\nexport interface Brand {\r\n '@type': 'Brand';\r\n name: string;\r\n logo?: string;\r\n}\r\n\r\n/**\r\n * Offer (price information)\r\n */\r\nexport interface Offer {\r\n '@type': 'Offer';\r\n price: number | string;\r\n priceCurrency: string;\r\n availability?: 'InStock' | 'OutOfStock' | 'PreOrder' | 'SoldOut' | 'BackOrder' | string;\r\n url?: string;\r\n priceValidUntil?: string;\r\n seller?: Organization;\r\n itemCondition?: 'NewCondition' | 'RefurbishedCondition' | 'UsedCondition' | string;\r\n}\r\n\r\n/**\r\n * Aggregate rating\r\n */\r\nexport interface AggregateRating {\r\n '@type': 'AggregateRating';\r\n ratingValue: number;\r\n reviewCount?: number;\r\n ratingCount?: number;\r\n bestRating?: number;\r\n worstRating?: number;\r\n}\r\n\r\n/**\r\n * Review\r\n */\r\nexport interface Review {\r\n '@type': 'Review';\r\n author: Person | string;\r\n datePublished?: string;\r\n reviewBody?: string;\r\n name?: string;\r\n reviewRating?: Rating;\r\n}\r\n\r\n/**\r\n * Rating\r\n */\r\nexport interface Rating {\r\n '@type': 'Rating';\r\n ratingValue: number;\r\n bestRating?: number;\r\n worstRating?: number;\r\n}\r\n\r\n// ============================================================================\r\n// Breadcrumb\r\n// ============================================================================\r\n\r\n/**\r\n * Breadcrumb list\r\n */\r\nexport interface BreadcrumbList {\r\n '@type': 'BreadcrumbList';\r\n itemListElement: BreadcrumbItem[];\r\n}\r\n\r\n/**\r\n * Breadcrumb item\r\n */\r\nexport interface BreadcrumbItem {\r\n '@type': 'ListItem';\r\n position: number;\r\n name: string;\r\n item?: string;\r\n}\r\n\r\n// ============================================================================\r\n// FAQ\r\n// ============================================================================\r\n\r\n/**\r\n * FAQ Page\r\n */\r\nexport interface FAQPage extends Thing {\r\n '@type': 'FAQPage';\r\n mainEntity: Question[];\r\n}\r\n\r\n/**\r\n * Question\r\n */\r\nexport interface Question {\r\n '@type': 'Question';\r\n name: string;\r\n acceptedAnswer: Answer;\r\n}\r\n\r\n/**\r\n * Answer\r\n */\r\nexport interface Answer {\r\n '@type': 'Answer';\r\n text: string;\r\n}\r\n\r\n// ============================================================================\r\n// Local Business\r\n// ============================================================================\r\n\r\n/**\r\n * Local business\r\n */\r\nexport interface LocalBusiness extends Omit<Organization, '@type'> {\r\n '@type': 'LocalBusiness' | 'Restaurant' | 'Store' | 'MedicalBusiness' | string;\r\n priceRange?: string;\r\n openingHoursSpecification?: OpeningHoursSpecification[];\r\n geo?: GeoCoordinates;\r\n telephone?: string;\r\n hasMap?: string;\r\n}\r\n\r\n\r\n/**\r\n * Opening hours\r\n */\r\nexport interface OpeningHoursSpecification {\r\n '@type': 'OpeningHoursSpecification';\r\n dayOfWeek: string | string[];\r\n opens: string;\r\n closes: string;\r\n}\r\n\r\n/**\r\n * Geo coordinates\r\n */\r\nexport interface GeoCoordinates {\r\n '@type': 'GeoCoordinates';\r\n latitude: number;\r\n longitude: number;\r\n}\r\n\r\n// ============================================================================\r\n// Event\r\n// ============================================================================\r\n\r\n/**\r\n * Event\r\n */\r\nexport interface Event extends Thing {\r\n '@type': 'Event' | 'BusinessEvent' | 'MusicEvent' | 'SportsEvent' | string;\r\n startDate: string;\r\n endDate?: string;\r\n location: Place | VirtualLocation | string;\r\n organizer?: Organization | Person;\r\n performer?: Person | Organization | (Person | Organization)[];\r\n offers?: Offer | Offer[];\r\n eventStatus?: 'EventScheduled' | 'EventCancelled' | 'EventPostponed' | 'EventRescheduled';\r\n eventAttendanceMode?: 'OfflineEventAttendanceMode' | 'OnlineEventAttendanceMode' | 'MixedEventAttendanceMode';\r\n}\r\n\r\n/**\r\n * Place\r\n */\r\nexport interface Place extends Thing {\r\n '@type': 'Place';\r\n address?: PostalAddress | string;\r\n geo?: GeoCoordinates;\r\n}\r\n\r\n/**\r\n * Virtual location\r\n */\r\nexport interface VirtualLocation {\r\n '@type': 'VirtualLocation';\r\n url: string;\r\n}\r\n\r\n// ============================================================================\r\n// Union Type\r\n// ============================================================================\r\n\r\n/**\r\n * All supported JSON-LD schemas\r\n */\r\nexport type JsonLdSchema =\r\n | Organization\r\n | Person\r\n | WebSite\r\n | WebPage\r\n | Article\r\n | Product\r\n | BreadcrumbList\r\n | FAQPage\r\n | LocalBusiness\r\n | Event;\r\n\r\n// ============================================================================\r\n// Builder Functions\r\n// ============================================================================\r\n\r\n/**\r\n * Create JSON-LD script content\r\n */\r\nexport function createJsonLd<T extends JsonLdSchema>(\r\n schema: T,\r\n options?: { context?: string }\r\n): string {\r\n const data = {\r\n '@context': options?.context || 'https://schema.org',\r\n ...schema,\r\n };\r\n\r\n return JSON.stringify(data);\r\n}\r\n\r\n/**\r\n * Create multiple JSON-LD schemas in a graph\r\n */\r\nexport function createJsonLdGraph(\r\n schemas: JsonLdSchema[],\r\n options?: { context?: string }\r\n): string {\r\n const data = {\r\n '@context': options?.context || 'https://schema.org',\r\n '@graph': schemas,\r\n };\r\n\r\n return JSON.stringify(data);\r\n}\r\n\r\n/**\r\n * Create Organization JSON-LD\r\n */\r\nexport function organizationJsonLd(data: Omit<Organization, '@type'>): Organization {\r\n return {\r\n '@type': 'Organization',\r\n ...data,\r\n };\r\n}\r\n\r\n/**\r\n * Create WebSite JSON-LD\r\n */\r\nexport function websiteJsonLd(data: Omit<WebSite, '@type'>): WebSite {\r\n return {\r\n '@type': 'WebSite',\r\n ...data,\r\n };\r\n}\r\n\r\n/**\r\n * Create Article JSON-LD\r\n */\r\nexport function articleJsonLd(\r\n data: Omit<Article, '@type'> & { type?: Article['@type'] }\r\n): Article {\r\n const { type = 'Article', ...rest } = data;\r\n return {\r\n '@type': type,\r\n ...rest,\r\n };\r\n}\r\n\r\n/**\r\n * Create Product JSON-LD\r\n */\r\nexport function productJsonLd(data: Omit<Product, '@type'>): Product {\r\n return {\r\n '@type': 'Product',\r\n ...data,\r\n };\r\n}\r\n\r\n/**\r\n * Create BreadcrumbList JSON-LD\r\n */\r\nexport function breadcrumbJsonLd(\r\n items: Array<{ name: string; url?: string }>\r\n): BreadcrumbList {\r\n return {\r\n '@type': 'BreadcrumbList',\r\n itemListElement: items.map((item, index) => ({\r\n '@type': 'ListItem',\r\n position: index + 1,\r\n name: item.name,\r\n item: item.url,\r\n })),\r\n };\r\n}\r\n\r\n/**\r\n * Create FAQ JSON-LD\r\n */\r\nexport function faqJsonLd(\r\n questions: Array<{ question: string; answer: string }>\r\n): FAQPage {\r\n return {\r\n '@type': 'FAQPage',\r\n mainEntity: questions.map(q => ({\r\n '@type': 'Question',\r\n name: q.question,\r\n acceptedAnswer: {\r\n '@type': 'Answer',\r\n text: q.answer,\r\n },\r\n })),\r\n };\r\n}\r\n\r\n/**\r\n * Create LocalBusiness JSON-LD\r\n */\r\nexport function localBusinessJsonLd(\r\n data: Omit<LocalBusiness, '@type'> & { type?: LocalBusiness['@type'] }\r\n): LocalBusiness {\r\n const { type = 'LocalBusiness', ...rest } = data;\r\n return {\r\n '@type': type,\r\n ...rest,\r\n } as LocalBusiness;\r\n}\r\n\r\n/**\r\n * Create Event JSON-LD\r\n */\r\nexport function eventJsonLd(\r\n data: Omit<Event, '@type'> & { type?: Event['@type'] }\r\n): Event {\r\n const { type = 'Event', ...rest } = data;\r\n return {\r\n '@type': type,\r\n ...rest,\r\n };\r\n}\r\n"]}
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { M as Metadata } from '../types-BBIMJIqz.js';
|
|
3
|
+
import { JsonLdSchema, Article, Product, Organization } from '../json-ld/index.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @flightdev/seo/react
|
|
7
|
+
*
|
|
8
|
+
* React components and hooks for SEO management.
|
|
9
|
+
* SSR-first with client-side hydration support.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```tsx
|
|
13
|
+
* import { SEO, JsonLd } from '@flightdev/seo/react';
|
|
14
|
+
*
|
|
15
|
+
* export default function ProductPage({ product }) {
|
|
16
|
+
* return (
|
|
17
|
+
* <>
|
|
18
|
+
* <SEO
|
|
19
|
+
* title={product.name}
|
|
20
|
+
* description={product.description}
|
|
21
|
+
* openGraph={{ images: [{ url: product.image }] }}
|
|
22
|
+
* />
|
|
23
|
+
* <JsonLd type="Product" data={{ name: product.name }} />
|
|
24
|
+
* <main>...</main>
|
|
25
|
+
* </>
|
|
26
|
+
* );
|
|
27
|
+
* }
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
|
|
31
|
+
interface SEOContextValue {
|
|
32
|
+
metadata: Metadata;
|
|
33
|
+
setMetadata: (metadata: Metadata) => void;
|
|
34
|
+
addMetadata: (metadata: Metadata) => void;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* SEO Provider for managing metadata across the component tree
|
|
38
|
+
*/
|
|
39
|
+
declare function SEOProvider({ children, defaultMetadata, }: {
|
|
40
|
+
children: React.ReactNode;
|
|
41
|
+
defaultMetadata?: Metadata;
|
|
42
|
+
}): React.FunctionComponentElement<React.ProviderProps<SEOContextValue | null>>;
|
|
43
|
+
/**
|
|
44
|
+
* Hook to access SEO context
|
|
45
|
+
*/
|
|
46
|
+
declare function useSEOContext(): SEOContextValue | null;
|
|
47
|
+
interface SEOProps extends Metadata {
|
|
48
|
+
children?: React.ReactNode;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* SEO component for setting page metadata
|
|
52
|
+
*
|
|
53
|
+
* On the server, this renders meta tags directly.
|
|
54
|
+
* On the client, this updates document.head.
|
|
55
|
+
*
|
|
56
|
+
* @example
|
|
57
|
+
* ```tsx
|
|
58
|
+
* <SEO
|
|
59
|
+
* title="Product Name"
|
|
60
|
+
* description="Product description"
|
|
61
|
+
* openGraph={{ type: 'product', images: [{ url: '/product.jpg' }] }}
|
|
62
|
+
* twitter={{ card: 'summary_large_image' }}
|
|
63
|
+
* />
|
|
64
|
+
* ```
|
|
65
|
+
*/
|
|
66
|
+
declare function SEO(props: SEOProps): React.ReactElement | null;
|
|
67
|
+
interface HeadProps {
|
|
68
|
+
children?: React.ReactNode;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Head component for injecting arbitrary tags into document head
|
|
72
|
+
*
|
|
73
|
+
* @example
|
|
74
|
+
* ```tsx
|
|
75
|
+
* <Head>
|
|
76
|
+
* <link rel="preconnect" href="https://fonts.googleapis.com" />
|
|
77
|
+
* <meta name="custom" content="value" />
|
|
78
|
+
* </Head>
|
|
79
|
+
* ```
|
|
80
|
+
*/
|
|
81
|
+
declare function Head({ children }: HeadProps): React.ReactElement | null;
|
|
82
|
+
interface JsonLdProps<T extends JsonLdSchema = JsonLdSchema> {
|
|
83
|
+
/** JSON-LD data */
|
|
84
|
+
data: T;
|
|
85
|
+
/** Script ID for deduplication */
|
|
86
|
+
id?: string;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* JsonLd component for structured data
|
|
90
|
+
*
|
|
91
|
+
* @example
|
|
92
|
+
* ```tsx
|
|
93
|
+
* <JsonLd
|
|
94
|
+
* id="product"
|
|
95
|
+
* data={{
|
|
96
|
+
* '@type': 'Product',
|
|
97
|
+
* name: 'Widget',
|
|
98
|
+
* offers: { price: 9.99, priceCurrency: 'USD' }
|
|
99
|
+
* }}
|
|
100
|
+
* />
|
|
101
|
+
* ```
|
|
102
|
+
*/
|
|
103
|
+
declare function JsonLd<T extends JsonLdSchema>({ data, id, }: JsonLdProps<T>): React.ReactElement;
|
|
104
|
+
/**
|
|
105
|
+
* Article JSON-LD component
|
|
106
|
+
*/
|
|
107
|
+
declare function ArticleJsonLd(props: Omit<Article, '@type'> & {
|
|
108
|
+
type?: Article['@type'];
|
|
109
|
+
}): React.ReactElement;
|
|
110
|
+
/**
|
|
111
|
+
* Product JSON-LD component
|
|
112
|
+
*/
|
|
113
|
+
declare function ProductJsonLd(props: Omit<Product, '@type'>): React.ReactElement;
|
|
114
|
+
/**
|
|
115
|
+
* Organization JSON-LD component
|
|
116
|
+
*/
|
|
117
|
+
declare function OrganizationJsonLd(props: Omit<Organization, '@type'>): React.ReactElement;
|
|
118
|
+
/**
|
|
119
|
+
* Breadcrumb JSON-LD component
|
|
120
|
+
*/
|
|
121
|
+
declare function BreadcrumbJsonLd({ items }: {
|
|
122
|
+
items: Array<{
|
|
123
|
+
name: string;
|
|
124
|
+
url?: string;
|
|
125
|
+
}>;
|
|
126
|
+
}): React.ReactElement;
|
|
127
|
+
/**
|
|
128
|
+
* FAQ JSON-LD component
|
|
129
|
+
*/
|
|
130
|
+
declare function FAQJsonLd({ questions }: {
|
|
131
|
+
questions: Array<{
|
|
132
|
+
question: string;
|
|
133
|
+
answer: string;
|
|
134
|
+
}>;
|
|
135
|
+
}): React.ReactElement;
|
|
136
|
+
/**
|
|
137
|
+
* Hook for managing SEO metadata
|
|
138
|
+
*
|
|
139
|
+
* @example
|
|
140
|
+
* ```tsx
|
|
141
|
+
* function ProductPage({ product }) {
|
|
142
|
+
* useSEO({
|
|
143
|
+
* title: product.name,
|
|
144
|
+
* description: product.description,
|
|
145
|
+
* });
|
|
146
|
+
*
|
|
147
|
+
* return <div>...</div>;
|
|
148
|
+
* }
|
|
149
|
+
* ```
|
|
150
|
+
*/
|
|
151
|
+
declare function useSEO(metadata: Metadata): void;
|
|
152
|
+
/**
|
|
153
|
+
* Render metadata to HTML string for SSR
|
|
154
|
+
*/
|
|
155
|
+
declare function renderMetadataToString(metadata: Metadata): string;
|
|
156
|
+
/**
|
|
157
|
+
* Create metadata from props for SSR
|
|
158
|
+
*/
|
|
159
|
+
declare function createMetadataFromProps(props: SEOProps): Metadata;
|
|
160
|
+
|
|
161
|
+
export { ArticleJsonLd, BreadcrumbJsonLd, FAQJsonLd, Head, type HeadProps, JsonLd, type JsonLdProps, OrganizationJsonLd, ProductJsonLd, SEO, type SEOProps, SEOProvider, createMetadataFromProps, renderMetadataToString, useSEO, useSEOContext };
|