feat: add Hersteller page with manufacturer data fetching and SEO support

This commit is contained in:
sebseb7
2026-04-21 16:04:11 +02:00
parent 2c0b7aa84d
commit 66a1efd87b
10 changed files with 690 additions and 35 deletions

View File

@@ -131,6 +131,8 @@ const {
generateHomepageJsonLd,
generateSitemapJsonLd,
generateKonfiguratorMetaTags,
generateHerstellerMetaTags,
generateHerstellerJsonLd,
generateXmlSitemap,
generateRobotsTxt,
generateProductsXml,
@@ -142,6 +144,7 @@ const {
const {
fetchCategoryProducts,
fetchProductDetails,
fetchManufacturers,
saveProductImages,
saveCategoryImages,
} = require("./prerender/data-fetching.cjs");
@@ -161,6 +164,7 @@ const Widerrufsrecht = require("./src/pages/Widerrufsrecht.js").default;
const Sitemap = require("./src/pages/Sitemap.js").default;
const PrerenderSitemap = require("./src/PrerenderSitemap.js").default;
const PrerenderCategoriesPage = require("./src/PrerenderCategoriesPage.js").default;
const PrerenderHerstellerPage = require("./src/PrerenderHerstellerPage.js").default;
const AGB = require("./src/pages/AGB.js").default;
const NotFound404 = require("./src/pages/NotFound404.js").default;
@@ -376,6 +380,29 @@ const renderApp = async (categoryData, socket) => {
global.categoryCache = {};
}
// Fetch manufacturers data for Hersteller page
let manufacturerData = null;
console.log("🏭 [renderApp] Starting manufacturer fetch...");
console.log("🏭 [renderApp] socket exists:", !!socket);
console.log("🏭 [renderApp] socket.connected:", socket ? socket.connected : "N/A");
if (!socket) {
console.error("🏭 [renderApp] FATAL: No socket - cannot fetch manufacturers!");
} else if (!socket.connected) {
console.error("🏭 [renderApp] FATAL: Socket not connected - cannot fetch manufacturers!");
} else {
try {
console.log("🏭 [renderApp] Calling fetchManufacturers...");
manufacturerData = await fetchManufacturers(socket);
console.log("🏭 [renderApp] ✅ Fetched " + manufacturerData.length + " manufacturers");
} catch (error) {
console.error("🏭 [renderApp] ❌ Failed to fetch manufacturers:", error.message);
manufacturerData = [];
}
}
console.log("🏭 [renderApp] Final manufacturerData:", manufacturerData ? (manufacturerData.length + " items") : "null");
// Helper to call renderPage with config
const render = (
component,
@@ -383,8 +410,10 @@ const renderApp = async (categoryData, socket) => {
filename,
description,
metaTags = "",
needsRouter = false
needsRouter = false,
manufacturerDataForPage = null
) => {
console.log(" 📦 [render helper] Calling renderPage for", filename, "with manufacturerData:", manufacturerDataForPage ? (manufacturerDataForPage.length + " items") : "null");
return renderPage(
component,
location,
@@ -392,7 +421,10 @@ const renderApp = async (categoryData, socket) => {
description,
metaTags,
needsRouter,
config
config,
false, // suppressLogs
null, // productData
manufacturerDataForPage // manufacturerData - 10th parameter!
);
};
@@ -474,6 +506,13 @@ const renderApp = async (categoryData, socket) => {
description: "Categories page",
needsCategoryData: true,
},
{
component: PrerenderHerstellerPage,
path: "/Hersteller",
filename: "Hersteller",
description: "Hersteller page",
needsManufacturerData: true,
},
{ component: AGB, path: "/agb", filename: "agb", description: "AGB page" },
{ component: NotFound404, path: "/404", filename: "404", description: "404 Not Found page" },
{
@@ -492,8 +531,17 @@ const renderApp = async (categoryData, socket) => {
let staticPagesRendered = 0;
for (const page of staticPages) {
// Pass category data as props if needed
const pageProps = page.needsCategoryData ? { categoryData } : null;
// Pass category and manufacturer data as props if needed
let pageProps = null;
if (page.needsCategoryData || page.needsManufacturerData) {
pageProps = {};
if (page.needsCategoryData) {
pageProps.categoryData = categoryData;
}
if (page.needsManufacturerData) {
pageProps.manufacturerData = manufacturerData;
}
}
const pageComponent = React.createElement(page.component, pageProps);
let metaTags = "";
@@ -509,13 +557,25 @@ const renderApp = async (categoryData, socket) => {
metaTags = konfiguratorMetaTags;
}
// Special handling for Hersteller page to include SEO tags
if (page.filename === "Hersteller") {
const manufacturerCount = manufacturerData ? manufacturerData.length : 0;
const herstellerMetaTags = generateHerstellerMetaTags(shopConfig.baseUrl, shopConfig, manufacturerCount);
const herstellerJsonLd = generateHerstellerJsonLd(shopConfig.baseUrl, shopConfig);
metaTags = herstellerMetaTags + "\n" + herstellerJsonLd;
}
// Pass manufacturerData only for Hersteller page
const pageManufacturerData = page.needsManufacturerData ? manufacturerData : null;
const success = render(
pageComponent,
page.path,
page.filename,
page.description,
metaTags,
true
true,
pageManufacturerData
);
if (success) {
staticPagesRendered++;