Enhance SEO text generation for product categories by implementing pagination support. Updated generateCategoryLlmsTxt to include page navigation and product count details, improving clarity for users accessing product catalogs. Added helper function generateAllCategoryLlmsPages to facilitate the creation of multiple category pages.

This commit is contained in:
seb
2025-07-05 15:41:36 +02:00
parent f81b9d12df
commit eb0d5621e6

View File

@@ -959,9 +959,42 @@ GrowHeads.de is a German online shop and local store in Dresden specializing in
if (category.seoName) { if (category.seoName) {
const productCount = productsByCategory[category.id]?.length || 0; const productCount = productsByCategory[category.id]?.length || 0;
const categorySlug = category.seoName.toLowerCase().replace(/[^a-z0-9]/g, '-'); const categorySlug = category.seoName.toLowerCase().replace(/[^a-z0-9]/g, '-');
const productsPerPage = 50;
const totalPages = Math.ceil(productCount / productsPerPage);
llmsTxt += `#### ${category.name} (${productCount} products) llmsTxt += `#### ${category.name} (${productCount} products)`;
- **Product Catalog**: ${baseUrl}/llms-${categorySlug}.txt
if (totalPages > 1) {
llmsTxt += `
- **Product Catalog**: ${totalPages} pages available
- **Page 1**: ${baseUrl}/llms-${categorySlug}-page-1.txt (Products 1-${Math.min(productsPerPage, productCount)})`;
if (totalPages > 2) {
llmsTxt += `
- **Page 2**: ${baseUrl}/llms-${categorySlug}-page-2.txt (Products ${productsPerPage + 1}-${Math.min(productsPerPage * 2, productCount)})`;
}
if (totalPages > 3) {
llmsTxt += `
- **...**: Additional pages available`;
}
if (totalPages > 2) {
llmsTxt += `
- **Page ${totalPages}**: ${baseUrl}/llms-${categorySlug}-page-${totalPages}.txt (Products ${((totalPages - 1) * productsPerPage) + 1}-${productCount})`;
}
llmsTxt += `
- **Access Pattern**: Replace "page-X" with desired page number (1-${totalPages})`;
} else if (productCount > 0) {
llmsTxt += `
- **Product Catalog**: ${baseUrl}/llms-${categorySlug}-page-1.txt`;
} else {
llmsTxt += `
- **Product Catalog**: No products available`;
}
llmsTxt += `
`; `;
} }
@@ -976,10 +1009,18 @@ GrowHeads.de is a German online shop and local store in Dresden specializing in
return llmsTxt; return llmsTxt;
}; };
const generateCategoryLlmsTxt = (category, categoryProducts = [], baseUrl, config) => { const generateCategoryLlmsTxt = (category, categoryProducts = [], baseUrl, config, pageNumber = 1, productsPerPage = 50) => {
const currentDate = new Date().toISOString().split("T")[0]; // YYYY-MM-DD format const currentDate = new Date().toISOString().split("T")[0]; // YYYY-MM-DD format
const categorySlug = category.seoName.toLowerCase().replace(/[^a-z0-9]/g, '-');
let categoryLlmsTxt = `# ${category.name} - Product Catalog // Calculate pagination
const totalProducts = categoryProducts.length;
const totalPages = Math.ceil(totalProducts / productsPerPage);
const startIndex = (pageNumber - 1) * productsPerPage;
const endIndex = Math.min(startIndex + productsPerPage, totalProducts);
const pageProducts = categoryProducts.slice(startIndex, endIndex);
let categoryLlmsTxt = `# ${category.name} - Product Catalog (Page ${pageNumber} of ${totalPages})
Generated: ${currentDate} Generated: ${currentDate}
Base URL: ${baseUrl} Base URL: ${baseUrl}
@@ -987,18 +1028,53 @@ Category: ${category.name} (ID: ${category.id})
Category URL: ${baseUrl}/Kategorie/${category.seoName} Category URL: ${baseUrl}/Kategorie/${category.seoName}
## Category Overview ## Category Overview
This file contains all products in the "${category.name}" category from ${config.siteName}. This file contains products ${startIndex + 1}-${endIndex} of ${totalProducts} in the "${category.name}" category from ${config.siteName}.
**Statistics:** **Statistics:**
- **Total Products**: ${categoryProducts.length} - **Total Products in Category**: ${totalProducts}
- **Products on This Page**: ${pageProducts.length}
- **Current Page**: ${pageNumber} of ${totalPages}
- **Category ID**: ${category.id} - **Category ID**: ${category.id}
- **Category URL**: ${baseUrl}/Kategorie/${category.seoName} - **Category URL**: ${baseUrl}/Kategorie/${category.seoName}
- **Back to Main Sitemap**: ${baseUrl}/llms.txt - **Back to Main Sitemap**: ${baseUrl}/llms.txt
`; `;
if (categoryProducts.length > 0) { // Add navigation hints for LLMs
categoryProducts.forEach((product, index) => { if (totalPages > 1) {
categoryLlmsTxt += `## Navigation for LLMs
**How to access other pages in this category:**
`;
if (pageNumber > 1) {
categoryLlmsTxt += `- **Previous Page**: ${baseUrl}/llms-${categorySlug}-page-${pageNumber - 1}.txt
`;
}
if (pageNumber < totalPages) {
categoryLlmsTxt += `- **Next Page**: ${baseUrl}/llms-${categorySlug}-page-${pageNumber + 1}.txt
`;
}
categoryLlmsTxt += `- **First Page**: ${baseUrl}/llms-${categorySlug}-page-1.txt
- **Last Page**: ${baseUrl}/llms-${categorySlug}-page-${totalPages}.txt
**All pages in this category:**
`;
for (let i = 1; i <= totalPages; i++) {
categoryLlmsTxt += `- **Page ${i}**: ${baseUrl}/llms-${categorySlug}-page-${i}.txt (Products ${((i-1) * productsPerPage) + 1}-${Math.min(i * productsPerPage, totalProducts)})
`;
}
categoryLlmsTxt += `
`;
}
if (pageProducts.length > 0) {
pageProducts.forEach((product, index) => {
if (product.seoName) { if (product.seoName) {
// Clean description for markdown (remove HTML tags and limit length) // Clean description for markdown (remove HTML tags and limit length)
const cleanDescription = product.description const cleanDescription = product.description
@@ -1009,7 +1085,8 @@ This file contains all products in the "${category.name}" category from ${config
.substring(0, 300) .substring(0, 300)
: ""; : "";
categoryLlmsTxt += `## ${index + 1}. ${product.name} const globalIndex = startIndex + index + 1;
categoryLlmsTxt += `## ${globalIndex}. ${product.name}
- **Product URL**: ${baseUrl}/Artikel/${product.seoName} - **Product URL**: ${baseUrl}/Artikel/${product.seoName}
- **Article Number**: ${product.articleNumber || 'N/A'} - **Article Number**: ${product.articleNumber || 'N/A'}
@@ -1046,6 +1123,26 @@ ${cleanDescription}${product.description && product.description.length > 300 ? '
This category currently contains no products. This category currently contains no products.
`;
}
// Add footer navigation for convenience
if (totalPages > 1) {
categoryLlmsTxt += `## Page Navigation
`;
if (pageNumber > 1) {
categoryLlmsTxt += `← [Previous Page](${baseUrl}/llms-${categorySlug}-page-${pageNumber - 1}.txt) | `;
}
categoryLlmsTxt += `[Category Overview](${baseUrl}/llms-${categorySlug}-page-1.txt)`;
if (pageNumber < totalPages) {
categoryLlmsTxt += ` | [Next Page](${baseUrl}/llms-${categorySlug}-page-${pageNumber + 1}.txt) →`;
}
categoryLlmsTxt += `
`; `;
} }
@@ -1057,6 +1154,28 @@ This category currently contains no products.
return categoryLlmsTxt; return categoryLlmsTxt;
}; };
// Helper function to generate all pages for a category
const generateAllCategoryLlmsPages = (category, categoryProducts = [], baseUrl, config, productsPerPage = 50) => {
const totalProducts = categoryProducts.length;
const totalPages = Math.ceil(totalProducts / productsPerPage);
const pages = [];
for (let pageNumber = 1; pageNumber <= totalPages; pageNumber++) {
const pageContent = generateCategoryLlmsTxt(category, categoryProducts, baseUrl, config, pageNumber, productsPerPage);
const categorySlug = category.seoName.toLowerCase().replace(/[^a-z0-9]/g, '-');
const fileName = `llms-${categorySlug}-page-${pageNumber}.txt`;
pages.push({
fileName,
content: pageContent,
pageNumber,
totalPages
});
}
return pages;
};
module.exports = { module.exports = {
generateProductMetaTags, generateProductMetaTags,
generateProductJsonLd, generateProductJsonLd,
@@ -1070,4 +1189,5 @@ module.exports = {
generateProductsXml, generateProductsXml,
generateLlmsTxt, generateLlmsTxt,
generateCategoryLlmsTxt, generateCategoryLlmsTxt,
generateAllCategoryLlmsPages,
}; };