UNPKG

@asgerami/zemenay-blog

Version:

Plug-and-play blog system for Next.js - Get a fully functional blog running in minutes with zero configuration

132 lines (131 loc) 4.17 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.generateSEOFromPost = generateSEOFromPost; exports.extractDescription = extractDescription; exports.generateMetaTags = generateMetaTags; exports.generateStructuredData = generateStructuredData; const imageUpload_1 = require("./imageUpload"); /** * Generate SEO data from a blog post */ function generateSEOFromPost(post, baseUrl) { // Extract description from content (first 160 characters, strip HTML) const description = extractDescription(post.content); // Get featured image URL if available const image = post.featured_image ? (0, imageUpload_1.getImageUrl)(post.featured_image.file_path) : undefined; // Generate full URL if baseUrl provided const url = baseUrl ? `${baseUrl}/blog/${post.slug}` : undefined; return { title: post.title, description, image, url, type: "article", publishedTime: post.created_at, modifiedTime: post.updated_at, author: "Blog Author", // You can customize this }; } /** * Extract a clean description from HTML content */ function extractDescription(htmlContent, maxLength = 160) { // Remove HTML tags const textContent = htmlContent.replace(/<[^>]*>/g, ""); // Clean up whitespace const cleanText = textContent.replace(/\s+/g, " ").trim(); // Truncate to maxLength if (cleanText.length <= maxLength) { return cleanText; } // Find the last complete word within the limit const truncated = cleanText.substring(0, maxLength); const lastSpaceIndex = truncated.lastIndexOf(" "); if (lastSpaceIndex > 0) { return truncated.substring(0, lastSpaceIndex) + "..."; } return truncated + "..."; } /** * Generate meta tags for SEO */ function generateMetaTags(seoData) { const tags = { title: seoData.title, description: seoData.description, }; // Open Graph tags tags["og:title"] = seoData.title; tags["og:description"] = seoData.description; tags["og:type"] = seoData.type || "website"; if (seoData.url) { tags["og:url"] = seoData.url; } if (seoData.image) { tags["og:image"] = seoData.image; tags["og:image:alt"] = seoData.title; } // Twitter Card tags tags["twitter:card"] = "summary_large_image"; tags["twitter:title"] = seoData.title; tags["twitter:description"] = seoData.description; if (seoData.image) { tags["twitter:image"] = seoData.image; } // Article-specific tags if (seoData.type === "article") { if (seoData.publishedTime) { tags["article:published_time"] = seoData.publishedTime; } if (seoData.modifiedTime) { tags["article:modified_time"] = seoData.modifiedTime; } if (seoData.author) { tags["article:author"] = seoData.author; } } return tags; } /** * Generate JSON-LD structured data */ function generateStructuredData(seoData, baseUrl) { const structuredData = { "@context": "https://schema.org", "@type": seoData.type === "article" ? "BlogPosting" : "WebPage", headline: seoData.title, description: seoData.description, }; if (seoData.url) { structuredData.url = seoData.url; } if (seoData.image) { structuredData.image = { "@type": "ImageObject", url: seoData.image, }; } if (seoData.type === "article") { if (seoData.publishedTime) { structuredData.datePublished = seoData.publishedTime; } if (seoData.modifiedTime) { structuredData.dateModified = seoData.modifiedTime; } if (seoData.author) { structuredData.author = { "@type": "Person", name: seoData.author, }; } // Add publisher info (customize as needed) structuredData.publisher = { "@type": "Organization", name: "Zemenay Blog", url: baseUrl || "", }; } return structuredData; }