@dijitrak/react-nextjs-seo-plugin
Version:
A modern, user-friendly SEO plugin for React and Next.js with multilingual support and comprehensive optimization tools
375 lines (351 loc) • 8.51 kB
text/typescript
/**
* JSON-LD şema işlemleri
*/
import { JSONLDSchema, SchemaType } from '../types';
/**
* JSON-LD şemalarını oluşturur
* @param schemas JSON-LD şemaları
* @returns HTML script etiketi
*/
export function generateJSONLD(schemas: JSONLDSchema[]): string {
if (!schemas || schemas.length === 0) return '';
let result = '';
schemas.forEach(schema => {
// Schemas.org URL'si ve tip
const schemaData = prepareSchemaData(schema);
// JSON-LD script tag
result += `<script type="application/ld+json">${JSON.stringify(schemaData)}</script>\n`;
});
return result;
}
/**
* Şema verilerini hazırlar
* @param schema Şema verileri
* @returns Schema.org uyumlu veri
*/
function prepareSchemaData(schema: JSONLDSchema): Record<string, any> {
// @context eklenmesi
const schemaData: Record<string, any> = {
'@context': 'https://schema.org',
'@type': schema.type
};
// Şema verilerini ekleme
if (schema.data) {
Object.keys(schema.data).forEach(key => {
schemaData[key] = schema.data[key];
});
}
return schemaData;
}
/**
* Varsayılan şema şablonu oluşturur
* @param type Şema tipi
* @param siteUrl Site URL'si
* @returns Varsayılan şema verisi
*/
export function getDefaultSchemaTemplate(type: SchemaType, siteUrl: string): Record<string, any> {
switch (type) {
case 'WebSite':
return {
name: '',
url: siteUrl,
potentialAction: {
'@type': 'SearchAction',
'target': `${siteUrl}/search?q={search_term_string}`,
'query-input': 'required name=search_term_string'
}
};
case 'Organization':
return {
name: '',
url: siteUrl,
logo: '',
contactPoint: {
'@type': 'ContactPoint',
telephone: '',
contactType: 'customer service'
},
sameAs: [
// Sosyal medya linkleri
]
};
case 'LocalBusiness':
return {
name: '',
image: '',
'@id': '',
url: siteUrl,
telephone: '',
address: {
'@type': 'PostalAddress',
streetAddress: '',
addressLocality: '',
postalCode: '',
addressCountry: ''
},
geo: {
'@type': 'GeoCoordinates',
latitude: '',
longitude: ''
},
openingHoursSpecification: [
{
'@type': 'OpeningHoursSpecification',
dayOfWeek: ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday'],
opens: '09:00',
closes: '17:00'
}
]
};
case 'Person':
return {
name: '',
jobTitle: '',
image: '',
telephone: '',
email: '',
address: {
'@type': 'PostalAddress',
addressLocality: '',
addressCountry: ''
},
sameAs: [
// Sosyal medya linkleri
]
};
case 'Product':
return {
name: '',
image: '',
description: '',
sku: '',
brand: {
'@type': 'Brand',
name: ''
},
offers: {
'@type': 'Offer',
url: siteUrl + '/product',
priceCurrency: 'USD',
price: '0',
availability: 'https://schema.org/InStock'
},
aggregateRating: {
'@type': 'AggregateRating',
ratingValue: '4.5',
reviewCount: '100'
}
};
case 'Article':
return {
headline: '',
image: '',
description: '',
author: {
'@type': 'Person',
name: ''
},
publisher: {
'@type': 'Organization',
name: '',
logo: {
'@type': 'ImageObject',
url: ''
}
},
datePublished: '',
dateModified: ''
};
case 'BlogPosting':
return {
headline: '',
image: '',
description: '',
author: {
'@type': 'Person',
name: ''
},
publisher: {
'@type': 'Organization',
name: '',
logo: {
'@type': 'ImageObject',
url: ''
}
},
datePublished: '',
dateModified: ''
};
case 'Event':
return {
name: '',
description: '',
startDate: '',
endDate: '',
location: {
'@type': 'Place',
name: '',
address: {
'@type': 'PostalAddress',
streetAddress: '',
addressLocality: '',
postalCode: '',
addressCountry: ''
}
},
image: '',
offers: {
'@type': 'Offer',
url: siteUrl + '/event',
price: '0',
priceCurrency: 'USD',
availability: 'https://schema.org/InStock'
},
performer: {
'@type': 'Person',
name: ''
}
};
case 'FAQ':
return {
'@type': 'FAQPage',
mainEntity: [
{
'@type': 'Question',
name: 'What is the first question?',
acceptedAnswer: {
'@type': 'Answer',
text: 'This is the answer to the first question.'
}
},
{
'@type': 'Question',
name: 'What is the second question?',
acceptedAnswer: {
'@type': 'Answer',
text: 'This is the answer to the second question.'
}
}
]
};
case 'HowTo':
return {
name: '',
description: '',
totalTime: 'PT2H',
supply: [
{
'@type': 'HowToSupply',
name: 'Supply item 1'
},
{
'@type': 'HowToSupply',
name: 'Supply item 2'
}
],
tool: [
{
'@type': 'HowToTool',
name: 'Tool 1'
},
{
'@type': 'HowToTool',
name: 'Tool 2'
}
],
step: [
{
'@type': 'HowToStep',
name: 'Step 1',
text: 'Description of step 1',
image: '',
url: siteUrl + '/how-to#step1'
},
{
'@type': 'HowToStep',
name: 'Step 2',
text: 'Description of step 2',
image: '',
url: siteUrl + '/how-to#step2'
}
]
};
case 'BreadcrumbList':
return {
itemListElement: [
{
'@type': 'ListItem',
position: 1,
name: 'Home',
item: siteUrl
},
{
'@type': 'ListItem',
position: 2,
name: 'Category',
item: siteUrl + '/category'
},
{
'@type': 'ListItem',
position: 3,
name: 'Page',
item: siteUrl + '/category/page'
}
]
};
case 'Recipe':
return {
name: '',
image: '',
description: '',
author: {
'@type': 'Person',
name: ''
},
datePublished: '',
prepTime: 'PT15M',
cookTime: 'PT1H',
totalTime: 'PT1H15M',
recipeYield: '4 servings',
nutrition: {
'@type': 'NutritionInformation',
calories: '250 cal',
fatContent: '10 g'
},
recipeIngredient: [
'Ingredient 1',
'Ingredient 2',
'Ingredient 3'
],
recipeInstructions: [
{
'@type': 'HowToStep',
name: 'Step 1',
text: 'Description of step 1'
},
{
'@type': 'HowToStep',
name: 'Step 2',
text: 'Description of step 2'
}
]
};
case 'VideoObject':
return {
name: '',
description: '',
thumbnailUrl: '',
uploadDate: '',
duration: 'PT1M33S',
contentUrl: '',
embedUrl: '',
interactionStatistic: {
'@type': 'InteractionCounter',
interactionType: 'https://schema.org/WatchAction',
userInteractionCount: '100'
}
};
default:
return {};
}
}