SEO blogpost V2

This commit is contained in:
2026-08-05 20:17:01 +02:00
parent 529a95cba2
commit b423c4502a
26 changed files with 173 additions and 26 deletions

View File

@@ -1,8 +1,11 @@
import type { Metadata } from "next";
import Image from "next/image";
import Link from "next/link";
import { notFound } from "next/navigation";
import Nav from "@/components/nav";
import Footer from "@/components/footer";
import ContextualGuideLink from "@/components/contextual-guide-link";
import RelatedGuideArticles from "@/components/related-guide-articles";
import { getGuide, GUIDES } from "@/lib/guides";
import { TOOL_PAGES } from "@/lib/tool-pages";
@@ -27,9 +30,16 @@ export async function generateMetadata({ params }: PageProps<"/ratgeber/[slug]">
url: `${SITE_URL}/ratgeber/${guide.slug}`,
title: guide.title,
description: guide.description,
images: [{ url: guide.image.socialSrc, alt: guide.image.alt, width: 1200, height: 630 }],
publishedTime: "2026-08-03T08:00:00+02:00",
modifiedTime: "2026-08-03T08:00:00+02:00",
},
twitter: {
card: "summary_large_image",
title: guide.title,
description: guide.description,
images: [{ url: guide.image.socialSrc, alt: guide.image.alt }],
},
};
}
@@ -44,15 +54,33 @@ export default async function GuidePage({ params }: PageProps<"/ratgeber/[slug]"
.filter((tool): tool is (typeof TOOL_PAGES)[number] => Boolean(tool));
const jsonLd = {
"@context": "https://schema.org",
"@type": "Article",
headline: guide.title,
description: guide.description,
datePublished: "2026-08-03",
dateModified: "2026-08-03",
inLanguage: "de-DE",
mainEntityOfPage: url,
author: { "@type": "Person", name: "Timo Knuth" },
publisher: { "@type": "Organization", name: "Entscheidomat", url: SITE_URL },
"@graph": [
{
"@type": "Article",
headline: guide.title,
description: guide.description,
datePublished: "2026-08-03",
dateModified: "2026-08-03",
inLanguage: "de-DE",
mainEntityOfPage: url,
author: { "@type": "Person", name: "Timo Knuth" },
publisher: {
"@type": "Organization",
name: "Entscheidomat",
url: SITE_URL,
logo: { "@type": "ImageObject", url: `${SITE_URL}/icon.svg`, width: 512, height: 512 },
},
image: { "@type": "ImageObject", url: `${SITE_URL}${guide.image.src}`, width: 1536, height: 1024 },
},
{
"@type": "BreadcrumbList",
itemListElement: [
{ "@type": "ListItem", position: 1, name: "Entscheidomat", item: SITE_URL },
{ "@type": "ListItem", position: 2, name: "Ratgeber", item: `${SITE_URL}/ratgeber` },
{ "@type": "ListItem", position: 3, name: guide.title, item: url },
],
},
],
};
return (
@@ -72,6 +100,9 @@ export default async function GuidePage({ params }: PageProps<"/ratgeber/[slug]"
<p className="mt-6 text-lg leading-relaxed text-ink-soft">{guide.description}</p>
<p className="mt-6 text-sm text-ink-soft">Von Timo Knuth · Veröffentlicht und aktualisiert am {guide.updated}</p>
</header>
<figure className="mt-10 overflow-hidden rounded-3xl border border-line bg-surface shadow-soft">
<Image src={guide.image.src} alt={guide.image.alt} width={1536} height={1024} priority sizes="(min-width: 1024px) 768px, 100vw" className="h-auto w-full object-cover" />
</figure>
<div className="mt-10 space-y-10 text-[1.0625rem] leading-8 text-ink-soft">
{guide.sections.map((section) => (
<section key={section.heading}>
@@ -84,9 +115,11 @@ export default async function GuidePage({ params }: PageProps<"/ratgeber/[slug]"
{section.bullets.map((bullet) => <li key={bullet}>{bullet}</li>)}
</ul>
)}
<ContextualGuideLink guide={guide} sectionHeading={section.heading} />
</section>
))}
</div>
<RelatedGuideArticles guide={guide} />
<aside className="mt-12 rounded-3xl border border-emerald-line bg-emerald-soft p-6 text-ink">
<h2 className="font-display text-2xl font-semibold">Passendes Tool auswählen</h2>
<p className="mt-2 leading-relaxed text-ink-soft">Für spielerische, folgenarme Entscheidungen kannst du die kostenlosen Tools direkt im Browser nutzen ohne Anmeldung.</p>