fix(mdx): support recursive product file searching for OG images and routing
Some checks failed
Build & Deploy / 🔍 Prepare (push) Successful in 7s
Build & Deploy / 🧪 QA (push) Failing after 45s
Build & Deploy / 🏗️ Build (push) Has been skipped
Build & Deploy / 🚀 Deploy (push) Has been skipped
Build & Deploy / 🧪 Smoke Test (push) Has been skipped
Build & Deploy / ⚡ Lighthouse (push) Has been skipped
Build & Deploy / ♿ WCAG (push) Has been skipped
Build & Deploy / 📸 Visual Diff (push) Has been skipped
Build & Deploy / 🛡️ Quality Gates (push) Has been skipped
Build & Deploy / 🔔 Notify (push) Successful in 31s

This commit is contained in:
2026-02-22 11:22:35 +01:00
parent 1a39e9c0e4
commit a55680ed41

View File

@@ -26,42 +26,43 @@ export async function getProductMetadata(
const fileSlug = await mapSlugToFileSlug(slug, locale); const fileSlug = await mapSlugToFileSlug(slug, locale);
const productsDir = path.join(process.cwd(), 'data', 'products', locale); const productsDir = path.join(process.cwd(), 'data', 'products', locale);
// Try exact slug first if (!fs.existsSync(productsDir)) return null;
let filePath = path.join(productsDir, `${fileSlug}.mdx`);
if (!fs.existsSync(filePath)) { // Recursive search for the file
// Try with -2 suffix (common in the dumped files) const findFile = (dir: string): string | null => {
filePath = path.join(productsDir, `${fileSlug}-2.mdx`); const files = fs.readdirSync(dir);
for (const file of files) {
const fullPath = path.join(dir, file);
const stat = fs.statSync(fullPath);
if (stat.isDirectory()) {
const found = findFile(fullPath);
if (found) return found;
} else if (file === `${fileSlug}.mdx` || file === `${fileSlug}-2.mdx`) {
return fullPath;
} }
}
return null;
};
if (!fs.existsSync(filePath)) { let filePath = findFile(productsDir);
// Fallback to English if locale is not 'en'
if (locale !== 'en') { if (!filePath && locale !== 'en') {
// Fallback to English
const enProductsDir = path.join(process.cwd(), 'data', 'products', 'en'); const enProductsDir = path.join(process.cwd(), 'data', 'products', 'en');
let enFilePath = path.join(enProductsDir, `${fileSlug}.mdx`); if (fs.existsSync(enProductsDir)) {
if (!fs.existsSync(enFilePath)) { filePath = findFile(enProductsDir);
enFilePath = path.join(enProductsDir, `${fileSlug}-2.mdx`); }
} }
if (fs.existsSync(enFilePath)) { if (filePath && fs.existsSync(filePath)) {
const fileContent = fs.readFileSync(enFilePath, 'utf8'); const fileContent = fs.readFileSync(filePath, 'utf8');
const { data } = matter(fileContent); const { data } = matter(fileContent);
return { return {
slug: fileSlug, slug: fileSlug,
frontmatter: { frontmatter: {
...data, ...data,
isFallback: true, isFallback: filePath.includes('/en/'),
} as ProductFrontmatter & { isFallback?: boolean }, } as any,
};
}
}
} else {
const fileContent = fs.readFileSync(filePath, 'utf8');
const { data } = matter(fileContent);
return {
slug: fileSlug,
frontmatter: data as ProductFrontmatter,
}; };
} }
@@ -73,55 +74,53 @@ export async function getProductBySlug(slug: string, locale: string): Promise<Pr
const fileSlug = await mapSlugToFileSlug(slug, locale); const fileSlug = await mapSlugToFileSlug(slug, locale);
const productsDir = path.join(process.cwd(), 'data', 'products', locale); const productsDir = path.join(process.cwd(), 'data', 'products', locale);
// Try exact slug first if (!fs.existsSync(productsDir)) return null;
let filePath = path.join(productsDir, `${fileSlug}.mdx`);
if (!fs.existsSync(filePath)) { // Recursive search for the file
// Try with -2 suffix (common in the dumped files) const findFile = (dir: string): string | null => {
filePath = path.join(productsDir, `${fileSlug}-2.mdx`); const files = fs.readdirSync(dir);
for (const file of files) {
const fullPath = path.join(dir, file);
const stat = fs.statSync(fullPath);
if (stat.isDirectory()) {
const found = findFile(fullPath);
if (found) return found;
} else if (file === `${fileSlug}.mdx` || file === `${fileSlug}-2.mdx`) {
return fullPath;
} }
}
return null;
};
let product: ProductMdx | null = null; let filePath = findFile(productsDir);
let isFallback = false;
if (!fs.existsSync(filePath)) { if (!filePath && locale !== 'en') {
// Fallback to English if locale is not 'en' // Fallback to English
if (locale !== 'en') {
const enProductsDir = path.join(process.cwd(), 'data', 'products', 'en'); const enProductsDir = path.join(process.cwd(), 'data', 'products', 'en');
let enFilePath = path.join(enProductsDir, `${fileSlug}.mdx`); if (fs.existsSync(enProductsDir)) {
if (!fs.existsSync(enFilePath)) { filePath = findFile(enProductsDir);
enFilePath = path.join(enProductsDir, `${fileSlug}-2.mdx`); if (filePath) isFallback = true;
}
} }
if (fs.existsSync(enFilePath)) { if (filePath && fs.existsSync(filePath)) {
const fileContent = fs.readFileSync(enFilePath, 'utf8'); const fileContent = fs.readFileSync(filePath, 'utf8');
const { data, content } = matter(fileContent); const { data, content } = matter(fileContent);
product = { const product = {
slug: fileSlug, slug: fileSlug,
frontmatter: { frontmatter: {
...data, ...data,
isFallback: true, isFallback,
} as ProductFrontmatter & { isFallback?: boolean }, } as any,
content, content,
}; };
}
}
} else {
const fileContent = fs.readFileSync(filePath, 'utf8');
const { data, content } = matter(fileContent);
product = {
slug: fileSlug,
frontmatter: data as ProductFrontmatter,
content,
};
}
// Filter out products without images // Filter out products without images
if ( if (
product && !product.frontmatter.images ||
(!product.frontmatter.images ||
product.frontmatter.images.length === 0 || product.frontmatter.images.length === 0 ||
!product.frontmatter.images[0]) !product.frontmatter.images[0]
) { ) {
return null; return null;
} }
@@ -129,12 +128,29 @@ export async function getProductBySlug(slug: string, locale: string): Promise<Pr
return product; return product;
} }
return null;
}
export async function getAllProductSlugs(locale: string): Promise<string[]> { export async function getAllProductSlugs(locale: string): Promise<string[]> {
const productsDir = path.join(process.cwd(), 'data', 'products', locale); const productsDir = path.join(process.cwd(), 'data', 'products', locale);
if (!fs.existsSync(productsDir)) return []; if (!fs.existsSync(productsDir)) return [];
const files = fs.readdirSync(productsDir); const slugs: string[] = [];
return files.filter((file) => file.endsWith('.mdx')).map((file) => file.replace(/\.mdx$/, '')); const walk = (dir: string) => {
const files = fs.readdirSync(dir);
for (const file of files) {
const fullPath = path.join(dir, file);
const stat = fs.statSync(fullPath);
if (stat.isDirectory()) {
walk(fullPath);
} else if (file.endsWith('.mdx')) {
slugs.push(file.replace(/\.mdx$/, ''));
}
}
};
walk(productsDir);
return slugs;
} }
export async function getAllProducts(locale: string): Promise<ProductMdx[]> { export async function getAllProducts(locale: string): Promise<ProductMdx[]> {