canina/frontend/application/lib/schema.ts
parsa aghaei 70c2627d93
All checks were successful
Deploy Canina / deploy (push) Successful in 1m44s
feat(seo): implement B2B dedicated route, structured data schemas, archive optimizations, and SEO database backfill
2026-08-25 11:19:30 +03:30

234 lines
7.2 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* Structured Data (JSON-LD) Generators for Canina Iran
* Conforming to Schema.org and Google Search Rich Results guidelines
*/
export interface OrganizationSchemaOptions {
name?: string;
alternateName?: string;
url?: string;
logo?: string;
description?: string;
telephone?: string;
email?: string;
address?: {
streetAddress?: string;
addressLocality?: string;
addressRegion?: string;
postalCode?: string;
addressCountry?: string;
};
sameAs?: string[];
}
export function generateOrganizationSchema(options: OrganizationSchemaOptions = {}) {
const brandName = options.name || 'کنینا ایران';
const siteUrl = options.url || 'https://canina.ir';
const logoUrl = options.logo || `${siteUrl}/assets/images/logo.png`;
return {
'@context': 'https://schema.org',
'@type': 'Organization',
'@id': `${siteUrl}#organization`,
name: brandName,
alternateName: options.alternateName || 'Canina pharma GmbH Iran Representative',
url: siteUrl,
logo: {
'@type': 'ImageObject',
url: logoUrl,
caption: brandName,
},
image: logoUrl,
description:
options.description ||
'نماینده رسمی و انحصاری مکمل‌های دارویی و درمانی Canina pharma GmbH آلمان در ایران.',
telephone: options.telephone || '+989211231517',
email: options.email || 'caninairan@gmail.com',
address: {
'@type': 'PostalAddress',
streetAddress: options.address?.streetAddress || 'جردن، خیابان سعیدی، ساختمان کنینا، طبقه ۵',
addressLocality: options.address?.addressLocality || 'تهران',
addressRegion: options.address?.addressRegion || 'تهران',
postalCode: options.address?.postalCode || '1967812345',
addressCountry: options.address?.addressCountry || 'IR',
},
sameAs: options.sameAs || [
'https://instagram.com/caninairan',
'https://t.me/caninairan',
'https://www.canina.de',
],
contactPoint: [
{
'@type': 'ContactPoint',
telephone: options.telephone || '+989211231517',
contactType: 'customer service',
availableLanguage: ['Persian', 'English', 'German'],
areaServed: 'IR',
},
],
};
}
export function generateLocalBusinessSchema(options: OrganizationSchemaOptions = {}) {
const siteUrl = options.url || 'https://canina.ir';
const brandName = options.name || 'کنینا ایران';
const logoUrl = options.logo || `${siteUrl}/assets/images/logo.png`;
return {
'@context': 'https://schema.org',
'@type': 'VeterinaryCare',
'@id': `${siteUrl}#localbusiness`,
name: `${brandName} - دفتر مرکزی و پشتیبانی تخصصی`,
image: logoUrl,
url: siteUrl,
telephone: options.telephone || '+989211231517',
priceRange: '$$',
address: {
'@type': 'PostalAddress',
streetAddress: options.address?.streetAddress || 'تهران، جردن، خیابان سعیدی، ساختمان کنینا، طبقه ۵، واحد ۱۹',
addressLocality: options.address?.addressLocality || 'تهران',
addressRegion: options.address?.addressRegion || 'تهران',
postalCode: options.address?.postalCode || '1967812345',
addressCountry: 'IR',
},
geo: {
'@type': 'GeoCoordinates',
latitude: 35.7785,
longitude: 51.4172,
},
openingHoursSpecification: [
{
'@type': 'OpeningHoursSpecification',
dayOfWeek: ['Saturday', 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday'],
opens: '09:00',
closes: '18:00',
},
],
sameAs: options.sameAs || [
'https://instagram.com/caninairan',
'https://t.me/caninairan',
],
};
}
export interface B2BServiceSchemaOptions {
serviceName?: string;
description?: string;
siteUrl?: string;
}
export function generateB2BServiceSchema(options: B2BServiceSchemaOptions = {}) {
const siteUrl = options.siteUrl || 'https://canina.ir';
return {
'@context': 'https://schema.org',
'@type': 'Service',
'@id': `${siteUrl}/b2b#service`,
name: options.serviceName || 'تأمین عمده و همکاری تجاری مکمل‌های دارویی کنینا آلمان',
serviceType: 'B2B Veterinary Supply & Wholesale',
provider: {
'@type': 'Organization',
name: 'کنینا ایران',
url: siteUrl,
logo: `${siteUrl}/assets/images/logo.png`,
},
areaServed: {
'@type': 'Country',
name: 'Iran',
},
description:
options.description ||
'تأمین مستقیم، پخش عمده و اعطای نمایندگی مکمل‌های تخصصی دامپزشکی Canina آلمان به کلینیک‌ها، بیمارستان‌های دامپزشکی و پت‌شاپ‌های معتبر سراسر کشور.',
offers: {
'@type': 'Offer',
availability: 'https://schema.org/InStock',
businessFunction: 'http://purl.org/goodrelations/v1#ProvideService',
},
};
}
export interface MedicalWebPageSchemaOptions {
title: string;
description: string;
url: string;
datePublished?: string;
dateModified?: string;
medicalAudience?: string;
aspects?: string[];
}
export function generateMedicalWebPageSchema(options: MedicalWebPageSchemaOptions) {
return {
'@context': 'https://schema.org',
'@type': 'MedicalWebPage',
name: options.title,
headline: options.title,
description: options.description,
url: options.url,
datePublished: options.datePublished || '2025-01-01',
dateModified: options.dateModified || new Date().toISOString(),
medicalAudience: {
'@type': 'MedicalAudience',
audienceType: options.medicalAudience || 'Veterinarians, Pet Care Professionals, and Pet Owners',
},
publisher: {
'@type': 'Organization',
name: 'کنینا ایران',
url: 'https://canina.ir',
},
about: options.aspects?.map((aspect) => ({
'@type': 'MedicalCondition',
name: aspect,
})) || [],
};
}
export interface VideoObjectSchemaOptions {
name: string;
description: string;
thumbnailUrl: string;
uploadDate: string;
contentUrl?: string;
embedUrl?: string;
duration?: string;
}
export function generateVideoObjectSchema(options: VideoObjectSchemaOptions) {
return {
'@context': 'https://schema.org',
'@type': 'VideoObject',
name: options.name,
description: options.description,
thumbnailUrl: [options.thumbnailUrl],
uploadDate: options.uploadDate,
contentUrl: options.contentUrl,
embedUrl: options.embedUrl || options.contentUrl,
duration: options.duration || 'PT3M30S',
publisher: {
'@type': 'Organization',
name: 'کنینا ایران',
logo: {
'@type': 'ImageObject',
url: 'https://canina.ir/assets/images/logo.png',
},
},
};
}
export interface BreadcrumbItem {
name: string;
url: string;
}
export function generateBreadcrumbSchema(items: BreadcrumbItem[]) {
return {
'@context': 'https://schema.org',
'@type': 'BreadcrumbList',
itemListElement: items.map((item, index) => ({
'@type': 'ListItem',
position: index + 1,
name: item.name,
item: item.url,
})),
};
}