Compare commits
3 Commits
v1.2.11-rc
...
v1.1.7
| Author | SHA1 | Date | |
|---|---|---|---|
| 8652dd722e | |||
| 5e48c75a83 | |||
| 50fc8a0554 |
@@ -14,6 +14,7 @@ jobs:
|
|||||||
uses: actions/setup-node@v4
|
uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version: 20
|
node-version: 20
|
||||||
|
cache: 'pnpm'
|
||||||
|
|
||||||
- name: Setup pnpm
|
- name: Setup pnpm
|
||||||
uses: pnpm/action-setup@v3
|
uses: pnpm/action-setup@v3
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
echo "Purging old build layers and dangling images..."
|
echo "Purging old build layers and dangling images..."
|
||||||
docker image prune -f
|
docker image prune -f
|
||||||
docker builder prune -f --filter "until=6h"
|
docker builder prune -f --filter "until=24h"
|
||||||
|
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
@@ -158,6 +158,7 @@ jobs:
|
|||||||
uses: actions/setup-node@v4
|
uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version: 20
|
node-version: 20
|
||||||
|
cache: 'pnpm'
|
||||||
- name: Setup pnpm
|
- name: Setup pnpm
|
||||||
uses: pnpm/action-setup@v3
|
uses: pnpm/action-setup@v3
|
||||||
with:
|
with:
|
||||||
@@ -180,7 +181,7 @@ jobs:
|
|||||||
# ──────────────────────────────────────────────────────────────────────────────
|
# ──────────────────────────────────────────────────────────────────────────────
|
||||||
build:
|
build:
|
||||||
name: 🏗️ Build
|
name: 🏗️ Build
|
||||||
needs: [prepare, qa]
|
needs: [prepare]
|
||||||
if: needs.prepare.outputs.target != 'skip'
|
if: needs.prepare.outputs.target != 'skip'
|
||||||
runs-on: docker
|
runs-on: docker
|
||||||
container:
|
container:
|
||||||
@@ -379,7 +380,7 @@ jobs:
|
|||||||
smoke_test:
|
smoke_test:
|
||||||
name: 🧪 Smoke Test
|
name: 🧪 Smoke Test
|
||||||
needs: [prepare, deploy]
|
needs: [prepare, deploy]
|
||||||
if: needs.deploy.result == 'success'
|
if: needs.deploy.result == 'success' && needs.prepare.outputs.target != 'branch'
|
||||||
runs-on: docker
|
runs-on: docker
|
||||||
container:
|
container:
|
||||||
image: catthehacker/ubuntu:act-latest
|
image: catthehacker/ubuntu:act-latest
|
||||||
@@ -390,6 +391,7 @@ jobs:
|
|||||||
uses: actions/setup-node@v4
|
uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version: 20
|
node-version: 20
|
||||||
|
cache: 'pnpm'
|
||||||
- name: Setup pnpm
|
- name: Setup pnpm
|
||||||
uses: pnpm/action-setup@v3
|
uses: pnpm/action-setup@v3
|
||||||
with:
|
with:
|
||||||
@@ -411,7 +413,7 @@ jobs:
|
|||||||
lighthouse:
|
lighthouse:
|
||||||
name: ⚡ Lighthouse
|
name: ⚡ Lighthouse
|
||||||
needs: [prepare, deploy]
|
needs: [prepare, deploy]
|
||||||
if: success() && needs.prepare.outputs.target != 'skip'
|
if: success() && needs.prepare.outputs.target != 'skip' && needs.prepare.outputs.target != 'branch'
|
||||||
runs-on: docker
|
runs-on: docker
|
||||||
container:
|
container:
|
||||||
image: catthehacker/ubuntu:act-latest
|
image: catthehacker/ubuntu:act-latest
|
||||||
@@ -422,6 +424,7 @@ jobs:
|
|||||||
uses: actions/setup-node@v4
|
uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version: 20
|
node-version: 20
|
||||||
|
cache: 'pnpm'
|
||||||
- name: Setup pnpm
|
- name: Setup pnpm
|
||||||
uses: pnpm/action-setup@v3
|
uses: pnpm/action-setup@v3
|
||||||
with:
|
with:
|
||||||
|
|||||||
@@ -53,17 +53,17 @@ export async function generateMetadata({ params }: ProductPageProps): Promise<Me
|
|||||||
title: categoryTitle,
|
title: categoryTitle,
|
||||||
description: categoryDesc,
|
description: categoryDesc,
|
||||||
alternates: {
|
alternates: {
|
||||||
canonical: `${SITE_URL}/${locale}/products/${productSlug}`,
|
canonical: `${SITE_URL}/${locale}/${await mapFileSlugToTranslated('products', locale)}/${productSlug}`,
|
||||||
languages: {
|
languages: {
|
||||||
de: `${SITE_URL}/de/products/${await mapFileSlugToTranslated(productSlug, 'de')}`,
|
de: `${SITE_URL}/de/${await mapFileSlugToTranslated('products', 'de')}/${await mapFileSlugToTranslated(productSlug, 'de')}`,
|
||||||
en: `${SITE_URL}/en/products/${await mapFileSlugToTranslated(productSlug, 'en')}`,
|
en: `${SITE_URL}/en/${await mapFileSlugToTranslated('products', 'en')}/${await mapFileSlugToTranslated(productSlug, 'en')}`,
|
||||||
'x-default': `${SITE_URL}/en/products/${await mapFileSlugToTranslated(productSlug, 'en')}`,
|
'x-default': `${SITE_URL}/en/${await mapFileSlugToTranslated('products', 'en')}/${await mapFileSlugToTranslated(productSlug, 'en')}`,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
openGraph: {
|
openGraph: {
|
||||||
title: `${categoryTitle} | KLZ Cables`,
|
title: `${categoryTitle} | KLZ Cables`,
|
||||||
description: categoryDesc,
|
description: categoryDesc,
|
||||||
url: `${SITE_URL}/${locale}/products/${productSlug}`,
|
url: `${SITE_URL}/${locale}/${await mapFileSlugToTranslated('products', locale)}/${productSlug}`,
|
||||||
images: getProductOGImageMetadata(fileSlug, categoryTitle, locale),
|
images: getProductOGImageMetadata(fileSlug, categoryTitle, locale),
|
||||||
},
|
},
|
||||||
twitter: {
|
twitter: {
|
||||||
@@ -81,18 +81,18 @@ export async function generateMetadata({ params }: ProductPageProps): Promise<Me
|
|||||||
title: product.frontmatter.title,
|
title: product.frontmatter.title,
|
||||||
description: product.frontmatter.description,
|
description: product.frontmatter.description,
|
||||||
alternates: {
|
alternates: {
|
||||||
canonical: `${SITE_URL}/${locale}/products/${slug.join('/')}`,
|
canonical: `${SITE_URL}/${locale}/${await mapFileSlugToTranslated('products', locale)}/${slug.join('/')}`,
|
||||||
languages: {
|
languages: {
|
||||||
de: `${SITE_URL}/de/products/${await mapFileSlugToTranslated(slug[0], 'de')}/${await mapFileSlugToTranslated(productSlug, 'de')}`,
|
de: `${SITE_URL}/de/${await mapFileSlugToTranslated('products', 'de')}/${await mapFileSlugToTranslated(slug[0], 'de')}/${await mapFileSlugToTranslated(productSlug, 'de')}`,
|
||||||
en: `${SITE_URL}/en/products/${await mapFileSlugToTranslated(slug[0], 'en')}/${await mapFileSlugToTranslated(productSlug, 'en')}`,
|
en: `${SITE_URL}/en/${await mapFileSlugToTranslated('products', 'en')}/${await mapFileSlugToTranslated(slug[0], 'en')}/${await mapFileSlugToTranslated(productSlug, 'en')}`,
|
||||||
'x-default': `${SITE_URL}/en/products/${await mapFileSlugToTranslated(slug[0], 'en')}/${await mapFileSlugToTranslated(productSlug, 'en')}`,
|
'x-default': `${SITE_URL}/en/${await mapFileSlugToTranslated('products', 'en')}/${await mapFileSlugToTranslated(slug[0], 'en')}/${await mapFileSlugToTranslated(productSlug, 'en')}`,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
openGraph: {
|
openGraph: {
|
||||||
title: `${product.frontmatter.title} | KLZ Cables`,
|
title: `${product.frontmatter.title} | KLZ Cables`,
|
||||||
description: product.frontmatter.description,
|
description: product.frontmatter.description,
|
||||||
type: 'website',
|
type: 'website',
|
||||||
url: `${SITE_URL}/${locale}/products/${slug.join('/')}`,
|
url: `${SITE_URL}/${locale}/${await mapFileSlugToTranslated('products', locale)}/${slug.join('/')}`,
|
||||||
images: getProductOGImageMetadata(productSlug, product.frontmatter.title, locale),
|
images: getProductOGImageMetadata(productSlug, product.frontmatter.title, locale),
|
||||||
},
|
},
|
||||||
twitter: {
|
twitter: {
|
||||||
@@ -236,7 +236,7 @@ export default async function ProductPage({ params }: ProductPageProps) {
|
|||||||
{productsWithTranslatedSlugs.map((product) => (
|
{productsWithTranslatedSlugs.map((product) => (
|
||||||
<Link
|
<Link
|
||||||
key={product.slug}
|
key={product.slug}
|
||||||
href={`/${locale}/products/${productSlug}/${product.translatedSlug}`}
|
href={`/${locale}/${productSlug}/${product.translatedSlug}`}
|
||||||
className="group block bg-white rounded-[32px] overflow-hidden shadow-sm hover:shadow-2xl transition-all duration-500 border border-neutral-dark/5"
|
className="group block bg-white rounded-[32px] overflow-hidden shadow-sm hover:shadow-2xl transition-all duration-500 border border-neutral-dark/5"
|
||||||
>
|
>
|
||||||
<Card tag="article" className="premium-card-reset">
|
<Card tag="article" className="premium-card-reset">
|
||||||
@@ -381,7 +381,7 @@ export default async function ProductPage({ params }: ProductPageProps) {
|
|||||||
</Link>
|
</Link>
|
||||||
<span className="mx-4 opacity-20">/</span>
|
<span className="mx-4 opacity-20">/</span>
|
||||||
<Link
|
<Link
|
||||||
href={`/${locale}/products/${categorySlug}`}
|
href={`/${locale}/${productSlug}`}
|
||||||
className="hover:text-accent transition-colors"
|
className="hover:text-accent transition-colors"
|
||||||
>
|
>
|
||||||
{categoryTitle}
|
{categoryTitle}
|
||||||
@@ -504,7 +504,7 @@ export default async function ProductPage({ params }: ProductPageProps) {
|
|||||||
'@type': 'Offer',
|
'@type': 'Offer',
|
||||||
availability: 'https://schema.org/InStock',
|
availability: 'https://schema.org/InStock',
|
||||||
priceCurrency: 'EUR',
|
priceCurrency: 'EUR',
|
||||||
url: `${SITE_URL}/${locale}/products/${slug.join('/')}`,
|
url: `${SITE_URL}/${locale}/${await mapFileSlugToTranslated('products', locale)}/${slug.join('/')}`,
|
||||||
itemCondition: 'https://schema.org/NewCondition',
|
itemCondition: 'https://schema.org/NewCondition',
|
||||||
},
|
},
|
||||||
additionalProperty: technicalItems.map((item: any) => ({
|
additionalProperty: technicalItems.map((item: any) => ({
|
||||||
@@ -515,7 +515,7 @@ export default async function ProductPage({ params }: ProductPageProps) {
|
|||||||
category: product.frontmatter.categories.join(', '),
|
category: product.frontmatter.categories.join(', '),
|
||||||
mainEntityOfPage: {
|
mainEntityOfPage: {
|
||||||
'@type': 'WebPage',
|
'@type': 'WebPage',
|
||||||
'@id': `${SITE_URL}/${locale}/products/${slug.join('/')}`,
|
'@id': `${SITE_URL}/${locale}/${await mapFileSlugToTranslated('products', locale)}/${slug.join('/')}`,
|
||||||
},
|
},
|
||||||
} as any
|
} as any
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import { getAllProducts } from '@/lib/mdx';
|
|||||||
import { getTranslations } from 'next-intl/server';
|
import { getTranslations } from 'next-intl/server';
|
||||||
import Image from 'next/image';
|
import Image from 'next/image';
|
||||||
import { RelatedProductLink } from './RelatedProductLink';
|
import { RelatedProductLink } from './RelatedProductLink';
|
||||||
|
import { mapFileSlugToTranslated } from '@/lib/slugs';
|
||||||
|
|
||||||
interface RelatedProductsProps {
|
interface RelatedProductsProps {
|
||||||
currentSlug: string;
|
currentSlug: string;
|
||||||
@@ -16,6 +17,7 @@ export default async function RelatedProducts({
|
|||||||
}: RelatedProductsProps) {
|
}: RelatedProductsProps) {
|
||||||
const products = await getAllProducts(locale);
|
const products = await getAllProducts(locale);
|
||||||
const t = await getTranslations('Products');
|
const t = await getTranslations('Products');
|
||||||
|
const productsSlug = await mapFileSlugToTranslated('products', locale);
|
||||||
|
|
||||||
// Filter products: same category, not current product
|
// Filter products: same category, not current product
|
||||||
const related = products
|
const related = products
|
||||||
@@ -61,7 +63,7 @@ export default async function RelatedProducts({
|
|||||||
return (
|
return (
|
||||||
<RelatedProductLink
|
<RelatedProductLink
|
||||||
key={product.slug}
|
key={product.slug}
|
||||||
href={`/${locale}/products/${catSlug}/${product.slug}`}
|
href={`/${locale}/${productsSlug}/${catSlug}/${product.slug}`}
|
||||||
productSlug={product.slug}
|
productSlug={product.slug}
|
||||||
productTitle={product.frontmatter.title}
|
productTitle={product.frontmatter.title}
|
||||||
className="group block bg-white rounded-[32px] overflow-hidden shadow-sm hover:shadow-2xl transition-all duration-500 border border-neutral-dark/5"
|
className="group block bg-white rounded-[32px] overflow-hidden shadow-sm hover:shadow-2xl transition-all duration-500 border border-neutral-dark/5"
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ function createConfig() {
|
|||||||
umami: {
|
umami: {
|
||||||
websiteId: env.UMAMI_WEBSITE_ID,
|
websiteId: env.UMAMI_WEBSITE_ID,
|
||||||
apiEndpoint: env.UMAMI_API_ENDPOINT || 'https://analytics.infra.mintel.me',
|
apiEndpoint: env.UMAMI_API_ENDPOINT || 'https://analytics.infra.mintel.me',
|
||||||
enabled: Boolean(env.UMAMI_WEBSITE_ID),
|
enabled: typeof window !== 'undefined' || Boolean(env.UMAMI_WEBSITE_ID),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -344,6 +344,14 @@ const nextConfig = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return [
|
return [
|
||||||
|
{
|
||||||
|
source: '/de/produkte',
|
||||||
|
destination: '/de/products',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
source: '/de/produkte/:path*',
|
||||||
|
destination: '/de/products/:path*',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
source: '/cms/:path*',
|
source: '/cms/:path*',
|
||||||
destination: `${directusUrl}/:path*`,
|
destination: `${directusUrl}/:path*`,
|
||||||
|
|||||||
Reference in New Issue
Block a user