next-seo
Version:
SEO plugin for Next.js projects
1,744 lines (1,735 loc) • 105 kB
JavaScript
var __defProp = Object.defineProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
// src/utils/stringify.ts
var safeJsonLdReplacer = /* @__PURE__ */ (() => {
return (_, value) => {
switch (typeof value) {
case "object":
if (value === null) {
return void 0;
}
return value;
// JSON.stringify will recursively call replacer.
case "number":
case "boolean":
case "bigint":
case "string":
return value;
// Return all primitive values as-is
default: {
isNever(value);
return void 0;
}
}
};
})();
function isNever(_) {
}
var stringify = (data) => {
const jsonString = JSON.stringify(data, safeJsonLdReplacer);
return jsonString.replace(/<\/script>/gi, "\\u003C/script>").replace(/<!--/g, "\\u003C!--").replace(/-->/g, "--\\u003E");
};
// src/core/JsonLdScript.tsx
import { jsx } from "react/jsx-runtime";
function JsonLdScript({
data,
id,
scriptKey
}) {
if (data === null || data === void 0) {
return null;
}
const jsonString = stringify(data);
return /* @__PURE__ */ jsx(
"script",
{
type: "application/ld+json",
id: id || scriptKey,
"data-testid": id,
dangerouslySetInnerHTML: { __html: jsonString }
},
scriptKey
);
}
// src/utils/processors.export.ts
var processors_export_exports = {};
__export(processors_export_exports, {
processAccommodation: () => processAccommodation,
processAddress: () => processAddress,
processAggregateOffer: () => processAggregateOffer,
processAggregateRating: () => processAggregateRating,
processAppearance: () => processAppearance,
processApplicantLocationRequirements: () => processApplicantLocationRequirements,
processAuthor: () => processAuthor,
processBedDetails: () => processBedDetails,
processBrand: () => processBrand,
processBreadcrumbItem: () => processBreadcrumbItem,
processBroadcastEvent: () => processBroadcastEvent,
processCertification: () => processCertification,
processClaim: () => processClaim,
processClaimReviewRating: () => processClaimReviewRating,
processClip: () => processClip,
processComment: () => processComment,
processContactPoint: () => processContactPoint,
processCreator: () => processCreator,
processDataCatalog: () => processDataCatalog,
processDataDownload: () => processDataDownload,
processDefinedRegion: () => processDefinedRegion,
processDirector: () => processDirector,
processEducationRequirements: () => processEducationRequirements,
processEstimatedCost: () => processEstimatedCost,
processExperienceRequirements: () => processExperienceRequirements,
processFeatureList: () => processFeatureList,
processFunder: () => processFunder,
processGeo: () => processGeo,
processHiringOrganization: () => processHiringOrganization,
processHowToDirection: () => processHowToDirection,
processHowToSection: () => processHowToSection,
processHowToStep: () => processHowToStep,
processHowToSupply: () => processHowToSupply,
processHowToTip: () => processHowToTip,
processHowToTool: () => processHowToTool,
processHowToYield: () => processHowToYield,
processIdentifier: () => processIdentifier,
processImage: () => processImage,
processInstruction: () => processInstruction,
processInteractionStatistic: () => processInteractionStatistic,
processIsPartOf: () => processIsPartOf,
processItemReviewed: () => processItemReviewed,
processJobLocation: () => processJobLocation,
processJobPropertyValue: () => processJobPropertyValue,
processLicense: () => processLicense,
processLocationFeatureSpecification: () => processLocationFeatureSpecification,
processLogo: () => processLogo,
processMainEntityOfPage: () => processMainEntityOfPage,
processMemberProgram: () => processMemberProgram,
processMemberProgramTier: () => processMemberProgramTier,
processMembershipPointsEarned: () => processMembershipPointsEarned,
processMerchantReturnPolicy: () => processMerchantReturnPolicy,
processMonetaryAmount: () => processMonetaryAmount,
processNumberOfEmployees: () => processNumberOfEmployees,
processNutrition: () => processNutrition,
processOffer: () => processOffer,
processOfferShippingDetails: () => processOfferShippingDetails,
processOpeningHours: () => processOpeningHours,
processOrganization: () => processOrganization,
processOrganizer: () => processOrganizer,
processPeopleAudience: () => processPeopleAudience,
processPerformer: () => processPerformer,
processPlace: () => processPlace,
processPriceSpecification: () => processPriceSpecification,
processProductItemList: () => processProductItemList,
processProductOffer: () => processProductOffer,
processProductReview: () => processProductReview,
processProductVariant: () => processProductVariant,
processProvider: () => processProvider,
processPublisher: () => processPublisher,
processQuantitativeValue: () => processQuantitativeValue,
processRating: () => processRating,
processReturnPolicySeasonalOverride: () => processReturnPolicySeasonalOverride,
processReview: () => processReview,
processSchemaType: () => processSchemaType,
processScreenshot: () => processScreenshot,
processSeekToAction: () => processSeekToAction,
processSharedContent: () => processSharedContent,
processShippingDeliveryTime: () => processShippingDeliveryTime,
processSimpleMonetaryAmount: () => processSimpleMonetaryAmount,
processSizeSpecification: () => processSizeSpecification,
processSpatialCoverage: () => processSpatialCoverage,
processStep: () => processStep,
processThreeDModel: () => processThreeDModel,
processTierBenefit: () => processTierBenefit,
processTierRequirement: () => processTierRequirement,
processUnitPriceSpecification: () => processUnitPriceSpecification,
processVariesBy: () => processVariesBy,
processVideo: () => processVideo,
processWebPageElement: () => processWebPageElement
});
// src/utils/processors.ts
var SCHEMA_TYPES = {
PERSON: "Person",
ORGANIZATION: "Organization",
IMAGE_OBJECT: "ImageObject",
POSTAL_ADDRESS: "PostalAddress",
CONTACT_POINT: "ContactPoint",
QUANTITATIVE_VALUE: "QuantitativeValue",
GEO_COORDINATES: "GeoCoordinates",
GEO_SHAPE: "GeoShape",
OPENING_HOURS: "OpeningHoursSpecification",
REVIEW: "Review",
RATING: "Rating",
AGGREGATE_RATING: "AggregateRating",
MERCHANT_RETURN_POLICY: "MerchantReturnPolicy",
MERCHANT_RETURN_POLICY_SEASONAL_OVERRIDE: "MerchantReturnPolicySeasonalOverride",
MONETARY_AMOUNT: "MonetaryAmount",
VIDEO_OBJECT: "VideoObject",
INTERACTION_COUNTER: "InteractionCounter",
BRAND: "Brand",
CREDIT_CARD: "CreditCard",
UNIT_PRICE_SPECIFICATION: "UnitPriceSpecification",
MEMBER_PROGRAM: "MemberProgram",
MEMBER_PROGRAM_TIER: "MemberProgramTier",
BED_DETAILS: "BedDetails",
LOCATION_FEATURE: "LocationFeatureSpecification",
ACCOMMODATION: "Accommodation",
PLACE: "Place",
PERFORMING_GROUP: "PerformingGroup",
OFFER: "Offer",
AGGREGATE_OFFER: "AggregateOffer",
PRICE_SPECIFICATION: "PriceSpecification",
ITEM_LIST: "ItemList",
LIST_ITEM: "ListItem",
PRODUCT: "Product",
PRODUCT_GROUP: "ProductGroup",
NUTRITION_INFORMATION: "NutritionInformation",
HOW_TO_STEP: "HowToStep",
HOW_TO_SECTION: "HowToSection",
HOW_TO_SUPPLY: "HowToSupply",
HOW_TO_TOOL: "HowToTool",
HOW_TO_DIRECTION: "HowToDirection",
HOW_TO_TIP: "HowToTip",
PROPERTY_VALUE: "PropertyValue",
CREATIVE_WORK: "CreativeWork",
DATA_DOWNLOAD: "DataDownload",
DATA_CATALOG: "DataCatalog",
COUNTRY: "Country",
STATE: "State",
EDUCATIONAL_CREDENTIAL: "EducationalOccupationalCredential",
OCCUPATIONAL_EXPERIENCE: "OccupationalExperienceRequirements",
COMMENT: "Comment",
WEB_PAGE: "WebPage",
WEB_PAGE_ELEMENT: "WebPageElement",
CLAIM: "Claim",
CERTIFICATION: "Certification",
PEOPLE_AUDIENCE: "PeopleAudience",
SIZE_SPECIFICATION: "SizeSpecification",
THREE_D_MODEL: "3DModel",
DEFINED_REGION: "DefinedRegion",
SHIPPING_DELIVERY_TIME: "ShippingDeliveryTime",
OFFER_SHIPPING_DETAILS: "OfferShippingDetails"
};
function hasType(obj) {
return obj !== null && typeof obj === "object" && "@type" in obj;
}
function isString(value) {
return typeof value === "string";
}
function processSchemaType(value, schemaType, stringHandler, numberHandler) {
if (isString(value) && stringHandler) {
return { "@type": schemaType, ...stringHandler(value) };
}
if (typeof value === "number" && numberHandler) {
return { "@type": schemaType, ...numberHandler(value) };
}
if (hasType(value)) {
return value;
}
if (typeof value === "object" && value !== null) {
return { "@type": schemaType, ...value };
}
return { "@type": schemaType };
}
function processOrganizationFields(org) {
if (org.logo && !isString(org.logo)) {
org.logo = processLogo(org.logo);
}
if (org.address && !isString(org.address)) {
if (Array.isArray(org.address)) {
org.address = org.address.map(
(addr) => isString(addr) ? addr : processAddress(addr)
);
} else {
org.address = processAddress(org.address);
}
}
if (org.contactPoint) {
if (Array.isArray(org.contactPoint)) {
org.contactPoint = org.contactPoint.map(processContactPoint);
} else {
org.contactPoint = processContactPoint(org.contactPoint);
}
}
}
function processAuthor(author) {
if (isString(author)) {
const orgIndicators = [
"magazine",
"publication",
"company",
"corporation",
"corp",
"inc",
"llc",
"ltd",
"limited",
"group",
"foundation",
"institute",
"association",
"society",
"union",
"times",
"news",
"press",
"media",
"network",
"agency",
"studio"
];
const lowerName = author.toLowerCase();
const isLikelyOrg = orgIndicators.some(
(indicator) => lowerName.includes(indicator)
);
if (isLikelyOrg) {
return {
"@type": SCHEMA_TYPES.ORGANIZATION,
name: author
};
}
return {
"@type": SCHEMA_TYPES.PERSON,
name: author
};
}
if (hasType(author)) {
return author;
}
const hasOrgProperties = "logo" in author || "address" in author || "contactPoint" in author;
if (hasOrgProperties) {
const org = {
"@type": SCHEMA_TYPES.ORGANIZATION,
...author
};
processOrganizationFields(org);
return org;
}
return {
"@type": SCHEMA_TYPES.PERSON,
...author
};
}
function processImage(image) {
if (isString(image)) {
return image;
}
return processSchemaType(image, SCHEMA_TYPES.IMAGE_OBJECT);
}
function processAddress(address) {
return processSchemaType(
address,
SCHEMA_TYPES.POSTAL_ADDRESS,
(str) => ({ streetAddress: str }),
void 0
);
}
function processContactPoint(contactPoint) {
return processSchemaType(
contactPoint,
SCHEMA_TYPES.CONTACT_POINT
);
}
function processLogo(logo) {
return processImage(logo);
}
function processNumberOfEmployees(numberOfEmployees) {
return processSchemaType(
numberOfEmployees,
SCHEMA_TYPES.QUANTITATIVE_VALUE,
void 0,
(num) => ({ value: num })
);
}
function processGeo(geo) {
return processSchemaType(geo, SCHEMA_TYPES.GEO_COORDINATES);
}
function processOpeningHours(hours) {
return processSchemaType(
hours,
SCHEMA_TYPES.OPENING_HOURS
);
}
function processReview(review) {
const processed = processSchemaType(
review,
SCHEMA_TYPES.REVIEW
);
if (review.reviewRating) {
processed.reviewRating = processSchemaType(
review.reviewRating,
SCHEMA_TYPES.RATING
);
}
if (review.author) {
processed.author = processAuthor(review.author);
}
return processed;
}
function processBreadcrumbItem(item, position) {
return {
"@type": SCHEMA_TYPES.LIST_ITEM,
position,
...item.name && { name: item.name },
...item.item && { item: item.item }
};
}
function processPlace(location) {
return processSchemaType(
location,
SCHEMA_TYPES.PLACE,
(str) => ({
name: str,
address: {
"@type": SCHEMA_TYPES.POSTAL_ADDRESS,
streetAddress: str
}
}),
void 0
);
}
function processPerformer(performer) {
if (isString(performer)) {
return {
"@type": SCHEMA_TYPES.PERFORMING_GROUP,
name: performer
};
}
if (hasType(performer)) {
return performer;
}
const hasPersonProperties = "familyName" in performer || "givenName" in performer || "additionalName" in performer;
return hasPersonProperties ? { "@type": SCHEMA_TYPES.PERSON, ...performer } : {
"@type": SCHEMA_TYPES.PERFORMING_GROUP,
...performer
};
}
function processOrganizer(organizer) {
if (isString(organizer)) {
return {
"@type": SCHEMA_TYPES.ORGANIZATION,
name: organizer
};
}
if (hasType(organizer)) {
return organizer;
}
const hasPersonProperties = "familyName" in organizer || "givenName" in organizer || "additionalName" in organizer;
return hasPersonProperties ? { "@type": SCHEMA_TYPES.PERSON, ...organizer } : { "@type": SCHEMA_TYPES.ORGANIZATION, ...organizer };
}
function processOrganization(org) {
if (isString(org)) {
return {
"@type": SCHEMA_TYPES.ORGANIZATION,
name: org
};
}
const processed = processSchemaType(
org,
SCHEMA_TYPES.ORGANIZATION
);
processOrganizationFields(processed);
return processed;
}
function processOffer(offer) {
return processSchemaType(offer, SCHEMA_TYPES.OFFER);
}
function processPublisher(publisher) {
if (isString(publisher)) {
return {
"@type": SCHEMA_TYPES.ORGANIZATION,
name: publisher
};
}
if (hasType(publisher) && publisher["@type"] === SCHEMA_TYPES.ORGANIZATION) {
const org2 = { ...publisher };
processOrganizationFields(org2);
return org2;
}
if (hasType(publisher)) {
return publisher;
}
const org = {
"@type": SCHEMA_TYPES.ORGANIZATION,
...publisher
};
processOrganizationFields(org);
return org;
}
function processNutrition(nutrition) {
return {
"@type": SCHEMA_TYPES.NUTRITION_INFORMATION,
...nutrition
};
}
function processAggregateRating(rating) {
return processSchemaType(
rating,
SCHEMA_TYPES.AGGREGATE_RATING
);
}
function processMainEntityOfPage(mainEntityOfPage) {
if (isString(mainEntityOfPage)) {
return mainEntityOfPage;
}
return processSchemaType(mainEntityOfPage, SCHEMA_TYPES.WEB_PAGE);
}
function processSimpleMonetaryAmount(amount) {
if (!amount) return void 0;
if (typeof amount === "number") {
return {
"@type": SCHEMA_TYPES.MONETARY_AMOUNT,
value: amount,
currency: "USD"
// Default currency, should be overridden in component
};
}
return processSchemaType(
amount,
SCHEMA_TYPES.MONETARY_AMOUNT
);
}
function processReturnPolicySeasonalOverride(override) {
return processSchemaType(
override,
SCHEMA_TYPES.MERCHANT_RETURN_POLICY_SEASONAL_OVERRIDE
);
}
function processMerchantReturnPolicy(policy) {
if (!policy) return policy;
const processed = processSchemaType(
policy,
SCHEMA_TYPES.MERCHANT_RETURN_POLICY
);
if (processed.applicableCountry && !Array.isArray(processed.applicableCountry)) {
processed.applicableCountry = [processed.applicableCountry];
}
if (processed.returnPolicyCountry && !Array.isArray(processed.returnPolicyCountry)) {
processed.returnPolicyCountry = [processed.returnPolicyCountry];
}
if (processed.returnMethod && !Array.isArray(processed.returnMethod)) {
processed.returnMethod = [processed.returnMethod];
}
if (processed.refundType && !Array.isArray(processed.refundType)) {
processed.refundType = [processed.refundType];
}
if (processed.itemCondition && !Array.isArray(processed.itemCondition)) {
processed.itemCondition = [processed.itemCondition];
}
if (processed.returnShippingFeesAmount) {
processed.returnShippingFeesAmount = processSimpleMonetaryAmount(
processed.returnShippingFeesAmount
);
}
if (processed.customerRemorseReturnShippingFeesAmount) {
processed.customerRemorseReturnShippingFeesAmount = processSimpleMonetaryAmount(
processed.customerRemorseReturnShippingFeesAmount
);
}
if (processed.itemDefectReturnShippingFeesAmount) {
processed.itemDefectReturnShippingFeesAmount = processSimpleMonetaryAmount(
processed.itemDefectReturnShippingFeesAmount
);
}
if (processed.restockingFee && typeof processed.restockingFee === "object") {
processed.restockingFee = processSimpleMonetaryAmount(
processed.restockingFee
);
}
if (processed.returnPolicySeasonalOverride) {
if (Array.isArray(processed.returnPolicySeasonalOverride)) {
processed.returnPolicySeasonalOverride = processed.returnPolicySeasonalOverride.map(
processReturnPolicySeasonalOverride
);
} else {
processed.returnPolicySeasonalOverride = processReturnPolicySeasonalOverride(
processed.returnPolicySeasonalOverride
);
}
}
return processed;
}
function processTierRequirement(requirement) {
if (!requirement) return requirement;
if (isString(requirement)) {
return requirement;
}
if (hasType(requirement)) {
return requirement;
}
if ("priceCurrency" in requirement && "price" in requirement) {
if ("billingDuration" in requirement || "billingIncrement" in requirement || "unitCode" in requirement) {
return {
"@type": SCHEMA_TYPES.UNIT_PRICE_SPECIFICATION,
...requirement
};
}
}
if ("value" in requirement && "currency" in requirement) {
return {
"@type": SCHEMA_TYPES.MONETARY_AMOUNT,
...requirement
};
}
if ("name" in requirement) {
return {
"@type": SCHEMA_TYPES.CREDIT_CARD,
...requirement
};
}
return requirement;
}
function processTierBenefit(benefit) {
const normalizeBenefit = (b) => {
if (b.startsWith("https://schema.org/")) {
return b;
}
if (b === "TierBenefitLoyaltyPoints") {
return "https://schema.org/TierBenefitLoyaltyPoints";
}
if (b === "TierBenefitLoyaltyPrice") {
return "https://schema.org/TierBenefitLoyaltyPrice";
}
return b;
};
if (Array.isArray(benefit)) {
return benefit.map(normalizeBenefit);
}
return normalizeBenefit(benefit);
}
function processMembershipPointsEarned(points) {
if (typeof points === "number") {
return {
"@type": SCHEMA_TYPES.QUANTITATIVE_VALUE,
value: points
};
}
return processSchemaType(
points,
SCHEMA_TYPES.QUANTITATIVE_VALUE
);
}
function processMemberProgramTier(tier) {
const processed = processSchemaType(
tier,
SCHEMA_TYPES.MEMBER_PROGRAM_TIER
);
if (processed.hasTierBenefit) {
processed.hasTierBenefit = processTierBenefit(processed.hasTierBenefit);
}
if (processed.hasTierRequirement) {
processed.hasTierRequirement = processTierRequirement(
processed.hasTierRequirement
);
}
if (processed.membershipPointsEarned !== void 0) {
processed.membershipPointsEarned = processMembershipPointsEarned(
processed.membershipPointsEarned
);
}
return processed;
}
function processMemberProgram(program) {
const processed = processSchemaType(
program,
SCHEMA_TYPES.MEMBER_PROGRAM
);
if (processed.hasTiers) {
if (Array.isArray(processed.hasTiers)) {
processed.hasTiers = processed.hasTiers.map(processMemberProgramTier);
} else {
processed.hasTiers = processMemberProgramTier(processed.hasTiers);
}
}
return processed;
}
function processVideo(video) {
return processSchemaType(video, SCHEMA_TYPES.VIDEO_OBJECT);
}
function processBroadcastEvent(broadcast) {
if (!broadcast) return broadcast;
if (typeof broadcast === "object" && !("@type" in broadcast)) {
return {
"@type": "BroadcastEvent",
...broadcast
};
}
return broadcast;
}
function processClip(clip) {
if (!clip) return clip;
if (typeof clip === "object" && !("@type" in clip)) {
return {
"@type": "Clip",
...clip
};
}
return clip;
}
function processSeekToAction(action) {
if (!action) return action;
if (typeof action === "object" && !("@type" in action)) {
return {
"@type": "SeekToAction",
...action
};
}
return action;
}
function processInstruction(instruction) {
if (isString(instruction)) {
return instruction;
}
if (hasType(instruction)) {
if (instruction["@type"] === SCHEMA_TYPES.HOW_TO_SECTION && "itemListElement" in instruction) {
return {
...instruction,
itemListElement: instruction.itemListElement.map(
(item) => processInstruction(item)
)
};
}
return instruction;
}
if ("itemListElement" in instruction) {
return {
"@type": SCHEMA_TYPES.HOW_TO_SECTION,
...instruction,
itemListElement: instruction.itemListElement.map(
(item) => processInstruction(item)
)
};
}
return {
"@type": SCHEMA_TYPES.HOW_TO_STEP,
...instruction
};
}
function processDirector(director) {
return processSchemaType(
director,
SCHEMA_TYPES.PERSON,
(str) => ({ name: str }),
void 0
);
}
function processCreator(creator) {
return Array.isArray(creator) ? creator.map(processAuthor) : processAuthor(creator);
}
function processIdentifier(identifier) {
if (isString(identifier)) {
return identifier;
}
return processSchemaType(
identifier,
SCHEMA_TYPES.PROPERTY_VALUE
);
}
function processSpatialCoverage(spatial) {
if (isString(spatial)) {
return spatial;
}
const processed = processSchemaType(
spatial,
SCHEMA_TYPES.PLACE
);
if (spatial.geo && typeof spatial.geo === "object" && !hasType(spatial.geo)) {
if ("latitude" in spatial.geo && "longitude" in spatial.geo) {
processed.geo = processSchemaType(
spatial.geo,
SCHEMA_TYPES.GEO_COORDINATES
);
} else if ("box" in spatial.geo || "circle" in spatial.geo || "line" in spatial.geo || "polygon" in spatial.geo) {
processed.geo = processSchemaType(
spatial.geo,
SCHEMA_TYPES.GEO_SHAPE
);
}
}
return processed;
}
function processDataDownload(download) {
return processSchemaType(download, SCHEMA_TYPES.DATA_DOWNLOAD);
}
function processLicense(license) {
if (isString(license)) {
return license;
}
return processSchemaType(license, SCHEMA_TYPES.CREATIVE_WORK);
}
function processDataCatalog(catalog) {
return processSchemaType(catalog, SCHEMA_TYPES.DATA_CATALOG);
}
function processHiringOrganization(org) {
if (isString(org)) {
return {
"@type": SCHEMA_TYPES.ORGANIZATION,
name: org
};
}
const processed = processSchemaType(
org,
SCHEMA_TYPES.ORGANIZATION
);
if (processed.logo && !isString(processed.logo)) {
processed.logo = processImage(processed.logo);
}
return processed;
}
function processJobLocation(location) {
if (isString(location)) {
return {
"@type": SCHEMA_TYPES.PLACE,
address: {
"@type": SCHEMA_TYPES.POSTAL_ADDRESS,
streetAddress: location
}
};
}
const processed = processSchemaType(location, SCHEMA_TYPES.PLACE);
if (processed.address && !isString(processed.address)) {
processed.address = processAddress(processed.address);
}
return processed;
}
function processMonetaryAmount(amount) {
const processed = processSchemaType(amount, "MonetaryAmount");
processed.value = processSchemaType(
amount.value,
SCHEMA_TYPES.QUANTITATIVE_VALUE
);
return processed;
}
function processRating(rating) {
return processSchemaType(rating, SCHEMA_TYPES.RATING);
}
function processJobPropertyValue(identifier) {
return processSchemaType(
identifier,
SCHEMA_TYPES.PROPERTY_VALUE,
(str) => ({ value: str }),
void 0
);
}
function processApplicantLocationRequirements(location) {
if (hasType(location)) {
return location;
}
const name = location.name;
const statePatterns = [
/\b[A-Z]{2}\b/,
// Two-letter state codes
/\bstate\b/i,
// Contains "state"
/,/,
// Contains comma (often "City, State")
/\b(AL|AK|AZ|AR|CA|CO|CT|DE|FL|GA|HI|ID|IL|IN|IA|KS|KY|LA|ME|MD|MA|MI|MN|MS|MO|MT|NE|NV|NH|NJ|NM|NY|NC|ND|OH|OK|OR|PA|RI|SC|SD|TN|TX|UT|VT|VA|WA|WV|WI|WY)\b/
// US state codes
];
const isState = statePatterns.some((pattern) => pattern.test(name));
return {
"@type": isState ? SCHEMA_TYPES.STATE : SCHEMA_TYPES.COUNTRY,
...location
};
}
function processEducationRequirements(education) {
if (isString(education)) {
return education;
}
return processSchemaType(
education,
SCHEMA_TYPES.EDUCATIONAL_CREDENTIAL
);
}
function processExperienceRequirements(experience) {
if (isString(experience)) {
return experience;
}
return processSchemaType(
experience,
SCHEMA_TYPES.OCCUPATIONAL_EXPERIENCE
);
}
function processInteractionStatistic(statistic) {
return processSchemaType(
statistic,
SCHEMA_TYPES.INTERACTION_COUNTER
);
}
function processSharedContent(content) {
if (isString(content)) {
return {
"@type": SCHEMA_TYPES.WEB_PAGE,
url: content
};
}
if (hasType(content)) {
return content;
}
const hasVideoProperties = "uploadDate" in content && "thumbnailUrl" in content;
const hasImageProperties = "url" in content && ("width" in content || "height" in content);
if (hasVideoProperties) {
return processSchemaType(content, SCHEMA_TYPES.VIDEO_OBJECT);
}
if (hasImageProperties) {
return processSchemaType(content, SCHEMA_TYPES.IMAGE_OBJECT);
}
return processSchemaType(content, SCHEMA_TYPES.WEB_PAGE);
}
function processComment(comment) {
const processed = processSchemaType(
comment,
SCHEMA_TYPES.COMMENT
);
if (comment.author) {
processed.author = processAuthor(comment.author);
}
if (comment.image && !isString(comment.image)) {
processed.image = processImage(comment.image);
}
if (comment.video) {
processed.video = processVideo(comment.video);
}
if (comment.interactionStatistic) {
processed.interactionStatistic = Array.isArray(comment.interactionStatistic) ? comment.interactionStatistic.map(processInteractionStatistic) : processInteractionStatistic(comment.interactionStatistic);
}
if (comment.sharedContent) {
processed.sharedContent = processSharedContent(comment.sharedContent);
}
if (comment.comment) {
processed.comment = comment.comment.map(processComment);
}
return processed;
}
function processIsPartOf(isPartOf) {
if (isString(isPartOf)) {
return isPartOf;
}
return processSchemaType(
isPartOf,
SCHEMA_TYPES.CREATIVE_WORK
);
}
function processBrand(brand) {
if ("@type" in brand) {
return brand;
}
if ("logo" in brand || "address" in brand || "contactPoint" in brand) {
const org = {
"@type": SCHEMA_TYPES.ORGANIZATION,
...brand
};
processOrganizationFields(org);
return org;
}
return processSchemaType(brand, SCHEMA_TYPES.BRAND);
}
function processBedDetails(bed) {
return processSchemaType(bed, SCHEMA_TYPES.BED_DETAILS);
}
function processLocationFeatureSpecification(feature) {
return processSchemaType(
feature,
SCHEMA_TYPES.LOCATION_FEATURE
);
}
function processAccommodation(accommodation) {
const processed = processSchemaType(
accommodation,
SCHEMA_TYPES.ACCOMMODATION
);
if (accommodation.bed) {
processed.bed = Array.isArray(accommodation.bed) ? accommodation.bed.map(processBedDetails) : processBedDetails(accommodation.bed);
}
if (accommodation.occupancy) {
processed.occupancy = processNumberOfEmployees(
accommodation.occupancy
);
}
if (accommodation.amenityFeature) {
processed.amenityFeature = Array.isArray(accommodation.amenityFeature) ? accommodation.amenityFeature.map(processLocationFeatureSpecification) : processLocationFeatureSpecification(accommodation.amenityFeature);
}
if (accommodation.floorSize) {
processed.floorSize = processNumberOfEmployees(
accommodation.floorSize
);
}
return processed;
}
function processProvider(provider) {
return processSchemaType(
provider,
SCHEMA_TYPES.ORGANIZATION,
(str) => ({ name: str }),
void 0
);
}
function processFunder(funder) {
if (Array.isArray(funder)) {
return funder.map(processFunderSingle);
}
return processFunderSingle(funder);
}
function processFunderSingle(funder) {
if (isString(funder)) {
return {
"@type": SCHEMA_TYPES.ORGANIZATION,
name: funder
};
}
if (hasType(funder)) {
return funder;
}
return {
"@type": SCHEMA_TYPES.ORGANIZATION,
...funder
};
}
function processScreenshot(screenshot) {
return processImage(screenshot);
}
function processFeatureList(features) {
return features;
}
function processClaimReviewRating(rating) {
return processSchemaType(rating, SCHEMA_TYPES.RATING);
}
function processClaim(claim) {
const processed = processSchemaType(claim, SCHEMA_TYPES.CLAIM);
if (claim.author) {
processed.author = processAuthor(claim.author);
}
if (claim.appearance) {
if (Array.isArray(claim.appearance)) {
processed.appearance = claim.appearance.map(processAppearance);
} else {
processed.appearance = processAppearance(claim.appearance);
}
}
if (claim.firstAppearance) {
processed.firstAppearance = processAppearance(claim.firstAppearance);
}
return processed;
}
function processAppearance(appearance) {
if (isString(appearance)) {
return appearance;
}
const processed = processSchemaType(
appearance,
SCHEMA_TYPES.CREATIVE_WORK
);
if (appearance.author) {
processed.author = processAuthor(appearance.author);
}
if (appearance.publisher && !isString(appearance.publisher)) {
processed.publisher = processPublisher(appearance.publisher);
}
return processed;
}
function processWebPageElement(element) {
return processSchemaType(
element,
SCHEMA_TYPES.WEB_PAGE_ELEMENT
);
}
function processProductOffer(offer) {
const processed = processSchemaType(
offer,
SCHEMA_TYPES.OFFER
);
if (offer.seller) {
processed.seller = processAuthor(offer.seller);
}
if (offer.priceSpecification) {
if (Array.isArray(offer.priceSpecification)) {
processed.priceSpecification = offer.priceSpecification.map(
processPriceSpecification
);
} else {
processed.priceSpecification = processPriceSpecification(
offer.priceSpecification
);
}
}
if (offer.hasMerchantReturnPolicy) {
if (Array.isArray(offer.hasMerchantReturnPolicy)) {
processed.hasMerchantReturnPolicy = offer.hasMerchantReturnPolicy.map(
processMerchantReturnPolicy
);
} else {
processed.hasMerchantReturnPolicy = processMerchantReturnPolicy(
offer.hasMerchantReturnPolicy
);
}
}
if (offer.shippingDetails) {
if (Array.isArray(offer.shippingDetails)) {
processed.shippingDetails = offer.shippingDetails.map(
processOfferShippingDetails
);
} else {
processed.shippingDetails = processOfferShippingDetails(
offer.shippingDetails
);
}
}
return processed;
}
function processAggregateOffer(offer) {
const processed = processSchemaType(
offer,
SCHEMA_TYPES.AGGREGATE_OFFER
);
if (offer.offers) {
processed.offers = offer.offers.map(processProductOffer);
}
return processed;
}
function processPriceSpecification(spec) {
if ("priceType" in spec || "validForMemberTier" in spec || "membershipPointsEarned" in spec || "referenceQuantity" in spec) {
return processUnitPriceSpecification(
spec
);
}
return processSchemaType(
spec,
SCHEMA_TYPES.PRICE_SPECIFICATION
);
}
function processUnitPriceSpecification(spec) {
const processed = processSchemaType(
spec,
SCHEMA_TYPES.UNIT_PRICE_SPECIFICATION
);
if (spec.validForMemberTier) {
if (Array.isArray(spec.validForMemberTier)) {
processed.validForMemberTier = spec.validForMemberTier.map(
processMemberProgramTier
);
} else {
processed.validForMemberTier = processMemberProgramTier(
spec.validForMemberTier
);
}
}
if (spec.referenceQuantity) {
processed.referenceQuantity = processQuantitativeValue(
spec.referenceQuantity
);
}
return processed;
}
function processQuantitativeValue(value) {
const processed = processSchemaType(
value,
SCHEMA_TYPES.QUANTITATIVE_VALUE
);
if (value.valueReference) {
processed.valueReference = processQuantitativeValue(value.valueReference);
}
return processed;
}
function processProductItemList(list) {
const processed = processSchemaType(
list,
SCHEMA_TYPES.ITEM_LIST
);
if (list.itemListElement) {
processed.itemListElement = list.itemListElement.map((item, index) => {
const processedItem = processSchemaType(
item,
SCHEMA_TYPES.LIST_ITEM
);
if (!processedItem.position) {
processedItem.position = index + 1;
}
return processedItem;
});
}
return processed;
}
function processProductReview(review) {
const processed = processSchemaType(
review,
SCHEMA_TYPES.REVIEW
);
if (review.reviewRating) {
processed.reviewRating = processSchemaType(
review.reviewRating,
SCHEMA_TYPES.RATING
);
}
if (review.author) {
processed.author = processAuthor(review.author);
}
if (review.positiveNotes) {
processed.positiveNotes = processProductItemList(review.positiveNotes);
}
if (review.negativeNotes) {
processed.negativeNotes = processProductItemList(review.negativeNotes);
}
return processed;
}
function processVariesBy(variesBy) {
const processOne = (value) => {
if (value.startsWith("https://schema.org/")) {
return value;
}
return `https://schema.org/${value}`;
};
if (Array.isArray(variesBy)) {
return variesBy.map(processOne);
}
return processOne(variesBy);
}
function processProductVariant(variant) {
if ("url" in variant && Object.keys(variant).length <= 2) {
return variant;
}
const product = variant;
if ("@type" in product) {
return product;
}
const processed = {
"@type": SCHEMA_TYPES.PRODUCT,
...product
};
if (product.image) {
processed.image = Array.isArray(product.image) ? product.image.map(processImage) : processImage(product.image);
}
if (product.brand) {
if (typeof product.brand === "string") {
processed.brand = {
"@type": SCHEMA_TYPES.BRAND,
name: product.brand
};
} else {
processed.brand = processBrand(product.brand);
}
}
if (product.offers) {
if (Array.isArray(product.offers)) {
processed.offers = product.offers.map((offer) => {
if ("lowPrice" in offer && "priceCurrency" in offer) {
return processAggregateOffer(
offer
);
}
return processProductOffer(
offer
);
});
} else if ("lowPrice" in product.offers && "priceCurrency" in product.offers) {
processed.offers = processAggregateOffer(
product.offers
);
} else {
processed.offers = processProductOffer(
product.offers
);
}
}
if (product.review) {
processed.review = Array.isArray(product.review) ? product.review.map(processProductReview) : processProductReview(product.review);
}
if (product.aggregateRating) {
processed.aggregateRating = processAggregateRating(product.aggregateRating);
}
if (product.manufacturer) {
processed.manufacturer = processAuthor(product.manufacturer);
}
if (product.weight && typeof product.weight === "object" && !("@type" in product.weight)) {
processed.weight = { "@type": "QuantitativeValue", ...product.weight };
}
if (product.width && typeof product.width === "object" && !("@type" in product.width)) {
processed.width = { "@type": "QuantitativeValue", ...product.width };
}
if (product.height && typeof product.height === "object" && !("@type" in product.height)) {
processed.height = { "@type": "QuantitativeValue", ...product.height };
}
if (product.depth && typeof product.depth === "object" && !("@type" in product.depth)) {
processed.depth = { "@type": "QuantitativeValue", ...product.depth };
}
return processed;
}
function processCertification(cert) {
const processed = processSchemaType(
cert,
SCHEMA_TYPES.CERTIFICATION
);
if (cert.issuedBy) {
if (typeof cert.issuedBy === "object" && !("@type" in cert.issuedBy)) {
processed.issuedBy = {
"@type": SCHEMA_TYPES.ORGANIZATION,
...cert.issuedBy
};
} else {
processed.issuedBy = cert.issuedBy;
}
}
if (cert.certificationRating) {
processed.certificationRating = processRating(cert.certificationRating);
}
return processed;
}
function processPeopleAudience(audience) {
const processed = processSchemaType(
audience,
SCHEMA_TYPES.PEOPLE_AUDIENCE
);
if (audience.suggestedAge) {
processed.suggestedAge = processQuantitativeValue(audience.suggestedAge);
}
return processed;
}
function processSizeSpecification(size) {
if (typeof size === "string") {
return size;
}
return processSchemaType(
size,
SCHEMA_TYPES.SIZE_SPECIFICATION
);
}
function processThreeDModel(model) {
const processed = processSchemaType(
model,
SCHEMA_TYPES.THREE_D_MODEL
);
if (model.encoding && !("@type" in model.encoding)) {
processed.encoding = {
"@type": "MediaObject",
...model.encoding
};
}
return processed;
}
function processDefinedRegion(region) {
return processSchemaType(region, SCHEMA_TYPES.DEFINED_REGION);
}
function processShippingDeliveryTime(time) {
const processed = processSchemaType(
time,
SCHEMA_TYPES.SHIPPING_DELIVERY_TIME
);
if (time.handlingTime) {
processed.handlingTime = processQuantitativeValue(time.handlingTime);
}
if (time.transitTime) {
processed.transitTime = processQuantitativeValue(time.transitTime);
}
return processed;
}
function processOfferShippingDetails(details) {
const processed = processSchemaType(
details,
SCHEMA_TYPES.OFFER_SHIPPING_DETAILS
);
if (details.shippingRate) {
processed.shippingRate = processSimpleMonetaryAmount(details.shippingRate);
}
if (details.shippingDestination) {
if (Array.isArray(details.shippingDestination)) {
processed.shippingDestination = details.shippingDestination.map(processDefinedRegion);
} else {
processed.shippingDestination = processDefinedRegion(
details.shippingDestination
);
}
}
if (details.deliveryTime) {
processed.deliveryTime = processShippingDeliveryTime(details.deliveryTime);
}
return processed;
}
function processItemReviewed(itemReviewed, defaultType) {
if (isString(itemReviewed)) {
return { "@type": defaultType || "Thing", name: itemReviewed };
}
if (typeof itemReviewed === "object" && itemReviewed !== null && "@type" in itemReviewed) {
return itemReviewed;
}
const candidate = {
...itemReviewed
};
const inferType = () => {
if (defaultType) return defaultType;
if ("brand" in candidate || "sku" in candidate) return "Product";
if ("recipeIngredient" in candidate || "recipeInstructions" in candidate)
return "Recipe";
if ("servesCuisine" in candidate || "address" in candidate)
return "LocalBusiness";
if ("applicationCategory" in candidate || "operatingSystem" in candidate)
return "SoftwareApplication";
if ("director" in candidate || "actor" in candidate) return "Movie";
if ("provider" in candidate) return "Course";
return "Thing";
};
return { "@type": inferType(), ...candidate };
}
function processHowToDirection(direction) {
const processed = processSchemaType(
direction,
SCHEMA_TYPES.HOW_TO_DIRECTION
);
if (direction.beforeMedia && !isString(direction.beforeMedia)) {
processed.beforeMedia = processImage(direction.beforeMedia);
}
if (direction.afterMedia && !isString(direction.afterMedia)) {
processed.afterMedia = processImage(direction.afterMedia);
}
if (direction.duringMedia && !isString(direction.duringMedia)) {
processed.duringMedia = processImage(direction.duringMedia);
}
return processed;
}
function processHowToTip(tip) {
return processSchemaType(tip, SCHEMA_TYPES.HOW_TO_TIP);
}
function processHowToStepItem(item) {
if (hasType(item)) {
if (item["@type"] === SCHEMA_TYPES.HOW_TO_DIRECTION) {
return processHowToDirection(item);
}
return processHowToTip(item);
}
if ("beforeMedia" in item || "afterMedia" in item || "duringMedia" in item) {
return processHowToDirection(item);
}
return processHowToDirection(item);
}
function processHowToStep(step) {
if (isString(step)) {
return step;
}
const processed = processSchemaType(
step,
SCHEMA_TYPES.HOW_TO_STEP
);
if (step.image && !isString(step.image)) {
processed.image = processImage(step.image);
}
if (step.itemListElement) {
processed.itemListElement = step.itemListElement.map(processHowToStepItem);
}
return processed;
}
function processHowToSection(section) {
const processed = processSchemaType(
section,
SCHEMA_TYPES.HOW_TO_SECTION
);
if (section.itemListElement) {
processed.itemListElement = section.itemListElement.map((item) => {
const result = processHowToStep(item);
return typeof result === "string" ? { "@type": "HowToStep", text: result } : result;
});
}
return processed;
}
function processStep(step) {
if (isString(step)) {
return step;
}
if (hasType(step)) {
if (step["@type"] === SCHEMA_TYPES.HOW_TO_SECTION) {
return processHowToSection(step);
}
const result2 = processHowToStep(step);
return typeof result2 === "string" ? { "@type": "HowToStep", text: result2 } : result2;
}
if ("itemListElement" in step && "name" in step) {
return processHowToSection(step);
}
const result = processHowToStep(step);
return typeof result === "string" ? { "@type": "HowToStep", text: result } : result;
}
function processHowToSupply(supply) {
if (isString(supply)) {
return {
"@type": SCHEMA_TYPES.HOW_TO_SUPPLY,
name: supply
};
}
const processed = processSchemaType(
supply,
SCHEMA_TYPES.HOW_TO_SUPPLY
);
if (supply.image && !isString(supply.image)) {
processed.image = processImage(supply.image);
}
if (supply.estimatedCost && !isString(supply.estimatedCost)) {
processed.estimatedCost = processSimpleMonetaryAmount(supply.estimatedCost);
}
if (supply.requiredQuantity && typeof supply.requiredQuantity === "object") {
processed.requiredQuantity = processQuantitativeValue(
supply.requiredQuantity
);
}
return processed;
}
function processHowToTool(tool) {
if (isString(tool)) {
return {
"@type": SCHEMA_TYPES.HOW_TO_TOOL,
name: tool
};
}
const processed = processSchemaType(
tool,
SCHEMA_TYPES.HOW_TO_TOOL
);
if (tool.image && !isString(tool.image)) {
processed.image = processImage(tool.image);
}
if (tool.requiredQuantity && typeof tool.requiredQuantity === "object") {
processed.requiredQuantity = processQuantitativeValue(
tool.requiredQuantity
);
}
return processed;
}
function processEstimatedCost(cost) {
if (isString(cost)) {
return cost;
}
return processSimpleMonetaryAmount(cost);
}
function processHowToYield(yieldValue) {
if (isString(yieldValue)) {
return yieldValue;
}
return processQuantitativeValue(yieldValue);
}
// src/components/ArticleJsonLd.tsx
import { jsx as jsx2 } from "react/jsx-runtime";
function ArticleJsonLd({
type = "Article",
scriptId,
scriptKey,
headline,
url,
author,
datePublished,
dateModified,
image,
publisher,
description,
isAccessibleForFree,
mainEntityOfPage
}) {
const data = {
"@context": "https://schema.org",
"@type": type,
headline,
...url && { url },
...author && {
author: Array.isArray(author) ? author.map(processAuthor) : processAuthor(author)
},
...datePublished && { datePublished },
...dateModified && { dateModified },
// If dateModified is not provided but datePublished is, use datePublished
...!dateModified && datePublished && { dateModified: datePublished },
...image && {
image: Array.isArray(image) ? image.map(processImage) : processImage(image)
},
...publisher && { publisher: processPublisher(publisher) },
...description && { description },
...isAccessibleForFree !== void 0 && { isAccessibleForFree },
...mainEntityOfPage && {
mainEntityOfPage: processMainEntityOfPage(mainEntityOfPage)
}
};
return /* @__PURE__ */ jsx2(
JsonLdScript,
{
data,
id: scriptId,
scriptKey: scriptKey || `article-jsonld-${type}`
}
);
}
// src/components/ClaimReviewJsonLd.tsx
import { jsx as jsx3 } from "react/jsx-runtime";
function ClaimReviewJsonLd({
scriptId,
scriptKey,
claimReviewed,
reviewRating,
url,
author,
itemReviewed
}) {
const data = {
"@context": "https://schema.org",
"@type": "ClaimReview",
claimReviewed,
reviewRating: processClaimReviewRating(reviewRating),
url,
...author && { author: processAuthor(author) },
...itemReviewed && { itemReviewed: processClaim(itemReviewed) }
};
return /* @__PURE__ */ jsx3(
JsonLdScript,
{
data,
id: scriptId,
scriptKey: scriptKey || "claimreview-jsonld"
}
);
}
// src/components/CreativeWorkJsonLd.tsx
import { jsx as jsx4 } from "react/jsx-runtime";
function CreativeWorkJsonLd({
type = "CreativeWork",
scriptId,
scriptKey,
headline,
name,
url,
author,
datePublished,
dateModified,
image,
publisher,
description,
isAccessibleForFree,
hasPart,
mainEntityOfPage,
// Additional properties for specific types
text,
// For Comment
provider,
// For Course
itemReviewed,
// For Review
reviewRating
// For Review
}) {
const data = {
"@context": "https://schema.org",
"@type": type,
// Use headline if provided, otherwise use name
...headline && { headline },
...name && !headline && { name },
...url && { url },
...author && {
author: Array.isArray(author) ? author.map(processAuthor) : processAuthor(author)
},
...datePublished && { datePublished },
...dateModified && { dateModified },
// If dateModified is not provided but datePublished is, use datePublished for certain types
...!dateModified && datePublished && ["Article", "NewsArticle", "BlogPosting"].includes(type) && {
dateModified: datePublished
},
...image && {
image: Array.isArray(image) ? image.map(processImage) : processImage(image)
},
...publisher && { publisher: processPublisher(publisher) },
...description && { description },
...isAccessibleForFree !== void 0 && { isAccessibleForFree },
...hasPart && {
hasPart: Array.isArray(hasPart) ? hasPart.map(processWebPageElement) : processWebPageElement(hasPart)
},
...mainEntityOfPage && {
mainEntityOfPage: processMainEntityOfPage(mainEntityOfPage)
},
// Type-specific properties
...text && type === "Comment" && { text },
...provider && type === "Course" && { provider: processPublisher(provider) },
...itemReviewed && type === "Review" && { itemReviewed },
...reviewRating && type === "Review" && { reviewRating }
};
return /* @__PURE__ */ jsx4(
JsonLdScript,
{
data,
id: scriptId,
scriptKey: scriptKey || `creativework-jsonld-${type.toLowerCase()}`
}
);
}
// src/components/RecipeJsonLd.tsx
import { jsx as jsx5 } from "react/jsx-runtime";
function RecipeJsonLd({
scriptId,
scriptKey,
name,
image,
description,
author,
datePublished,
prepTime,
cookTime,
totalTime,
recipeYield,
recipeCategory,
recipeCuisine,
nutrition,
recipeIngredient,
recipeInstructions,
aggregateRating,
video,
keywords,
url
}) {
const data = {
"@context": "https://schema.org",
"@type": "Recipe",
name,
image: Array.isArray(image) ? image.map(processImage) : processImage(image),
...description && { description },
...author && { author: processAuthor(author) },
...datePublished && { datePublished },
...prepTime && { prepTime },
...cookTime && { cookTime },
...totalTime && { totalTime },
...recipeYield !== void 0 && { recipeYield },
...recipeCategory && { recipeCategory },
...recipeCuisine && { recipeCuisine },
...nutrition && { nutrition: processNutrition(nutrition) },
...recipeIngredient && { recipeIngredient },
...recipeInstructions && {
recipeInstructions: Array.isArray(recipeInstructions) ? recipeInstructions.map(processInstruction) : processInstruction(recipeInstructions)
},
...aggregateRating && {
aggregateRating: processAggregateRating(aggregateRating)
},
...video && { video: processVideo(video) },
...keywords && { keywords },
...url && { url }
};
return /* @__PURE__ */ jsx5(
JsonLdScript,
{
data,
id: scriptId,
scriptKey: scriptKey || "recipe-jsonld"
}
);
}
// src/components/HowToJsonLd.tsx
import { jsx as jsx6 } from "react/jsx-runtime";
function HowToJsonLd({
scriptId,
scriptKey,
name,
description,
image,
estimatedCost,
performTime,
prepTime,
totalTime,
step,
supply,
tool,
yield: yieldValue,
video
}) {
const data = {
"@context": "https://schema.org",
"@type": "HowTo",
name,
...description && { descript