Improve social media OG/Twitter meta for posts
- Fix bug: post page was overriding og:image with 150x200 thumbnail - og:type = "article" for posts (was always "website") - article:published_time, article:modified_time, article:author, article:tag - og:image:alt + twitter:image:alt (post headline) - twitter:label1/data1 with reading time - Remove thumbnail fallback from socialImage (falls back to site logo instead) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -52,6 +52,14 @@
|
||||
seoTitle?: string;
|
||||
seoDescription?: string;
|
||||
socialImage?: string;
|
||||
ogType?: string;
|
||||
ogImageAlt?: string;
|
||||
articlePublishedTime?: string | null;
|
||||
articleModifiedTime?: string | null;
|
||||
articleAuthor?: string | null;
|
||||
articleTags?: string[];
|
||||
twitterLabel1?: string;
|
||||
twitterData1?: string;
|
||||
robots?: string;
|
||||
keywords?: string;
|
||||
preview?: boolean;
|
||||
@@ -218,7 +226,7 @@
|
||||
{/if}
|
||||
<link rel="canonical" href={canonical} />
|
||||
<!-- Open Graph -->
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:type" content={pageData?.ogType ?? "website"} />
|
||||
<meta property="og:url" content={canonical} />
|
||||
<meta property="og:title" content={seoTitle} />
|
||||
{#if seoDescription}
|
||||
@@ -228,9 +236,24 @@
|
||||
<meta property="og:image" content={socialImageUrl} />
|
||||
<meta property="og:image:width" content={String(SOCIAL_IMAGE_DIMENSIONS.width)} />
|
||||
<meta property="og:image:height" content={String(SOCIAL_IMAGE_DIMENSIONS.height)} />
|
||||
{#if pageData?.ogImageAlt}
|
||||
<meta property="og:image:alt" content={pageData.ogImageAlt} />
|
||||
{/if}
|
||||
{/if}
|
||||
<meta property="og:locale" content="de_DE" />
|
||||
<meta property="og:site_name" content={data.siteName} />
|
||||
{#if pageData?.articlePublishedTime}
|
||||
<meta property="article:published_time" content={pageData.articlePublishedTime} />
|
||||
{/if}
|
||||
{#if pageData?.articleModifiedTime}
|
||||
<meta property="article:modified_time" content={pageData.articleModifiedTime} />
|
||||
{/if}
|
||||
{#if pageData?.articleAuthor}
|
||||
<meta property="article:author" content={pageData.articleAuthor} />
|
||||
{/if}
|
||||
{#each pageData?.articleTags ?? [] as tag}
|
||||
<meta property="article:tag" content={tag} />
|
||||
{/each}
|
||||
<!-- Twitter -->
|
||||
<meta name="twitter:card" content="summary_large_image" />
|
||||
<meta name="twitter:url" content={canonical} />
|
||||
@@ -240,6 +263,13 @@
|
||||
{/if}
|
||||
{#if socialImageUrl}
|
||||
<meta name="twitter:image" content={socialImageUrl} />
|
||||
{#if pageData?.ogImageAlt}
|
||||
<meta name="twitter:image:alt" content={pageData.ogImageAlt} />
|
||||
{/if}
|
||||
{/if}
|
||||
{#if pageData?.twitterLabel1 && pageData?.twitterData1}
|
||||
<meta name="twitter:label1" content={pageData.twitterLabel1} />
|
||||
<meta name="twitter:data1" content={pageData.twitterData1} />
|
||||
{/if}
|
||||
<!-- JSON-LD WebSite + Organization -->
|
||||
{@html jsonLdScript}
|
||||
|
||||
@@ -303,13 +303,22 @@ export const load: PageServerLoad = async ({ params, locals, url, setHeaders })
|
||||
translations,
|
||||
seoTitle: post.seoTitle ?? postHeadline,
|
||||
seoDescription: postDescription,
|
||||
socialImage: postSocialImageAbs ?? postImageUrl ?? undefined,
|
||||
socialImage: postSocialImageAbs ?? undefined,
|
||||
ogType: 'article' as const,
|
||||
ogImageAlt: postHeadline,
|
||||
articlePublishedTime: postCreated,
|
||||
articleModifiedTime: postUpdated,
|
||||
articleAuthor: postAuthor ?? siteName,
|
||||
articleTags: (() => {
|
||||
const tags = (post as { postTag?: Array<{ name?: string }> }).postTag ?? [];
|
||||
return tags.map((t) => (typeof t === 'string' ? t : (t?.name ?? ''))).filter(Boolean);
|
||||
})(),
|
||||
twitterLabel1: 'Lesezeit',
|
||||
twitterData1: `${readingTimeMinutes} Min.`,
|
||||
robots: (post as { seoMetaRobots?: string }).seoMetaRobots ?? undefined,
|
||||
keywords: (() => {
|
||||
const explicit = ((post as { seoKeywords?: string }).seoKeywords ?? '').trim();
|
||||
if (explicit) return explicit;
|
||||
// Fallback: join tag names so published posts without explicit keywords
|
||||
// still ship a meaningful <meta name="keywords">.
|
||||
const tags = (post as { postTag?: Array<{ name?: string }> }).postTag ?? [];
|
||||
const names = tags
|
||||
.map((t) => (typeof t?.name === 'string' ? t.name.trim() : ''))
|
||||
|
||||
@@ -14,15 +14,6 @@
|
||||
let { data }: { data: PageData } = $props();
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>{data.seoTitle}</title>
|
||||
{#if data.seoDescription}
|
||||
<meta name="description" content={data.seoDescription} />
|
||||
{/if}
|
||||
{#if data.postImageUrl}
|
||||
<meta property="og:image" content={data.postImageUrl} />
|
||||
{/if}
|
||||
</svelte:head>
|
||||
|
||||
<div class="my-4 md:flex md:items-start md:gap-4">
|
||||
{#if data.rawPostImageUrl}
|
||||
|
||||
Reference in New Issue
Block a user