Files
PVHFrontend/scripts/prerender.js
T

224 lines
7.5 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { readFileSync, writeFileSync, mkdirSync, existsSync } from "fs";
import { resolve, dirname } from "path";
import { fileURLToPath } from "url";
const __dirname = dirname(fileURLToPath(import.meta.url));
async function getProducts() {
try {
const response = await fetch('https://pvh.projects.rustprogersteam.ru/api/productList');
const data = await response.json();
if (Array.isArray(data)) {
console.log(`✅ Загружено ${data.length} товаров`);
return data;
}
return [];
} catch (error) {
console.error('Ошибка:', error.message);
return [];
}
}
// Получаем товары
const products = await getProducts();
const distPath = resolve(__dirname, "../dist");
const indexHtmlPath = resolve(distPath, "index.html");
if (!existsSync(indexHtmlPath)) {
console.error("❌ Сначала запустите npm run build");
process.exit(1);
}
// Читаем исходный HTML
let baseHtml = readFileSync(indexHtmlPath, "utf-8");
// ============================================
// ФУНКЦИИ ДЛЯ ГЕНЕРАЦИИ КОНТЕНТА
// ============================================
function escapeHtml(text) {
if (!text) return '';
return String(text)
.replace(/&/g, '&')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/"/g, '&quot;')
.replace(/'/g, '&#39;');
}
// Генерация страницы товара
function generateProductPage(product) {
return `
<div class="product-page">
<h1>${escapeHtml(product.full_name)}</h1>
<div class="product-description">
<p>${escapeHtml(product.description || 'Описание отсутствует')}</p>
</div>
<div class="product-details">
<p><strong>Артикул:</strong> ${product.id}</p>
</div>
</div>`;
}
// Генерация главной страницы
function generateHomePage(products) {
const topProducts = products.slice(0, 6).map(product => `
<div class="product-card">
<h3>${escapeHtml(product.full_name || `Товар ${product.id}`)}</h3>
<a href="/product/${product.slug || product.id}">Подробнее</a>
</div>`).join('');
return `
<div class="home-page">
<h1>Добро пожаловать в магазин труб RK PLASTIC technology!</h1>
<p>Широкий выбор канализационных труб, фитингов, колен, отводов, муфт, переходов, заглушек, тройников и ревизий.</p>
<h2>Популярные товары</h2>
<div class="products-grid">
${topProducts}
</div>
<a href="/products" class="catalog-link">Перейти в каталог</a>
</div>`;
}
// Генерация страницы каталога
function generateCatalogPage(products) {
const allProducts = products.map(product => `
<div class="product-card">
<h2>${escapeHtml(product.full_name || `Товар ${product.id}`)}</h2>
<p>${escapeHtml((product.description || '').slice(0, 150))}...</p>
<a href="/product/${product.slug || product.id}">Подробнее</a>
</div>`).join('');
return `
<div class="catalog-page">
<h1>Каталог товаров</h1>
<div class="product-list">
${allProducts}
</div>
</div>`;
}
// Генерация страницы "О нас"
function generateAboutPage() {
return `
<div class="about-page">
<h1>О магазине</h1>
<p>Мы занимаемся продажей качественных труб и остальных комплектующих для канализации.</p>
<h2>Наши преимущества:</h2>
<ul>
<li>Низкие цены</li>
<li>Быстрая доставка</li>
<li>Гарантия качества</li>
</ul>
</div>`;
}
const routes = [
{
path: "/",
title: "Магазин труб - Главная",
description: "Купить канализационные трубы, фитинги и комплектующие по низким ценам.",
getContent: () => generateHomePage(products)
},
{
path: "/products",
title: "Каталог труб и фитингов для канализации",
description: "Широкий выбор канализационных труб ПВХ, фитингов, тройников, переходов, колен.",
getContent: () => generateCatalogPage(products)
},
{
path: "/about",
title: "О магазине труб - Доставка и гарантия",
description: "Информация о нашей компании. Как мы работаем, условия доставки.",
getContent: () => generateAboutPage()
}
];
// Добавляем страницы товаров
for (const product of products) {
routes.push({
path: `/product/${product.slug || product.id}`,
title: product.full_name,
description: (product.description || ''),
getContent: () => generateProductPage(product)
});
}
console.log(`\n📄 Всего страниц для генерации: ${routes.length}\n`);
let successCount = 0;
for (const route of routes) {
try {
// Генерируем контент для этой страницы
const pageContent = route.getContent();
// Вставляем контент в #root
let html = baseHtml;
// Меняем title
html = html.replace(/<title>.*?<\/title>/, `<title>${escapeHtml(route.title)}</title>`);
// Меняем meta description
html = html.replace(/<meta name="description".*?>/, `<meta name="description" content="${escapeHtml(route.description)}">`);
// Вставляем контент в #root (ВАЖНО!)
html = html.replace('<div id="root"></div>', `<div id="root">${pageContent}</div>`);
// Добавляем Open Graph теги
html = html.replace(
"</head>",
` <meta property="og:title" content="${escapeHtml(route.title)}">
<meta property="og:description" content="${escapeHtml(route.description)}">
<meta property="og:type" content="website">
<meta name="robots" content="index, follow">
</head>`
);
// Определяем путь для сохранения
let outputPath;
if (route.path === "/") {
outputPath = indexHtmlPath;
} else {
const routeDir = resolve(distPath, route.path.substring(1));
if (!existsSync(routeDir)) {
mkdirSync(routeDir, { recursive: true });
}
outputPath = resolve(routeDir, "index.html");
}
writeFileSync(outputPath, html);
console.log(`✅ ${route.path}`);
successCount++;
} catch (error) {
console.error(`❌ Ошибка при генерации ${route.path}:`, error.message);
}
}
const urls = routes.map(route => ({
url: route.path,
lastmod: new Date().toISOString().split('T')[0],
priority: route.path === '/' ? 1.0 : route.path.startsWith('/product') ? 0.8 : 0.7
}));
function generateSitemap(urls, baseUrl) {
return `<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
${urls.map(item => ` <url>
<loc>${baseUrl}${item.url}</loc>
<lastmod>${item.lastmod}</lastmod>
<priority>${item.priority}</priority>
</url>`).join('\n')}
</urlset>`;
}
const sitemapContent = generateSitemap(urls, 'https://pvh.projects.rustprogersteam.ru');
const sitemapPath = resolve(distPath, 'sitemap.xml');
writeFileSync(sitemapPath, sitemapContent);
console.log(`\n✨ Готово! Сгенерировано ${successCount} страниц.`);
console.log(`🗺️ Sitemap: ${sitemapPath}`);