diff --git a/scripts/generate-social-card.mjs b/scripts/generate-social-card.mjs new file mode 100644 index 0000000..d3990a8 --- /dev/null +++ b/scripts/generate-social-card.mjs @@ -0,0 +1,85 @@ +import sharp from 'sharp'; +import { fileURLToPath } from 'url'; +import { dirname, join } from 'path'; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = dirname(__filename); + +// Social card dimensions (recommended for Open Graph) +const WIDTH = 1200; +const HEIGHT = 630; + +// Colors matching the site's theme +const BACKGROUND_COLOR = '#faf9f5'; // Light theme background +const TEXT_COLOR = '#141413'; // Dark text + +// Create SVG with site branding +const svg = ` + + + + + + + + + + + + + + + + + + + + Angel Baez + + + + + Full Stack Developer + + + + + + + + angel-baez.com + + +`; + +async function generateSocialCard() { + const outputPath = join(__dirname, '..', 'src', 'assets', 'social-card.png'); + + await sharp(Buffer.from(svg)) + .png() + .toFile(outputPath); + + console.log(`Social card generated: ${outputPath}`); +} + +generateSocialCard().catch(console.error); diff --git a/src/assets/social-card.png b/src/assets/social-card.png new file mode 100644 index 0000000..e822691 Binary files /dev/null and b/src/assets/social-card.png differ diff --git a/src/components/BaseHead.astro b/src/components/BaseHead.astro index 6f4d236..defd5ac 100644 --- a/src/components/BaseHead.astro +++ b/src/components/BaseHead.astro @@ -1,12 +1,14 @@ --- import { SITE_URL } from "../const"; import type { Language } from "@/i18n/ui"; +import type { ImageMetadata } from "astro"; import { getLocalizedUrl } from "@/i18n/utils"; +import defaultSocialCard from "@/assets/social-card.png"; interface Props { title: string; description: string; - image?: string; + image?: string | ImageMetadata; keywords?: string[]; lang: Language; } @@ -16,11 +18,16 @@ const defaultKeywords = ["Angel Baez", "angel-baez.com", "Full Stack Developer", const { title, description, - image = "/favicon.png", + image = defaultSocialCard, keywords, lang } = Astro.props; +// Handle image URL (string or imported image) +const imageUrl = typeof image === 'string' + ? new URL(image, SITE_URL) + : new URL(image.src, SITE_URL); + // Merge post-specific keywords with defaults const allKeywords = keywords && keywords.length > 0 ? [...keywords, ...defaultKeywords] @@ -57,7 +64,7 @@ const esUrl = new URL(getLocalizedUrl(Astro.url.pathname, 'es'), SITE_URL); - + @@ -66,7 +73,7 @@ const esUrl = new URL(getLocalizedUrl(Astro.url.pathname, 'es'), SITE_URL); - + @@ -83,13 +90,13 @@ const esUrl = new URL(getLocalizedUrl(Astro.url.pathname, 'es'), SITE_URL); -