feat: Add generateCategoryMetaTags function for enhanced SEO in category pages and integrate it into prerender process
This commit is contained in:
@@ -1,3 +1,43 @@
|
||||
/** Safe for double-quoted HTML attributes */
|
||||
const escAttr = (str) =>
|
||||
String(str ?? "")
|
||||
.replace(/&/g, "&")
|
||||
.replace(/"/g, """)
|
||||
.replace(/</g, "<");
|
||||
|
||||
/**
|
||||
* Head tags for prerendered category URLs — explicit canonical per /Kategorie/{slug}
|
||||
* so Google does not cluster different listing pages (e.g. neu vs Seeds) as duplicates.
|
||||
*/
|
||||
const generateCategoryMetaTags = (category, baseUrl, config) => {
|
||||
const root = baseUrl.endsWith("/") ? baseUrl.slice(0, -1) : baseUrl;
|
||||
const categoryUrl = `${root}/Kategorie/${category.seoName}`;
|
||||
const name = category.name || `Kategorie ${category.seoName}`;
|
||||
const site = config.siteName || config.brandName;
|
||||
const desc = `${name} bei ${config.brandName}: Growshop-Sortiment online kaufen. Schnelle Lieferung, Laden Dresden.`;
|
||||
const descShort = desc.length > 160 ? `${desc.slice(0, 157)}...` : desc;
|
||||
const e = escAttr;
|
||||
const logoUrl =
|
||||
config.images && config.images.logo
|
||||
? `${root}${config.images.logo}`
|
||||
: `${root}/assets/images/nopicture.jpg`;
|
||||
|
||||
return `
|
||||
<meta name="description" content="${e(descShort)}">
|
||||
<meta property="og:title" content="${e(`${name} | ${site}`)}">
|
||||
<meta property="og:description" content="${e(descShort)}">
|
||||
<meta property="og:url" content="${categoryUrl}">
|
||||
<meta property="og:type" content="website">
|
||||
<meta property="og:image" content="${e(logoUrl)}">
|
||||
<meta property="og:site_name" content="${e(site)}">
|
||||
<meta name="twitter:card" content="summary_large_image">
|
||||
<meta name="twitter:title" content="${e(`${name} | ${site}`)}">
|
||||
<meta name="twitter:description" content="${e(descShort)}">
|
||||
<meta name="robots" content="index, follow">
|
||||
<link rel="canonical" href="${categoryUrl}">
|
||||
`;
|
||||
};
|
||||
|
||||
const generateCategoryJsonLd = (category, products = [], baseUrl, config) => {
|
||||
// Category IDs to skip (seeds, plants, headshop items)
|
||||
const skipCategoryIds = [689, 706, 709, 711, 714, 748, 749, 896, 710, 924, 923, 922, 921, 916, 278, 259, 258];
|
||||
@@ -173,5 +213,6 @@ const generateCategoryJsonLd = (category, products = [], baseUrl, config) => {
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
generateCategoryMetaTags,
|
||||
generateCategoryJsonLd,
|
||||
};
|
||||
};
|
||||
Reference in New Issue
Block a user