Ahrefs 96->100

This commit is contained in:
Timo Knuth
2026-01-15 10:14:40 +01:00
parent 0a02876ea4
commit 83ea141230
17 changed files with 694 additions and 579 deletions

View File

@@ -10,10 +10,10 @@ export default function SeoJsonLd({ data }: SeoJsonLdProps) {
return (
<>
{jsonLdArray.map((item, index) => {
const schema = {
'@context': 'https://schema.org',
...item,
};
// Only add @context if it doesn't already exist in the item
const schema = (item as any)['@context']
? item
: { '@context': 'https://schema.org', ...item };
return (
<script

View File

@@ -66,9 +66,9 @@ export const Hero: React.FC<HeroProps> = ({ t }) => {
transition={{ duration: 0.5 }}
className="space-y-6"
>
<h1 className="text-5xl lg:text-6xl font-bold text-gray-900 leading-tight">
<h2 className="text-5xl lg:text-6xl font-bold text-gray-900 leading-tight">
{t.hero.title}
</h1>
</h2>
<p className="text-xl text-gray-600 leading-relaxed max-w-2xl">
{t.hero.subtitle}

View File

@@ -0,0 +1,34 @@
'use client';
import React, { useState, useEffect } from 'react';
interface ObfuscatedMailtoProps {
email: string;
className?: string;
children?: React.ReactNode;
}
/**
* Renders an email link that only becomes a clickable mailto: link after client-side hydration.
* This prevents Cloudflare's Email Obfuscation from breaking the link in the static HTML,
* which causes crawlers like Ahrefs to report 404 errors on /cdn-cgi/l/email-protection.
*/
export function ObfuscatedMailto({ email, className, children }: ObfuscatedMailtoProps) {
const [isMounted, setIsMounted] = useState(false);
useEffect(() => {
setIsMounted(true);
}, []);
// Before hydration, render as plain text/span to avoid Cloudflare manipulation
if (!isMounted) {
return <span className={className}>{children || email}</span>;
}
// After hydration, render as a proper mailto link
return (
<a href={`mailto:${email}`} className={className}>
{children || email}
</a>
);
}