This commit is contained in:
2026-01-19 19:29:44 +01:00
parent 2feb73b982
commit 6797303628
15 changed files with 406 additions and 18 deletions

View File

@@ -2,6 +2,7 @@ import { notFound } from 'next/navigation';
import { MDXRemote } from 'next-mdx-remote/rsc';
import { Section, Container, Heading, Badge } from '@/components/ui';
import { getTranslations } from 'next-intl/server';
import { Metadata } from 'next';
interface PageProps {
params: {
@@ -10,6 +11,45 @@ interface PageProps {
};
}
export async function generateMetadata({ params: { locale, slug } }: PageProps): Promise<Metadata> {
const { getPageBySlug } = await import('@/lib/pages');
const pageData = await getPageBySlug(slug, locale);
if (!pageData) return {};
return {
title: pageData.frontmatter.title,
description: pageData.frontmatter.excerpt || '',
alternates: {
canonical: `/${locale}/${slug}`,
languages: {
'de': `/de/${slug}`,
'en': `/en/${slug}`,
'x-default': `/en/${slug}`,
},
},
openGraph: {
title: `${pageData.frontmatter.title} | KLZ Cables`,
description: pageData.frontmatter.excerpt || '',
url: `https://klz-cables.com/${locale}/${slug}`,
images: [
{
url: '/uploads/2025/02/og-2.webp',
width: 1200,
height: 630,
alt: pageData.frontmatter.title,
},
],
},
twitter: {
card: 'summary_large_image',
title: `${pageData.frontmatter.title} | KLZ Cables`,
description: pageData.frontmatter.excerpt || '',
images: ['/uploads/2025/02/og-2.webp'],
},
};
}
export default async function StandardPage({ params: { locale, slug } }: PageProps) {
const { getPageBySlug } = await import('@/lib/pages');
const pageData = await getPageBySlug(slug, locale);

View File

@@ -16,22 +16,40 @@ export async function generateMetadata({ params: { locale, slug } }: BlogPostPro
if (!post) return {};
const description = post.frontmatter.excerpt || '';
const imageUrl = post.frontmatter.featuredImage || '/uploads/2025/02/og-2.webp';
return {
title: post.frontmatter.title,
description: description,
alternates: {
canonical: `/${locale}/blog/${slug}`,
languages: {
'de': `/de/blog/${slug}`,
'en': `/en/blog/${slug}`,
'x-default': `/en/blog/${slug}`,
},
},
openGraph: {
title: post.frontmatter.title,
title: `${post.frontmatter.title} | KLZ Cables`,
description: description,
type: 'article',
publishedTime: post.frontmatter.date,
authors: ['KLZ Cables'],
url: `https://klz-cables.com/${locale}/blog/${slug}`,
images: [
{
url: imageUrl,
width: 1200,
height: 630,
alt: post.frontmatter.title,
},
],
},
twitter: {
card: 'summary_large_image',
title: post.frontmatter.title,
title: `${post.frontmatter.title} | KLZ Cables`,
description: description,
images: [imageUrl],
},
};
}

View File

@@ -15,6 +15,33 @@ export async function generateMetadata({ params: { locale } }: BlogIndexProps) {
return {
title: t('title'),
description: t('description'),
alternates: {
canonical: `/${locale}/blog`,
languages: {
'de': '/de/blog',
'en': '/en/blog',
'x-default': '/en/blog',
},
},
openGraph: {
title: `${t('title')} | KLZ Cables`,
description: t('description'),
url: `https://klz-cables.com/${locale}/blog`,
images: [
{
url: '/uploads/2025/02/og-2.webp',
width: 1200,
height: 630,
alt: t('title'),
},
],
},
twitter: {
card: 'summary_large_image',
title: `${t('title')} | KLZ Cables`,
description: t('description'),
images: ['/uploads/2025/02/og-2.webp'],
},
};
}

View File

@@ -1,6 +1,49 @@
import { useTranslations } from 'next-intl';
import { getTranslations } from 'next-intl/server';
import { Metadata } from 'next';
import { Section, Container, Button, Heading, Card, Input, Textarea, Label } from '@/components/ui';
interface ContactPageProps {
params: {
locale: string;
};
}
export async function generateMetadata({ params: { locale } }: ContactPageProps): Promise<Metadata> {
const t = await getTranslations({ locale, namespace: 'Contact' });
return {
title: t('title'),
description: t('subtitle'),
alternates: {
canonical: `/${locale}/contact`,
languages: {
'de': '/de/contact',
'en': '/en/contact',
'x-default': '/en/contact',
},
},
openGraph: {
title: `${t('title')} | KLZ Cables`,
description: t('subtitle'),
url: `https://klz-cables.com/${locale}/contact`,
images: [
{
url: '/uploads/2025/02/og-2.webp',
width: 1200,
height: 630,
alt: t('title'),
},
],
},
twitter: {
card: 'summary_large_image',
title: `${t('title')} | KLZ Cables`,
description: t('subtitle'),
images: ['/uploads/2025/02/og-2.webp'],
},
};
}
export default function ContactPage() {
const t = useTranslations('Contact');

View File

@@ -13,15 +13,20 @@ export async function generateMetadata({params: {locale}}: {params: {locale: str
return {
title: {
default: t('title'),
template: `%s | ${t('title')}`
template: `%s | KLZ Cables`
},
description: t('description'),
metadataBase: new URL('https://klz-cables.com'),
icons: {
icon: '/favicon.ico',
apple: '/apple-touch-icon.png',
},
alternates: {
canonical: `/${locale}`,
languages: {
'de-DE': '/de',
'en-US': '/en',
'de': '/de',
'en': '/en',
'x-default': '/en',
},
},
openGraph: {
@@ -31,11 +36,20 @@ export async function generateMetadata({params: {locale}}: {params: {locale: str
siteName: 'KLZ Cables',
title: t('title'),
description: t('description'),
images: [
{
url: '/uploads/2025/02/og-2.webp',
width: 1200,
height: 630,
alt: 'KLZ Cables',
},
],
},
twitter: {
card: 'summary_large_image',
title: t('title'),
description: t('description'),
images: ['/uploads/2025/02/og-2.webp'],
},
robots: {
index: true,

View File

@@ -34,30 +34,71 @@ export async function generateMetadata({ params }: ProductPageProps): Promise<Me
return {
title: categoryTitle,
description: categoryDesc,
alternates: {
canonical: `/${locale}/products/${productSlug}`,
languages: {
'de': `/de/products/${productSlug}`,
'en': `/en/products/${productSlug}`,
'x-default': `/en/products/${productSlug}`,
},
},
openGraph: {
title: categoryTitle,
title: `${categoryTitle} | KLZ Cables`,
description: categoryDesc,
url: `https://klz-cables.com/${locale}/products/${productSlug}`,
}
images: [
{
url: '/uploads/2025/02/og-2.webp',
width: 1200,
height: 630,
alt: categoryTitle,
},
],
},
twitter: {
card: 'summary_large_image',
title: `${categoryTitle} | KLZ Cables`,
description: categoryDesc,
images: ['/uploads/2025/02/og-2.webp'],
},
};
}
const product = await getProductBySlug(productSlug, locale);
if (!product) return {};
const imageUrl = product.frontmatter.images?.[0] || '/uploads/2025/02/og-2.webp';
return {
title: product.frontmatter.title,
description: product.frontmatter.description,
alternates: {
canonical: `/${locale}/products/${slug.join('/')}`,
languages: {
'de': `/de/products/${slug.join('/')}`,
'en': `/en/products/${slug.join('/')}`,
'x-default': `/en/products/${slug.join('/')}`,
},
},
openGraph: {
title: product.frontmatter.title,
title: `${product.frontmatter.title} | KLZ Cables`,
description: product.frontmatter.description,
type: 'website',
url: `https://klz-cables.com/${locale}/products/${slug.join('/')}`,
images: [
{
url: imageUrl,
width: 1200,
height: 630,
alt: product.frontmatter.title,
},
],
},
twitter: {
card: 'summary_large_image',
title: product.frontmatter.title,
title: `${product.frontmatter.title} | KLZ Cables`,
description: product.frontmatter.description,
images: [imageUrl],
},
};
}

View File

@@ -2,6 +2,8 @@ import Reveal from '@/components/Reveal';
import Scribble from '@/components/Scribble';
import { Badge, Button, Card, Container, Section } from '@/components/ui';
import { useTranslations } from 'next-intl';
import { getTranslations } from 'next-intl/server';
import { Metadata } from 'next';
import Image from 'next/image';
import Link from 'next/link';
@@ -11,6 +13,41 @@ interface ProductsPageProps {
};
}
export async function generateMetadata({ params: { locale } }: ProductsPageProps): Promise<Metadata> {
const t = await getTranslations({ locale, namespace: 'Products' });
return {
title: t('title'),
description: t('subtitle'),
alternates: {
canonical: `/${locale}/products`,
languages: {
'de': '/de/products',
'en': '/en/products',
'x-default': '/en/products',
},
},
openGraph: {
title: `${t('title')} | KLZ Cables`,
description: t('subtitle'),
url: `https://klz-cables.com/${locale}/products`,
images: [
{
url: '/uploads/2025/02/og-2.webp',
width: 1200,
height: 630,
alt: t('title'),
},
],
},
twitter: {
card: 'summary_large_image',
title: `${t('title')} | KLZ Cables`,
description: t('subtitle'),
images: ['/uploads/2025/02/og-2.webp'],
},
};
}
export default function ProductsPage({ params }: ProductsPageProps) {
const t = useTranslations('Products');

View File

@@ -1,8 +1,51 @@
import { useTranslations } from 'next-intl';
import { getTranslations } from 'next-intl/server';
import { Metadata } from 'next';
import { Section, Container, Heading, Badge, Button } from '@/components/ui';
import Image from 'next/image';
import Reveal from '@/components/Reveal';
interface TeamPageProps {
params: {
locale: string;
};
}
export async function generateMetadata({ params: { locale } }: TeamPageProps): Promise<Metadata> {
const t = await getTranslations({ locale, namespace: 'Team' });
return {
title: t('hero.subtitle'),
description: t('hero.title'),
alternates: {
canonical: `/${locale}/team`,
languages: {
'de': '/de/team',
'en': '/en/team',
'x-default': '/en/team',
},
},
openGraph: {
title: `${t('hero.subtitle')} | KLZ Cables`,
description: t('hero.title'),
url: `https://klz-cables.com/${locale}/team`,
images: [
{
url: '/uploads/2024/12/DSC07655-Large.webp',
width: 1200,
height: 630,
alt: t('hero.subtitle'),
},
],
},
twitter: {
card: 'summary_large_image',
title: `${t('hero.subtitle')} | KLZ Cables`,
description: t('hero.title'),
images: ['/uploads/2024/12/DSC07655-Large.webp'],
},
};
}
export default function TeamPage() {
const t = useTranslations('Team');

25
app/manifest.ts Normal file
View File

@@ -0,0 +1,25 @@
import { MetadataRoute } from 'next';
export default function manifest(): MetadataRoute.Manifest {
return {
name: 'KLZ Cables',
short_name: 'KLZ',
description: 'Premium Cable Solutions',
start_url: '/',
display: 'standalone',
background_color: '#001a4d',
theme_color: '#001a4d',
icons: [
{
src: '/favicon.ico',
sizes: 'any',
type: 'image/x-icon',
},
{
src: '/apple-touch-icon.png',
sizes: '180x180',
type: 'image/png',
},
],
};
}

12
app/robots.ts Normal file
View File

@@ -0,0 +1,12 @@
import { MetadataRoute } from 'next';
export default function robots(): MetadataRoute.Robots {
return {
rules: {
userAgent: '*',
allow: '/',
disallow: ['/api/', '/health/'],
},
sitemap: 'https://klz-cables.com/sitemap.xml',
};
}

74
app/sitemap.ts Normal file
View File

@@ -0,0 +1,74 @@
import { MetadataRoute } from 'next';
import { getAllProducts } from '@/lib/mdx';
import { getAllPosts } from '@/lib/blog';
import { getAllPages } from '@/lib/pages';
export default async function sitemap(): Promise<MetadataRoute.Sitemap> {
const baseUrl = 'https://klz-cables.com';
const locales = ['de', 'en'];
const routes = [
'',
'/blog',
'/contact',
'/team',
'/products',
'/products/low-voltage-cables',
'/products/medium-voltage-cables',
'/products/high-voltage-cables',
'/products/solar-cables',
];
const sitemapEntries: MetadataRoute.Sitemap = [];
for (const locale of locales) {
// Static routes
for (const route of routes) {
sitemapEntries.push({
url: `${baseUrl}/${locale}${route}`,
lastModified: new Date(),
changeFrequency: route === '' ? 'daily' : 'weekly',
priority: route === '' ? 1 : 0.8,
});
}
// Products
const products = await getAllProducts(locale);
for (const product of products) {
// We need to find the category for the product to build the URL
// In this project, products are under /products/[category]/[slug]
// The category is in product.frontmatter.categories
const category = product.frontmatter.categories[0]?.toLowerCase().replace(/\s+/g, '-') || 'other';
sitemapEntries.push({
url: `${baseUrl}/${locale}/products/${category}/${product.slug}`,
lastModified: new Date(),
changeFrequency: 'monthly',
priority: 0.7,
});
}
// Blog posts
const posts = await getAllPosts(locale);
for (const post of posts) {
sitemapEntries.push({
url: `${baseUrl}/${locale}/blog/${post.slug}`,
lastModified: new Date(post.frontmatter.date),
changeFrequency: 'monthly',
priority: 0.6,
});
}
// Static pages
const pages = await getAllPages(locale);
for (const page of pages) {
sitemapEntries.push({
url: `${baseUrl}/${locale}/${page.slug}`,
lastModified: new Date(),
changeFrequency: 'monthly',
priority: 0.5,
});
}
}
return sitemapEntries;
}

View File

@@ -32,3 +32,17 @@ export async function getPageBySlug(slug: string, locale: string): Promise<PageM
content,
};
}
export async function getAllPages(locale: string): Promise<PageMdx[]> {
const pagesDir = path.join(process.cwd(), 'data', 'pages', locale);
if (!fs.existsSync(pagesDir)) return [];
const files = fs.readdirSync(pagesDir);
const pages = await Promise.all(
files
.filter(file => file.endsWith('.mdx'))
.map(file => getPageBySlug(file.replace(/\.mdx$/, ''), locale))
);
return pages.filter((p): p is PageMdx => p !== null);
}

View File

@@ -3,8 +3,8 @@
"title": "KLZ Cables - Hochwertige Kabel",
"description": "Ihr Partner für hochwertige Kabel.",
"meta": {
"title": "KLZ Cables",
"description": "Premium-Kabellösungen"
"title": "KLZ Cables | Hochwertige Strom- & Solarkabel",
"description": "Ihr Experte für hochwertige Stromkabel, Mittelspannungslösungen und Solarkabel. Zuverlässige Infrastruktur für eine grüne Energiezukunft."
}
},
"Navigation": {
@@ -287,8 +287,8 @@
},
"Blog": {
"meta": {
"title": "Neuigkeiten zu Kabeln und Energielösungen",
"description": "Bleiben Sie auf dem Laufenden! Lesen Sie aktuelle Themen und Insights zu Kabeltechnologie, Energielösungen und branchenspezifischen Innovationen."
"title": "Kabel-News & Energie-Insights | KLZ Cables Blog",
"description": "Bleiben Sie informiert über die neuesten Trends in der Kabeltechnologie, Energieinfrastruktur und nachhaltigen Stromlösungen. Expertenwissen von KLZ Cables."
},
"featuredPost": "Hervorgehobener Beitrag",
"readFullArticle": "Vollständigen Artikel lesen",

View File

@@ -3,8 +3,8 @@
"title": "KLZ Cables - High Quality Cables",
"description": "Your partner for high quality cables.",
"meta": {
"title": "KLZ Cables",
"description": "Premium Cable Solutions"
"title": "KLZ Cables | High-Quality Power & Solar Cables",
"description": "Your expert partner for high-quality power cables, medium voltage solutions, and solar cables. Reliable infrastructure for a green energy future."
}
},
"Navigation": {
@@ -287,8 +287,8 @@
},
"Blog": {
"meta": {
"title": "News on Cables and Energy Solutions",
"description": "Stay up to date! Read current topics and insights on cable technology, energy solutions and industry-specific innovations."
"title": "Cable Industry News & Energy Insights | KLZ Cables Blog",
"description": "Stay informed with the latest trends in cable technology, energy infrastructure, and sustainable power solutions. Expert insights from KLZ Cables."
},
"featuredPost": "Featured Post",
"readFullArticle": "Read Full Article",

File diff suppressed because one or more lines are too long