wip
This commit is contained in:
113
app/[locale]/blog/[slug]/opengraph-image.tsx
Normal file
113
app/[locale]/blog/[slug]/opengraph-image.tsx
Normal file
@@ -0,0 +1,113 @@
|
|||||||
|
import { ImageResponse } from 'next/og';
|
||||||
|
import { getPostBySlug } from '@/lib/blog';
|
||||||
|
|
||||||
|
export const runtime = 'edge';
|
||||||
|
|
||||||
|
export default async function Image({ params: { locale, slug } }: { params: { locale: string, slug: string } }) {
|
||||||
|
const post = await getPostBySlug(slug, locale);
|
||||||
|
|
||||||
|
if (!post) {
|
||||||
|
return new ImageResponse(
|
||||||
|
<div style={{ display: 'flex', width: '100%', height: '100%', backgroundColor: '#001a4d' }} />
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new ImageResponse(
|
||||||
|
(
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
height: '100%',
|
||||||
|
width: '100%',
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'column',
|
||||||
|
alignItems: 'flex-start',
|
||||||
|
justifyContent: 'flex-end',
|
||||||
|
backgroundColor: '#001a4d',
|
||||||
|
padding: '80px',
|
||||||
|
position: 'relative',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{/* Background Image Overlay if available */}
|
||||||
|
{post.frontmatter.featuredImage && (
|
||||||
|
<img
|
||||||
|
src={post.frontmatter.featuredImage.startsWith('http') ? post.frontmatter.featuredImage : `https://klz-cables.com${post.frontmatter.featuredImage}`}
|
||||||
|
alt=""
|
||||||
|
style={{
|
||||||
|
position: 'absolute',
|
||||||
|
inset: 0,
|
||||||
|
width: '100%',
|
||||||
|
height: '100%',
|
||||||
|
objectFit: 'cover',
|
||||||
|
opacity: 0.4,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* Gradient Overlay */}
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
position: 'absolute',
|
||||||
|
inset: 0,
|
||||||
|
background: 'linear-gradient(to top, rgba(0,26,77,1) 0%, rgba(0,26,77,0.4) 100%)',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<div style={{ display: 'flex', flexDirection: 'column', position: 'relative', zIndex: 10 }}>
|
||||||
|
{post.frontmatter.category && (
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
fontSize: '20px',
|
||||||
|
fontWeight: 'bold',
|
||||||
|
color: '#00ff99',
|
||||||
|
textTransform: 'uppercase',
|
||||||
|
letterSpacing: '0.1em',
|
||||||
|
marginBottom: '16px',
|
||||||
|
backgroundColor: 'rgba(0,255,153,0.1)',
|
||||||
|
padding: '4px 12px',
|
||||||
|
borderRadius: '4px',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{post.frontmatter.category}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
fontSize: '64px',
|
||||||
|
fontWeight: '900',
|
||||||
|
color: 'white',
|
||||||
|
lineHeight: '1.1',
|
||||||
|
maxWidth: '900px',
|
||||||
|
marginBottom: '24px',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{post.frontmatter.title}
|
||||||
|
</div>
|
||||||
|
<div style={{ display: 'flex', alignItems: 'center' }}>
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
fontSize: '24px',
|
||||||
|
color: 'rgba(255,255,255,0.6)',
|
||||||
|
fontWeight: '500',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
KLZ Cables Blog
|
||||||
|
</div>
|
||||||
|
<div style={{ width: '8px', height: '8px', borderRadius: '50%', backgroundColor: '#00ff99', margin: '0 16px' }} />
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
fontSize: '24px',
|
||||||
|
color: 'rgba(255,255,255,0.6)',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{new Date(post.frontmatter.date).toLocaleDateString(locale, { year: 'numeric', month: 'long', day: 'numeric' })}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
),
|
||||||
|
{
|
||||||
|
width: 1200,
|
||||||
|
height: 630,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
import { notFound } from 'next/navigation';
|
import { notFound } from 'next/navigation';
|
||||||
import { MDXRemote } from 'next-mdx-remote/rsc';
|
import { MDXRemote } from 'next-mdx-remote/rsc';
|
||||||
import { getPostBySlug, getAdjacentPosts } from '@/lib/blog';
|
import { getPostBySlug, getAdjacentPosts } from '@/lib/blog';
|
||||||
|
import { Metadata } from 'next';
|
||||||
|
|
||||||
interface BlogPostProps {
|
interface BlogPostProps {
|
||||||
params: {
|
params: {
|
||||||
@@ -9,6 +10,32 @@ interface BlogPostProps {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function generateMetadata({ params: { locale, slug } }: BlogPostProps): Promise<Metadata> {
|
||||||
|
const post = await getPostBySlug(slug, locale);
|
||||||
|
|
||||||
|
if (!post) return {};
|
||||||
|
|
||||||
|
const description = post.frontmatter.excerpt || '';
|
||||||
|
|
||||||
|
return {
|
||||||
|
title: post.frontmatter.title,
|
||||||
|
description: description,
|
||||||
|
openGraph: {
|
||||||
|
title: post.frontmatter.title,
|
||||||
|
description: description,
|
||||||
|
type: 'article',
|
||||||
|
publishedTime: post.frontmatter.date,
|
||||||
|
authors: ['KLZ Cables'],
|
||||||
|
url: `https://klz-cables.com/${locale}/blog/${slug}`,
|
||||||
|
},
|
||||||
|
twitter: {
|
||||||
|
card: 'summary_large_image',
|
||||||
|
title: post.frontmatter.title,
|
||||||
|
description: description,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
import VisualLinkPreview from '@/components/blog/VisualLinkPreview';
|
import VisualLinkPreview from '@/components/blog/VisualLinkPreview';
|
||||||
import Callout from '@/components/blog/Callout';
|
import Callout from '@/components/blog/Callout';
|
||||||
@@ -253,6 +280,34 @@ export default async function BlogPost({ params: { locale, slug } }: BlogPostPro
|
|||||||
<MDXRemote source={post.content} components={components} />
|
<MDXRemote source={post.content} components={components} />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* Structured Data */}
|
||||||
|
<script
|
||||||
|
type="application/ld+json"
|
||||||
|
dangerouslySetInnerHTML={{
|
||||||
|
__html: JSON.stringify({
|
||||||
|
'@context': 'https://schema.org',
|
||||||
|
'@type': 'BlogPosting',
|
||||||
|
headline: post.frontmatter.title,
|
||||||
|
datePublished: post.frontmatter.date,
|
||||||
|
image: post.frontmatter.featuredImage ? `https://klz-cables.com${post.frontmatter.featuredImage}` : undefined,
|
||||||
|
author: {
|
||||||
|
'@type': 'Organization',
|
||||||
|
name: 'KLZ Cables',
|
||||||
|
url: 'https://klz-cables.com',
|
||||||
|
},
|
||||||
|
publisher: {
|
||||||
|
'@type': 'Organization',
|
||||||
|
name: 'KLZ Cables',
|
||||||
|
logo: {
|
||||||
|
'@type': 'ImageObject',
|
||||||
|
url: 'https://klz-cables.com/logo.png', // Assuming logo exists
|
||||||
|
},
|
||||||
|
},
|
||||||
|
description: post.frontmatter.excerpt,
|
||||||
|
}),
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
{/* Power CTA */}
|
{/* Power CTA */}
|
||||||
<div className="mt-20">
|
<div className="mt-20">
|
||||||
<PowerCTA locale={locale} />
|
<PowerCTA locale={locale} />
|
||||||
|
|||||||
@@ -9,8 +9,43 @@ export async function generateMetadata({params: {locale}}: {params: {locale: str
|
|||||||
const t = await getTranslations({locale, namespace: 'Index.meta'});
|
const t = await getTranslations({locale, namespace: 'Index.meta'});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
title: t('title'),
|
title: {
|
||||||
description: t('description')
|
default: t('title'),
|
||||||
|
template: `%s | ${t('title')}`
|
||||||
|
},
|
||||||
|
description: t('description'),
|
||||||
|
metadataBase: new URL('https://klz-cables.com'),
|
||||||
|
alternates: {
|
||||||
|
canonical: `/${locale}`,
|
||||||
|
languages: {
|
||||||
|
'de-DE': '/de',
|
||||||
|
'en-US': '/en',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
openGraph: {
|
||||||
|
type: 'website',
|
||||||
|
locale: locale === 'de' ? 'de_DE' : 'en_US',
|
||||||
|
url: `https://klz-cables.com/${locale}`,
|
||||||
|
siteName: 'KLZ Cables',
|
||||||
|
title: t('title'),
|
||||||
|
description: t('description'),
|
||||||
|
},
|
||||||
|
twitter: {
|
||||||
|
card: 'summary_large_image',
|
||||||
|
title: t('title'),
|
||||||
|
description: t('description'),
|
||||||
|
},
|
||||||
|
robots: {
|
||||||
|
index: true,
|
||||||
|
follow: true,
|
||||||
|
googleBot: {
|
||||||
|
index: true,
|
||||||
|
follow: true,
|
||||||
|
'max-video-preview': -1,
|
||||||
|
'max-image-preview': 'large',
|
||||||
|
'max-snippet': -1,
|
||||||
|
},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
92
app/[locale]/opengraph-image.tsx
Normal file
92
app/[locale]/opengraph-image.tsx
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
import { ImageResponse } from 'next/og';
|
||||||
|
import { getTranslations } from 'next-intl/server';
|
||||||
|
|
||||||
|
export const runtime = 'edge';
|
||||||
|
|
||||||
|
export default async function Image({ params: { locale } }: { params: { locale: string } }) {
|
||||||
|
const t = await getTranslations({ locale, namespace: 'Index.meta' });
|
||||||
|
|
||||||
|
return new ImageResponse(
|
||||||
|
(
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
height: '100%',
|
||||||
|
width: '100%',
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'column',
|
||||||
|
alignItems: 'flex-start',
|
||||||
|
justifyContent: 'center',
|
||||||
|
backgroundColor: '#001a4d', // Primary Blue from Styleguide
|
||||||
|
padding: '80px',
|
||||||
|
position: 'relative',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{/* Background Pattern / Scribble placeholder */}
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
position: 'absolute',
|
||||||
|
top: '-100px',
|
||||||
|
right: '-100px',
|
||||||
|
width: '600px',
|
||||||
|
height: '600px',
|
||||||
|
borderRadius: '50%',
|
||||||
|
background: 'radial-gradient(circle, rgba(0,255,153,0.1) 0%, transparent 70%)',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<div style={{ display: 'flex', flexDirection: 'column' }}>
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
fontSize: '24px',
|
||||||
|
fontWeight: 'bold',
|
||||||
|
color: '#00ff99', // Accent Green
|
||||||
|
textTransform: 'uppercase',
|
||||||
|
letterSpacing: '0.2em',
|
||||||
|
marginBottom: '20px',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
KLZ Cables
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
fontSize: '72px',
|
||||||
|
fontWeight: '900',
|
||||||
|
color: 'white',
|
||||||
|
lineHeight: '1.1',
|
||||||
|
maxWidth: '800px',
|
||||||
|
marginBottom: '30px',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{t('title')}
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
fontSize: '32px',
|
||||||
|
color: 'rgba(255,255,255,0.7)',
|
||||||
|
maxWidth: '700px',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{t('description')}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Bottom Accent Line */}
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
position: 'absolute',
|
||||||
|
bottom: '80px',
|
||||||
|
left: '80px',
|
||||||
|
width: '120px',
|
||||||
|
height: '8px',
|
||||||
|
backgroundColor: '#00ff99',
|
||||||
|
borderRadius: '4px',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
),
|
||||||
|
{
|
||||||
|
width: 1200,
|
||||||
|
height: 630,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
135
app/[locale]/products/[...slug]/opengraph-image.tsx
Normal file
135
app/[locale]/products/[...slug]/opengraph-image.tsx
Normal file
@@ -0,0 +1,135 @@
|
|||||||
|
import { ImageResponse } from 'next/og';
|
||||||
|
import { getProductBySlug } from '@/lib/mdx';
|
||||||
|
|
||||||
|
export const runtime = 'edge';
|
||||||
|
|
||||||
|
export default async function Image({ params: { locale, slug } }: { params: { locale: string, slug: string[] } }) {
|
||||||
|
const productSlug = slug[slug.length - 1];
|
||||||
|
const product = await getProductBySlug(productSlug, locale);
|
||||||
|
|
||||||
|
if (!product) {
|
||||||
|
return new ImageResponse(
|
||||||
|
<div style={{ display: 'flex', width: '100%', height: '100%', backgroundColor: '#001a4d' }} />
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new ImageResponse(
|
||||||
|
(
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
height: '100%',
|
||||||
|
width: '100%',
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'row',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'space-between',
|
||||||
|
backgroundColor: 'white',
|
||||||
|
padding: '60px',
|
||||||
|
position: 'relative',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{/* Left Side: Content */}
|
||||||
|
<div style={{ display: 'flex', flexDirection: 'column', width: '55%' }}>
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
fontSize: '20px',
|
||||||
|
fontWeight: 'bold',
|
||||||
|
color: '#001a4d',
|
||||||
|
textTransform: 'uppercase',
|
||||||
|
letterSpacing: '0.2em',
|
||||||
|
marginBottom: '20px',
|
||||||
|
opacity: 0.6,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
KLZ Cables | {product.frontmatter.categories[0]}
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
fontSize: '72px',
|
||||||
|
fontWeight: '900',
|
||||||
|
color: '#001a4d',
|
||||||
|
lineHeight: '1.1',
|
||||||
|
marginBottom: '30px',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{product.frontmatter.title}
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
fontSize: '28px',
|
||||||
|
color: '#4a5568',
|
||||||
|
lineHeight: '1.4',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{product.frontmatter.description}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Accent Line */}
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
marginTop: '40px',
|
||||||
|
width: '100px',
|
||||||
|
height: '8px',
|
||||||
|
backgroundColor: '#00ff99',
|
||||||
|
borderRadius: '4px',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Right Side: Product Image */}
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
display: 'flex',
|
||||||
|
width: '40%',
|
||||||
|
height: '100%',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
position: 'relative',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{product.frontmatter.images?.[0] && (
|
||||||
|
<img
|
||||||
|
src={product.frontmatter.images[0].startsWith('http') ? product.frontmatter.images[0] : `https://klz-cables.com${product.frontmatter.images[0]}`}
|
||||||
|
alt=""
|
||||||
|
style={{
|
||||||
|
maxWidth: '100%',
|
||||||
|
maxHeight: '80%',
|
||||||
|
objectFit: 'contain',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
{/* Subtle shadow under product */}
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
position: 'absolute',
|
||||||
|
bottom: '10%',
|
||||||
|
width: '60%',
|
||||||
|
height: '20px',
|
||||||
|
backgroundColor: 'rgba(0,0,0,0.05)',
|
||||||
|
borderRadius: '50%',
|
||||||
|
filter: 'blur(10px)',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Branding Corner */}
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
position: 'absolute',
|
||||||
|
bottom: '40px',
|
||||||
|
right: '60px',
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div style={{ fontSize: '24px', fontWeight: 'bold', color: '#001a4d' }}>KLZ</div>
|
||||||
|
<div style={{ fontSize: '24px', fontWeight: 'normal', color: '#00ff99', marginLeft: '4px' }}>Cables</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
),
|
||||||
|
{
|
||||||
|
width: 1200,
|
||||||
|
height: 630,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -10,6 +10,7 @@ import Image from 'next/image';
|
|||||||
import { getTranslations } from 'next-intl/server';
|
import { getTranslations } from 'next-intl/server';
|
||||||
import { Section, Container, Heading, Badge, Button } from '@/components/ui';
|
import { Section, Container, Heading, Badge, Button } from '@/components/ui';
|
||||||
import Scribble from '@/components/Scribble';
|
import Scribble from '@/components/Scribble';
|
||||||
|
import { Metadata } from 'next';
|
||||||
|
|
||||||
interface ProductPageProps {
|
interface ProductPageProps {
|
||||||
params: {
|
params: {
|
||||||
@@ -18,6 +19,49 @@ interface ProductPageProps {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function generateMetadata({ params }: ProductPageProps): Promise<Metadata> {
|
||||||
|
const { locale, slug } = params;
|
||||||
|
const productSlug = slug[slug.length - 1];
|
||||||
|
const t = await getTranslations('Products');
|
||||||
|
|
||||||
|
// Check if it's a category page
|
||||||
|
const categories = ['low-voltage-cables', 'medium-voltage-cables', 'high-voltage-cables', 'solar-cables'];
|
||||||
|
if (categories.includes(productSlug)) {
|
||||||
|
const categoryKey = productSlug.replace(/-cables$/, '').replace(/-([a-z])/g, (g) => g[1].toUpperCase());
|
||||||
|
const categoryTitle = t(`categories.${categoryKey}.title`);
|
||||||
|
const categoryDesc = t(`categories.${categoryKey}.description`);
|
||||||
|
|
||||||
|
return {
|
||||||
|
title: categoryTitle,
|
||||||
|
description: categoryDesc,
|
||||||
|
openGraph: {
|
||||||
|
title: categoryTitle,
|
||||||
|
description: categoryDesc,
|
||||||
|
url: `https://klz-cables.com/${locale}/products/${productSlug}`,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const product = await getProductBySlug(productSlug, locale);
|
||||||
|
if (!product) return {};
|
||||||
|
|
||||||
|
return {
|
||||||
|
title: product.frontmatter.title,
|
||||||
|
description: product.frontmatter.description,
|
||||||
|
openGraph: {
|
||||||
|
title: product.frontmatter.title,
|
||||||
|
description: product.frontmatter.description,
|
||||||
|
type: 'website',
|
||||||
|
url: `https://klz-cables.com/${locale}/products/${slug.join('/')}`,
|
||||||
|
},
|
||||||
|
twitter: {
|
||||||
|
card: 'summary_large_image',
|
||||||
|
title: product.frontmatter.title,
|
||||||
|
description: product.frontmatter.description,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
const components = {
|
const components = {
|
||||||
ProductTechnicalData,
|
ProductTechnicalData,
|
||||||
ProductTabs,
|
ProductTabs,
|
||||||
@@ -224,6 +268,31 @@ export default async function ProductPage({ params }: ProductPageProps) {
|
|||||||
<MDXRemote source={product.content} components={components} />
|
<MDXRemote source={product.content} components={components} />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* Structured Data */}
|
||||||
|
<script
|
||||||
|
type="application/ld+json"
|
||||||
|
dangerouslySetInnerHTML={{
|
||||||
|
__html: JSON.stringify({
|
||||||
|
'@context': 'https://schema.org',
|
||||||
|
'@type': 'Product',
|
||||||
|
name: product.frontmatter.title,
|
||||||
|
description: product.frontmatter.description,
|
||||||
|
sku: product.frontmatter.sku,
|
||||||
|
image: product.frontmatter.images?.[0] ? `https://klz-cables.com${product.frontmatter.images[0]}` : undefined,
|
||||||
|
brand: {
|
||||||
|
'@type': 'Brand',
|
||||||
|
name: 'KLZ Cables',
|
||||||
|
},
|
||||||
|
offers: {
|
||||||
|
'@type': 'Offer',
|
||||||
|
availability: 'https://schema.org/InStock',
|
||||||
|
priceCurrency: 'EUR',
|
||||||
|
url: `https://klz-cables.com/${locale}/products/${slug.join('/')}`,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
{/* Related Products */}
|
{/* Related Products */}
|
||||||
<RelatedProducts
|
<RelatedProducts
|
||||||
currentSlug={productSlug}
|
currentSlug={productSlug}
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user