--- import BaseLayout from '@/layouts/BaseLayout.astro'; import { getCollection, render } from 'astro:content'; export async function getStaticPaths() { const articles = await getCollection('blog'); return articles.map(article => ({ params: { slug: article.id }, props: { article }, })); } const { article } = Astro.props; const { Content } = await render(article); // Get related articles (same tags first, then by date, excluding current) const allArticles = await getCollection('blog'); const related = allArticles .filter(a => a.id !== article.id) .sort((a, b) => { const aTagMatch = a.data.tags?.some(t => article.data.tags?.includes(t)) ? 1 : 0; const bTagMatch = b.data.tags?.some(t => article.data.tags?.includes(t)) ? 1 : 0; if (aTagMatch !== bTagMatch) return bTagMatch - aTagMatch; return b.data.published_at.getTime() - a.data.published_at.getTime(); }) .slice(0, 3); const tag = article.data.tags?.[0] ?? ''; // BlogPosting JSON-LD — provides rich result eligibility in Google // (article cards, author attribution, publish date). const articleUrl = `https://dealplustech.com/${encodeURI('บทความ')}/${article.id}`; const blogPostingSchema = { '@context': 'https://schema.org', '@type': 'BlogPosting', '@id': `${articleUrl}#article`, headline: article.data.title, description: article.data.excerpt || `บทความ ${article.data.title}`, ...(article.data.featured_image && { image: /^https?:\/\//.test(article.data.featured_image) ? article.data.featured_image : `https://dealplustech.com${article.data.featured_image}`, }), datePublished: article.data.published_at.toISOString(), dateModified: (article.data.updated_at ?? article.data.published_at).toISOString(), author: { '@type': 'Organization', name: article.data.author || 'ดีล พลัส เทค', url: 'https://dealplustech.com', }, publisher: { '@type': 'Organization', name: 'ดีล พลัส เทค', logo: { '@type': 'ImageObject', url: 'https://dealplustech.com/images/logo/dealplustech-logo.png', }, }, mainEntityOfPage: { '@type': 'WebPage', '@id': articleUrl, }, ...(article.data.tags && article.data.tags.length > 0 && { keywords: article.data.tags.join(', '), }), ...(article.data.reviewer && { reviewedBy: { '@type': 'Organization', name: article.data.reviewer, }, }), }; // Extract FAQ pairs from article body — scoped to the FAQ section only. // Looks for `## คำถาม...` or `## FAQ` heading then captures all H3+paragraph // pairs until the next H2. const faqPairs: { question: string; answer: string }[] = []; const body = article.body ?? ''; const faqSection = body.match(/##\s+(?:คำถาม[^\n]*|FAQ[^\n]*|Common Questions[^\n]*)\s*\n([\s\S]*?)(?=\n##\s|\n---\s*$|$)/i); if (faqSection) { const sectionBody = faqSection[1]; const pairRegex = /###\s+(.+?)\n\n([\s\S]*?)(?=\n###|\n##\s|$)/g; for (const m of sectionBody.matchAll(pairRegex)) { const question = m[1].trim(); const answer = m[2].trim().replace(/\n+/g, ' '); if (question && answer && !question.startsWith('##')) { faqPairs.push({ question, answer }); } } } const faqSchema = faqPairs.length >= 2 ? { '@context': 'https://schema.org', '@type': 'FAQPage', mainEntity: faqPairs.map(p => ({ '@type': 'Question', name: p.question, acceptedAnswer: { '@type': 'Answer', text: p.answer }, })), } : null; ---
{/* Breadcrumb */}
{/* Article Header */}
{tag && ( {tag} )}

{article.data.title}

{/* Featured Image */} {article.data.featured_image && (
{article.data.title}
)} {/* Article Body */}
{/* Share Buttons */}
แชร์บทความ: Line Facebook
{/* Related Articles */} {related.length > 0 && (

บทความที่เกี่ยวข้อง

)}