Обновлены страницы с мета-тегами: заменены статические мета-теги на компонент MetaTags, который динамически получает данные через getMetaByPath. Изменен язык документа на русский в _document.tsx. Добавлены мета-теги для страниц: brands, catalog, contacts, index, search-result, thankyoupage, vin, wholesale и vehicle-search.

This commit is contained in:
Bivekich
2025-07-06 18:13:13 +03:00
parent 795ebf875a
commit 08ae507c36
13 changed files with 413 additions and 90 deletions

View File

@ -0,0 +1,98 @@
import Head from 'next/head';
import { useRouter } from 'next/router';
interface MetaTagsProps {
title?: string;
description?: string;
keywords?: string;
ogTitle?: string;
ogDescription?: string;
ogImage?: string;
ogUrl?: string;
twitterTitle?: string;
twitterDescription?: string;
twitterImage?: string;
canonical?: string;
robots?: string;
author?: string;
viewport?: string;
charset?: string;
}
const MetaTags: React.FC<MetaTagsProps> = ({
title = 'Protek - Автозапчасти и аксессуары',
description = 'Protek - широкий ассортимент автозапчастей и аксессуаров для всех марок автомобилей. Быстрая доставка, гарантия качества.',
keywords = 'автозапчасти, запчасти, автомобили, аксессуары, доставка, protek',
ogTitle,
ogDescription,
ogImage = '/images/og-image.jpg',
ogUrl,
twitterTitle,
twitterDescription,
twitterImage,
canonical,
robots = 'index, follow',
author = 'Protek',
viewport = 'width=device-width, initial-scale=1',
charset = 'utf-8'
}) => {
const router = useRouter();
const baseUrl = 'https://protek.ru'; // Замените на ваш домен
const currentUrl = ogUrl || `${baseUrl}${router.asPath}`;
const canonicalUrl = canonical || currentUrl;
const finalOgTitle = ogTitle || title;
const finalOgDescription = ogDescription || description;
const finalTwitterTitle = twitterTitle || title;
const finalTwitterDescription = twitterDescription || description;
const finalTwitterImage = twitterImage || ogImage;
return (
<Head>
{/* Базовые meta-теги */}
<meta charSet={charset} />
<title>{title}</title>
<meta name="description" content={description} />
<meta name="keywords" content={keywords} />
<meta name="author" content={author} />
<meta name="viewport" content={viewport} />
<meta name="robots" content={robots} />
{/* Canonical URL */}
<link rel="canonical" href={canonicalUrl} />
{/* Open Graph теги */}
<meta property="og:type" content="website" />
<meta property="og:title" content={finalOgTitle} />
<meta property="og:description" content={finalOgDescription} />
<meta property="og:image" content={ogImage} />
<meta property="og:url" content={currentUrl} />
<meta property="og:site_name" content="Protek" />
<meta property="og:locale" content="ru_RU" />
{/* Twitter Card теги */}
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:title" content={finalTwitterTitle} />
<meta name="twitter:description" content={finalTwitterDescription} />
<meta name="twitter:image" content={finalTwitterImage} />
{/* Favicon и иконки */}
<link href="/images/favicon.png" rel="shortcut icon" type="image/x-icon" />
<link href="/images/webclip.png" rel="apple-touch-icon" />
{/* Preconnect для производительности */}
<link href="https://fonts.googleapis.com" rel="preconnect" />
<link href="https://fonts.gstatic.com" rel="preconnect" crossOrigin="anonymous" />
{/* Дополнительные meta-теги для SEO */}
<meta name="format-detection" content="telephone=no" />
<meta name="theme-color" content="#dc2626" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="default" />
<meta name="apple-mobile-web-app-title" content="Protek" />
</Head>
);
};
export default MetaTags;

30
src/hooks/useMetaTags.ts Normal file
View File

@ -0,0 +1,30 @@
import { useRouter } from 'next/router';
import { useMemo } from 'react';
import { getMetaByPath } from '@/lib/meta-config';
interface MetaTagsData {
title: string;
description: string;
keywords: string;
ogTitle?: string;
ogDescription?: string;
}
export const useMetaTags = (customMeta?: Partial<MetaTagsData>): MetaTagsData => {
const router = useRouter();
const metaData = useMemo(() => {
// Получаем базовые meta-теги для текущего пути
const baseMeta = getMetaByPath(router.asPath);
// Объединяем с пользовательскими meta-тегами
return {
...baseMeta,
...customMeta
};
}, [router.asPath, customMeta]);
return metaData;
};
export default useMetaTags;

192
src/lib/meta-config.ts Normal file
View File

@ -0,0 +1,192 @@
interface MetaConfig {
title: string;
description: string;
keywords: string;
ogTitle?: string;
ogDescription?: string;
}
export const metaConfig: Record<string, MetaConfig> = {
// Главная страница
'/': {
title: 'Protek - Автозапчасти и аксессуары для всех марок автомобилей',
description: 'Protek - широкий ассортимент автозапчастей и аксессуаров для всех марок автомобилей. Быстрая доставка по России, гарантия качества, низкие цены.',
keywords: 'автозапчасти, запчасти для автомобилей, автоаксессуары, доставка запчастей, protek, протек',
ogTitle: 'Protek - Автозапчасти и аксессуары',
ogDescription: 'Широкий ассортимент автозапчастей и аксессуаров для всех марок автомобилей. Быстрая доставка, гарантия качества.'
},
// Каталог
'/catalog': {
title: 'Каталог автозапчастей - Protek',
description: 'Полный каталог автозапчастей для всех марок автомобилей. Более 1 миллиона наименований запчастей в наличии и под заказ.',
keywords: 'каталог запчастей, автозапчасти каталог, запчасти для авто, поиск запчастей',
ogTitle: 'Каталог автозапчастей - Protek',
ogDescription: 'Полный каталог автозапчастей для всех марок автомобилей. Более 1 миллиона наименований.'
},
// Марки автомобилей
'/brands': {
title: 'Все марки автомобилей - Каталог запчастей Protek',
description: 'Полный каталог автомобильных брендов для поиска запчастей. Выберите марку вашего автомобиля и найдите нужные запчасти.',
keywords: 'марки автомобилей, бренды авто, запчасти по маркам, автомобильные марки',
ogTitle: 'Все марки автомобилей - Protek',
ogDescription: 'Полный каталог автомобильных брендов для поиска запчастей.'
},
// Поиск по VIN
'/vin': {
title: 'Поиск запчастей по VIN коду - Protek',
description: 'Быстрый и точный поиск автозапчастей по VIN коду автомобиля. Определите совместимые запчасти для вашего авто.',
keywords: 'поиск по VIN, VIN код, запчасти по VIN, определение запчастей, совместимость',
ogTitle: 'Поиск запчастей по VIN коду - Protek',
ogDescription: 'Быстрый и точный поиск автозапчастей по VIN коду автомобиля.'
},
// Контакты
'/contacts': {
title: 'Контакты - Protek',
description: 'Контактная информация компании Protek. Адреса магазинов, телефоны, режим работы. Свяжитесь с нами для консультации.',
keywords: 'контакты protek, адрес, телефон, режим работы, магазины запчастей',
ogTitle: 'Контакты - Protek',
ogDescription: 'Контактная информация компании Protek. Адреса магазинов, телефоны, режим работы.'
},
// О компании
'/about': {
title: 'О компании Protek - Автозапчасти и аксессуары',
description: 'Компания Protek - надежный поставщик автозапчастей с многолетним опытом. Узнайте больше о нашей истории и преимуществах.',
keywords: 'о компании protek, история компании, преимущества, автозапчасти',
ogTitle: 'О компании Protek',
ogDescription: 'Компания Protek - надежный поставщик автозапчастей с многолетним опытом.'
},
// Новости
'/news': {
title: 'Новости и акции - Protek',
description: 'Актуальные новости компании Protek, специальные предложения и акции на автозапчасти.',
keywords: 'новости protek, акции, специальные предложения, скидки на запчасти',
ogTitle: 'Новости и акции - Protek',
ogDescription: 'Актуальные новости компании Protek, специальные предложения и акции.'
},
// Оптовые продажи
'/wholesale': {
title: 'Оптовые продажи автозапчастей - Protek',
description: 'Оптовые продажи автозапчастей для автосервисов и дилеров. Специальные цены, гибкие условия сотрудничества.',
keywords: 'оптовые продажи, запчасти оптом, для автосервисов, дилерам, оптовые цены',
ogTitle: 'Оптовые продажи автозапчастей - Protek',
ogDescription: 'Оптовые продажи автозапчастей для автосервисов и дилеров. Специальные цены.'
},
// Способы оплаты
'/payments-method': {
title: 'Способы оплаты - Protek',
description: 'Удобные способы оплаты автозапчастей: наличными, картой, банковским переводом, онлайн-платежи.',
keywords: 'способы оплаты, оплата запчастей, банковская карта, наличные, онлайн-платеж',
ogTitle: 'Способы оплаты - Protek',
ogDescription: 'Удобные способы оплаты автозапчастей: наличными, картой, банковским переводом.'
},
// Корзина
'/cart': {
title: 'Корзина - Protek',
description: 'Корзина покупок. Оформите заказ на выбранные автозапчасти с быстрой доставкой.',
keywords: 'корзина покупок, оформление заказа, заказать запчасти',
ogTitle: 'Корзина - Protek',
ogDescription: 'Корзина покупок. Оформите заказ на выбранные автозапчасти.'
},
// Избранное
'/favorite': {
title: 'Избранные товары - Protek',
description: 'Ваши избранные автозапчасти. Сохраните интересующие товары для быстрого доступа.',
keywords: 'избранные товары, сохраненные запчасти, избранное',
ogTitle: 'Избранные товары - Protek',
ogDescription: 'Ваши избранные автозапчасти. Сохраните интересующие товары.'
},
// Профиль
'/profile-orders': {
title: 'Мои заказы - Личный кабинет Protek',
description: 'Личный кабинет клиента Protek. Управляйте своими заказами, отслеживайте статус доставки.',
keywords: 'личный кабинет, мои заказы, статус заказа, история покупок',
ogTitle: 'Мои заказы - Личный кабинет Protek',
ogDescription: 'Личный кабинет клиента Protek. Управляйте своими заказами.'
},
// Страница благодарности
'/thankyoupage': {
title: 'Спасибо за заказ - Protek',
description: 'Ваш заказ успешно оформлен. Мы свяжемся с вами в ближайшее время для подтверждения.',
keywords: 'заказ оформлен, спасибо за заказ, подтверждение заказа',
ogTitle: 'Спасибо за заказ - Protek',
ogDescription: 'Ваш заказ успешно оформлен. Мы свяжемся с вами в ближайшее время.'
}
};
// Функция для получения meta-тегов по пути
export const getMetaByPath = (path: string): MetaConfig => {
// Нормализуем путь (убираем query параметры)
const normalizedPath = path.split('?')[0];
// Проверяем точное совпадение
if (metaConfig[normalizedPath]) {
return metaConfig[normalizedPath];
}
// Проверяем динамические пути
if (normalizedPath.startsWith('/vehicle-search/')) {
return {
title: 'Поиск запчастей по автомобилю - Protek',
description: 'Найдите подходящие запчасти для вашего автомобиля. Точный подбор по марке, модели и году выпуска.',
keywords: 'поиск запчастей, подбор по автомобилю, запчасти для авто'
};
}
if (normalizedPath.startsWith('/search-result')) {
return {
title: 'Результаты поиска - Protek',
description: 'Результаты поиска автозапчастей. Найдите нужные запчасти среди широкого ассортимента.',
keywords: 'результаты поиска, поиск запчастей, найти запчасти'
};
}
if (normalizedPath.startsWith('/payment/')) {
return {
title: 'Оплата заказа - Protek',
description: 'Оплата заказа автозапчастей. Безопасные способы оплаты онлайн.',
keywords: 'оплата заказа, онлайн оплата, безопасная оплата'
};
}
// Возвращаем дефолтные meta-теги
return metaConfig['/'];
};
// Функция для создания динамических meta-тегов для товаров
export const createProductMeta = (product: {
name: string;
brand: string;
articleNumber: string;
price?: number;
}): MetaConfig => {
return {
title: `${product.brand} ${product.articleNumber} - ${product.name} - Protek`,
description: `Купить ${product.name} ${product.brand} артикул ${product.articleNumber}${product.price ? ` по цене ${product.price} руб.` : ''}. Гарантия качества, быстрая доставка.`,
keywords: `${product.name}, ${product.brand}, ${product.articleNumber}, запчасти, автозапчасти`,
ogTitle: `${product.brand} ${product.articleNumber} - ${product.name}`,
ogDescription: `Купить ${product.name} ${product.brand} артикул ${product.articleNumber}. Гарантия качества, быстрая доставка.`
};
};
// Функция для создания meta-тегов для категорий
export const createCategoryMeta = (categoryName: string, count?: number): MetaConfig => {
return {
title: `${categoryName} - Каталог запчастей Protek`,
description: `Купить ${categoryName.toLowerCase()} для автомобилей${count ? `. В наличии ${count} товаров` : ''}. Широкий выбор, низкие цены, быстрая доставка.`,
keywords: `${categoryName.toLowerCase()}, запчасти, автозапчасти, каталог`,
ogTitle: `${categoryName} - Protek`,
ogDescription: `Купить ${categoryName.toLowerCase()} для автомобилей. Широкий выбор, низкие цены.`
};
};

View File

@ -2,8 +2,23 @@ import { Html, Head, Main, NextScript } from "next/document";
export default function Document() { export default function Document() {
return ( return (
<Html lang="en"> <Html lang="ru">
<Head /> <Head>
{/* Базовые meta-теги */}
<meta name="format-detection" content="telephone=no" />
<meta name="theme-color" content="#dc2626" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="default" />
<meta name="apple-mobile-web-app-title" content="Protek" />
{/* Preconnect для производительности */}
<link href="https://fonts.googleapis.com" rel="preconnect" />
<link href="https://fonts.gstatic.com" rel="preconnect" crossOrigin="anonymous" />
{/* Favicon */}
<link href="/images/favicon.png" rel="shortcut icon" type="image/x-icon" />
<link href="/images/webclip.png" rel="apple-touch-icon" />
</Head>
<body> <body>
<Main /> <Main />
<NextScript /> <NextScript />

View File

@ -8,6 +8,8 @@ import MobileMenuBottomSection from "@/components/MobileMenuBottomSection";
import { GET_LAXIMO_BRANDS } from "@/lib/graphql"; import { GET_LAXIMO_BRANDS } from "@/lib/graphql";
import { LaximoBrand } from "@/types/laximo"; import { LaximoBrand } from "@/types/laximo";
import BrandWizardSearchSection from "@/components/BrandWizardSearchSection"; import BrandWizardSearchSection from "@/components/BrandWizardSearchSection";
import MetaTags from "@/components/MetaTags";
import { getMetaByPath } from "@/lib/meta-config";
const InfoBrands = () => ( const InfoBrands = () => (
<section className="section-info"> <section className="section-info">
@ -85,14 +87,11 @@ const BrandsPage = () => {
setSelectedLetter(selectedLetter === letter ? '' : letter); setSelectedLetter(selectedLetter === letter ? '' : letter);
}; };
const metaData = getMetaByPath('/brands');
return ( return (
<> <>
<Head> <MetaTags {...metaData} />
<title>Все марки автомобилей - Protek</title>
<meta name="description" content="Полный каталог автомобильных брендов для поиска запчастей" />
<link href="images/favicon.png" rel="shortcut icon" type="image/x-icon" />
<link href="images/webclip.png" rel="apple-touch-icon" />
</Head>
<InfoBrands /> <InfoBrands />
<BrandWizardSearchSection /> <BrandWizardSearchSection />
<Footer /> <Footer />

View File

@ -24,6 +24,8 @@ import { PriceSkeleton } from '@/components/skeletons/ProductListSkeleton';
import { useCart } from '@/contexts/CartContext'; import { useCart } from '@/contexts/CartContext';
import toast from 'react-hot-toast'; import toast from 'react-hot-toast';
import CartIcon from '@/components/CartIcon'; import CartIcon from '@/components/CartIcon';
import MetaTags from "@/components/MetaTags";
import { getMetaByPath, createCategoryMeta } from "@/lib/meta-config";
const mockData = Array(12).fill({ const mockData = Array(12).fill({
image: "", image: "",
@ -506,16 +508,13 @@ export default function Catalog() {
return <div className="py-8 text-center">Загрузка фильтров...</div>; return <div className="py-8 text-center">Загрузка фильтров...</div>;
} }
// Определяем meta-теги для каталога
const categoryNameDecoded = decodeURIComponent(categoryName as string || 'Каталог');
const metaData = createCategoryMeta(categoryNameDecoded, visibleProductsCount || undefined);
return ( return (
<> <>
<Head> <MetaTags {...metaData} />
<title>Catalog</title>
<meta name="description" content="Catalog" />
<link href="https://fonts.googleapis.com" rel="preconnect" />
<link href="https://fonts.gstatic.com" rel="preconnect" crossOrigin="anonymous" />
<link href="images/favicon.png" rel="shortcut icon" type="image/x-icon" />
<link href="images/webclip.png" rel="apple-touch-icon" />
</Head>
<CatalogInfoHeader <CatalogInfoHeader
title={ title={
isPartsAPIMode ? decodeURIComponent(categoryName as string || 'Запчасти') : isPartsAPIMode ? decodeURIComponent(categoryName as string || 'Запчасти') :

View File

@ -8,17 +8,15 @@ import InfoContacts from "@/components/contacts/InfoContacts";
import MapContacts from "@/components/contacts/MapContacts"; import MapContacts from "@/components/contacts/MapContacts";
import OrderContacts from "@/components/contacts/OrderContacts"; import OrderContacts from "@/components/contacts/OrderContacts";
import LegalContacts from "@/components/contacts/LegalContacts"; import LegalContacts from "@/components/contacts/LegalContacts";
import MetaTags from "@/components/MetaTags";
import { getMetaByPath } from "@/lib/meta-config";
const Contacts = () => ( const Contacts = () => {
<> const metaData = getMetaByPath('/contacts');
<Head>
<title>Contacts</title> return (
<meta name="description" content="Contacts" /> <>
<link href="https://fonts.googleapis.com" rel="preconnect" /> <MetaTags {...metaData} />
<link href="https://fonts.gstatic.com" rel="preconnect" crossOrigin="anonymous" />
<link href="images/favicon.png" rel="shortcut icon" type="image/x-icon" />
<link href="images/webclip.png" rel="apple-touch-icon" />
</Head>
<InfoContacts /> <InfoContacts />
<section className="main"> <section className="main">
<div className="w-layout-blockcontainer container w-container"> <div className="w-layout-blockcontainer container w-container">
@ -38,7 +36,8 @@ const Contacts = () => (
</section> </section>
<Footer /> <Footer />
<MobileMenuBottomSection /> <MobileMenuBottomSection />
</> </>
); );
};
export default Contacts; export default Contacts;

View File

@ -11,6 +11,8 @@ import CatalogSection from "@/components/index/CatalogSection";
import AvailableParts from "@/components/index/AvailableParts"; import AvailableParts from "@/components/index/AvailableParts";
import NewsAndPromos from "@/components/index/NewsAndPromos"; import NewsAndPromos from "@/components/index/NewsAndPromos";
import AboutHelp from "@/components/about/AboutHelp"; import AboutHelp from "@/components/about/AboutHelp";
import MetaTags from "@/components/MetaTags";
import { getMetaByPath } from "@/lib/meta-config";
const geistSans = Geist({ const geistSans = Geist({
variable: "--font-geist-sans", variable: "--font-geist-sans",
@ -23,16 +25,11 @@ const geistMono = Geist_Mono({
}); });
export default function Home() { export default function Home() {
const metaData = getMetaByPath('/');
return ( return (
<> <>
<Head> <MetaTags {...metaData} />
<title>Protek</title>
<meta name="description" content="Protek" />
<link href="https://fonts.googleapis.com" rel="preconnect" />
<link href="https://fonts.gstatic.com" rel="preconnect" crossOrigin="anonymous" />
<link href="images/favicon.png" rel="shortcut icon" type="image/x-icon" />
<link href="images/webclip.png" rel="apple-touch-icon" />
</Head>
<HeroSlider /> <HeroSlider />
<CatalogSection /> <CatalogSection />
<div className="w-layout-blockcontainer container w-container"> <div className="w-layout-blockcontainer container w-container">

View File

@ -16,6 +16,8 @@ import MobileMenuBottomSection from '../components/MobileMenuBottomSection';
import { SEARCH_PRODUCT_OFFERS, GET_ANALOG_OFFERS } from "@/lib/graphql"; import { SEARCH_PRODUCT_OFFERS, GET_ANALOG_OFFERS } from "@/lib/graphql";
import { useArticleImage } from "@/hooks/useArticleImage"; import { useArticleImage } from "@/hooks/useArticleImage";
import { usePartsIndexEntityInfo } from "@/hooks/usePartsIndex"; import { usePartsIndexEntityInfo } from "@/hooks/usePartsIndex";
import MetaTags from "@/components/MetaTags";
import { createProductMeta } from "@/lib/meta-config";
const ANALOGS_CHUNK_SIZE = 5; const ANALOGS_CHUNK_SIZE = 5;
@ -435,21 +437,21 @@ export default function SearchResult() {
); );
} }
// Создаем динамические meta-теги для товара
const metaData = result ? createProductMeta({
name: result.name,
brand: result.brand,
articleNumber: result.articleNumber,
price: minPrice
}) : {
title: 'Результаты поиска - Protek',
description: 'Результаты поиска автозапчастей. Найдите нужные запчасти среди широкого ассортимента.',
keywords: 'результаты поиска, поиск запчастей, найти запчасти'
};
return ( return (
<> <>
<Head> <MetaTags {...metaData} />
<title>{result ? `${result.brand} ${result.articleNumber} - ${result.name}` : `Результаты поиска`} - Protek</title>
<meta name="description" content={`Лучшие предложения и аналоги для ${result?.name}`} />
<meta content="Search result" property="og:title" />
<meta content="Search result" property="twitter:title" />
<meta content="width=device-width, initial-scale=1" name="viewport" />
<meta content="Webflow" name="generator" />
<link href="https://fonts.googleapis.com" rel="preconnect" />
<link href="https://fonts.gstatic.com" rel="preconnect" crossOrigin="anonymous" />
<link href="images/favicon.png" rel="shortcut icon" type="image/x-icon" />
<link href="images/webclip.png" rel="apple-touch-icon" />
</Head>
<InfoSearch <InfoSearch
brand={result ? result.brand : brandQuery} brand={result ? result.brand : brandQuery}
articleNumber={result ? result.articleNumber : searchQuery} articleNumber={result ? result.articleNumber : searchQuery}

View File

@ -5,23 +5,19 @@ import CatalogSubscribe from "@/components/CatalogSubscribe";
import Footer from "@/components/Footer"; import Footer from "@/components/Footer";
import MobileMenuBottomSection from "@/components/MobileMenuBottomSection"; import MobileMenuBottomSection from "@/components/MobileMenuBottomSection";
import Link from 'next/link'; import Link from 'next/link';
import MetaTags from "@/components/MetaTags";
import { getMetaByPath } from "@/lib/meta-config";
export default function ThankYouPage() { export default function ThankYouPage() {
const metaData = getMetaByPath('/thankyoupage');
return ( return (
<> <>
<MetaTags {...metaData} />
<Head> <Head>
<meta charSet="utf-8" />
<title>thankyoupage</title>
<meta content="thankyoupage" property="og:title" />
<meta content="thankyoupage" property="twitter:title" />
<meta content="width=device-width, initial-scale=1" name="viewport" />
<link href="https://fonts.googleapis.com" rel="preconnect" />
<link href="https://fonts.gstatic.com" rel="preconnect" crossOrigin="anonymous" />
<script src="https://ajax.googleapis.com/ajax/libs/webfont/1.6.26/webfont.js" type="text/javascript"></script> <script src="https://ajax.googleapis.com/ajax/libs/webfont/1.6.26/webfont.js" type="text/javascript"></script>
<script type="text/javascript" dangerouslySetInnerHTML={{__html: `WebFont.load({ google: { families: [\"Onest:regular,600,700,800,900:cyrillic-ext,latin\"] }});`}} /> <script type="text/javascript" dangerouslySetInnerHTML={{__html: `WebFont.load({ google: { families: [\"Onest:regular,600,700,800,900:cyrillic-ext,latin\"] }});`}} />
<script type="text/javascript" dangerouslySetInnerHTML={{__html: `!function(o,c){var n=c.documentElement,t=\" w-mod-\";n.className+=t+\"js\",(\"ontouchstart\"in o||o.DocumentTouch&&c instanceof DocumentTouch)&&(n.className+=t+\"touch\")}(window,document);`}} /> <script type="text/javascript" dangerouslySetInnerHTML={{__html: `!function(o,c){var n=c.documentElement,t=\" w-mod-\";n.className+=t+\"js\",(\"ontouchstart\"in o||o.DocumentTouch&&c instanceof DocumentTouch)&&(n.className+=t+\"touch\")}(window,document);`}} />
<link href="images/favicon.png" rel="shortcut icon" type="image/x-icon" />
<link href="images/webclip.png" rel="apple-touch-icon" />
</Head> </Head>
<ThankInfo /> <ThankInfo />

View File

@ -19,6 +19,8 @@ import KnotParts from '@/components/vin/KnotParts';
import VinQuick from '@/components/vin/VinQuick'; import VinQuick from '@/components/vin/VinQuick';
import CatalogSubscribe from '@/components/CatalogSubscribe'; import CatalogSubscribe from '@/components/CatalogSubscribe';
import MobileMenuBottomSection from '@/components/MobileMenuBottomSection'; import MobileMenuBottomSection from '@/components/MobileMenuBottomSection';
import MetaTags from '@/components/MetaTags';
import { getMetaByPath } from '@/lib/meta-config';
interface LaximoVehicleInfo { interface LaximoVehicleInfo {
@ -290,16 +292,24 @@ const VehicleDetailsPage = () => {
const hasError = vehicleError && !vehicleData?.laximoVehicleInfo; const hasError = vehicleError && !vehicleData?.laximoVehicleInfo;
const catalogInfo = catalogData.laximoCatalogInfo; const catalogInfo = catalogData.laximoCatalogInfo;
// Создаем динамические meta-теги
const vehicleName = vehicleInfo.brand && vehicleInfo.name
? (vehicleInfo.name.indexOf(vehicleInfo.brand) !== 0
? `${vehicleInfo.brand} ${vehicleInfo.name}`
: vehicleInfo.name)
: 'Автомобиль';
const metaData = {
title: `Запчасти для ${vehicleName} - Поиск по каталогу Protek`,
description: `Найдите и купите запчасти для ${vehicleName}. Широкий выбор оригинальных и аналоговых запчастей с быстрой доставкой.`,
keywords: `запчасти ${vehicleName}, ${vehicleInfo.brand} запчасти, автозапчасти, каталог запчастей`,
ogTitle: `Запчасти для ${vehicleName} - Protek`,
ogDescription: `Найдите и купите запчасти для ${vehicleName}. Широкий выбор оригинальных и аналоговых запчастей.`
};
return ( return (
<> <>
<Head> <MetaTags {...metaData} />
<title>VIN</title>
<meta content="vin" property="og:title" />
<meta content="vin" property="twitter:title" />
<link href="images/favicon.png" rel="shortcut icon" type="image/x-icon" />
<link href="images/webclip.png" rel="apple-touch-icon" />
</Head>
{/* ====== ВРЕМЕННЫЙ МАКЕТ ДЛЯ ВЕРСТКИ (начало) ====== */} {/* ====== ВРЕМЕННЫЙ МАКЕТ ДЛЯ ВЕРСТКИ (начало) ====== */}
<InfoVin <InfoVin

View File

@ -8,6 +8,8 @@ import VinLeftbar from "@/components/vin/VinLeftbar";
import VinCategory from "@/components/vin/VinCategory"; import VinCategory from "@/components/vin/VinCategory";
import VinKnot from "@/components/vin/VinKnot"; import VinKnot from "@/components/vin/VinKnot";
import React, { useState } from "react"; import React, { useState } from "react";
import MetaTags from "@/components/MetaTags";
import { getMetaByPath } from "@/lib/meta-config";
export default function Vin() { export default function Vin() {
const [showKnot, setShowKnot] = useState(false); const [showKnot, setShowKnot] = useState(false);
@ -31,18 +33,11 @@ export default function Vin() {
return () => document.removeEventListener("click", handler); return () => document.removeEventListener("click", handler);
}, []); }, []);
const metaData = getMetaByPath('/vin');
return ( return (
<> <>
<Head> <MetaTags {...metaData} />
<title>VIN</title>
<meta content="vin" property="og:title" />
<meta content="vin" property="twitter:title" />
<meta content="width=device-width, initial-scale=1" name="viewport" />
<link href="https://fonts.googleapis.com" rel="preconnect" />
<link href="https://fonts.gstatic.com" rel="preconnect" crossOrigin="anonymous" />
<link href="images/favicon.png" rel="shortcut icon" type="image/x-icon" />
<link href="images/webclip.png" rel="apple-touch-icon" />
</Head>
<InfoVin /> <InfoVin />
<section className="main"> <section className="main">
<div className="w-layout-blockcontainer container-vin w-container"> <div className="w-layout-blockcontainer container-vin w-container">

View File

@ -9,25 +9,16 @@ import WhyWholesale from "@/components/wholesale/WhyWholesale";
import ServiceWholesale from "@/components/wholesale/ServiceWholesale"; import ServiceWholesale from "@/components/wholesale/ServiceWholesale";
import HowToBuy from "@/components/wholesale/HowToBuy"; import HowToBuy from "@/components/wholesale/HowToBuy";
import Help from "@/components/Help"; import Help from "@/components/Help";
import MetaTags from "@/components/MetaTags";
import { getMetaByPath } from "@/lib/meta-config";
export default function Wholesale() { export default function Wholesale() {
const metaData = getMetaByPath('/wholesale');
return ( return (
<> <>
<Head> <MetaTags {...metaData} />
<title>wholesale</title>
<meta content="wholesale" property="og:title" />
<meta content="wholesale" property="twitter:title" />
<meta content="width=device-width, initial-scale=1" name="viewport" />
<meta content="Webflow" name="generator" />
<link href="/css/normalize.css" rel="stylesheet" type="text/css" />
<link href="/css/webflow.css" rel="stylesheet" type="text/css" />
<link href="/css/protekproject.webflow.css" rel="stylesheet" type="text/css" />
<link href="https://fonts.googleapis.com" rel="preconnect" />
<link href="https://fonts.gstatic.com" rel="preconnect" crossOrigin="anonymous" />
<link href="images/favicon.png" rel="shortcut icon" type="image/x-icon" />
<link href="images/webclip.png" rel="apple-touch-icon" />
</Head>
<InfoWholesale /> <InfoWholesale />
<section className="main"> <section className="main">