Обновлены страницы с мета-тегами: заменены статические мета-теги на компонент MetaTags, который динамически получает данные через getMetaByPath. Изменен язык документа на русский в _document.tsx. Добавлены мета-теги для страниц: brands, catalog, contacts, index, search-result, thankyoupage, vin, wholesale и vehicle-search.
This commit is contained in:
98
src/components/MetaTags.tsx
Normal file
98
src/components/MetaTags.tsx
Normal 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
30
src/hooks/useMetaTags.ts
Normal 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
192
src/lib/meta-config.ts
Normal 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()} для автомобилей. Широкий выбор, низкие цены.`
|
||||
};
|
||||
};
|
@ -2,8 +2,23 @@ import { Html, Head, Main, NextScript } from "next/document";
|
||||
|
||||
export default function Document() {
|
||||
return (
|
||||
<Html lang="en">
|
||||
<Head />
|
||||
<Html lang="ru">
|
||||
<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>
|
||||
<Main />
|
||||
<NextScript />
|
||||
|
@ -8,6 +8,8 @@ import MobileMenuBottomSection from "@/components/MobileMenuBottomSection";
|
||||
import { GET_LAXIMO_BRANDS } from "@/lib/graphql";
|
||||
import { LaximoBrand } from "@/types/laximo";
|
||||
import BrandWizardSearchSection from "@/components/BrandWizardSearchSection";
|
||||
import MetaTags from "@/components/MetaTags";
|
||||
import { getMetaByPath } from "@/lib/meta-config";
|
||||
|
||||
const InfoBrands = () => (
|
||||
<section className="section-info">
|
||||
@ -85,14 +87,11 @@ const BrandsPage = () => {
|
||||
setSelectedLetter(selectedLetter === letter ? '' : letter);
|
||||
};
|
||||
|
||||
const metaData = getMetaByPath('/brands');
|
||||
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
<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>
|
||||
<MetaTags {...metaData} />
|
||||
<InfoBrands />
|
||||
<BrandWizardSearchSection />
|
||||
<Footer />
|
||||
|
@ -24,6 +24,8 @@ import { PriceSkeleton } from '@/components/skeletons/ProductListSkeleton';
|
||||
import { useCart } from '@/contexts/CartContext';
|
||||
import toast from 'react-hot-toast';
|
||||
import CartIcon from '@/components/CartIcon';
|
||||
import MetaTags from "@/components/MetaTags";
|
||||
import { getMetaByPath, createCategoryMeta } from "@/lib/meta-config";
|
||||
|
||||
const mockData = Array(12).fill({
|
||||
image: "",
|
||||
@ -506,16 +508,13 @@ export default function Catalog() {
|
||||
return <div className="py-8 text-center">Загрузка фильтров...</div>;
|
||||
}
|
||||
|
||||
// Определяем meta-теги для каталога
|
||||
const categoryNameDecoded = decodeURIComponent(categoryName as string || 'Каталог');
|
||||
const metaData = createCategoryMeta(categoryNameDecoded, visibleProductsCount || undefined);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
<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>
|
||||
<MetaTags {...metaData} />
|
||||
<CatalogInfoHeader
|
||||
title={
|
||||
isPartsAPIMode ? decodeURIComponent(categoryName as string || 'Запчасти') :
|
||||
|
@ -8,17 +8,15 @@ import InfoContacts from "@/components/contacts/InfoContacts";
|
||||
import MapContacts from "@/components/contacts/MapContacts";
|
||||
import OrderContacts from "@/components/contacts/OrderContacts";
|
||||
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');
|
||||
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
<title>Contacts</title>
|
||||
<meta name="description" content="Contacts" />
|
||||
<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>
|
||||
<MetaTags {...metaData} />
|
||||
<InfoContacts />
|
||||
<section className="main">
|
||||
<div className="w-layout-blockcontainer container w-container">
|
||||
@ -40,5 +38,6 @@ const Contacts = () => (
|
||||
<MobileMenuBottomSection />
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default Contacts;
|
@ -11,6 +11,8 @@ import CatalogSection from "@/components/index/CatalogSection";
|
||||
import AvailableParts from "@/components/index/AvailableParts";
|
||||
import NewsAndPromos from "@/components/index/NewsAndPromos";
|
||||
import AboutHelp from "@/components/about/AboutHelp";
|
||||
import MetaTags from "@/components/MetaTags";
|
||||
import { getMetaByPath } from "@/lib/meta-config";
|
||||
|
||||
const geistSans = Geist({
|
||||
variable: "--font-geist-sans",
|
||||
@ -23,16 +25,11 @@ const geistMono = Geist_Mono({
|
||||
});
|
||||
|
||||
export default function Home() {
|
||||
const metaData = getMetaByPath('/');
|
||||
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
<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>
|
||||
<MetaTags {...metaData} />
|
||||
<HeroSlider />
|
||||
<CatalogSection />
|
||||
<div className="w-layout-blockcontainer container w-container">
|
||||
|
@ -16,6 +16,8 @@ import MobileMenuBottomSection from '../components/MobileMenuBottomSection';
|
||||
import { SEARCH_PRODUCT_OFFERS, GET_ANALOG_OFFERS } from "@/lib/graphql";
|
||||
import { useArticleImage } from "@/hooks/useArticleImage";
|
||||
import { usePartsIndexEntityInfo } from "@/hooks/usePartsIndex";
|
||||
import MetaTags from "@/components/MetaTags";
|
||||
import { createProductMeta } from "@/lib/meta-config";
|
||||
|
||||
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 (
|
||||
<>
|
||||
<Head>
|
||||
<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>
|
||||
<MetaTags {...metaData} />
|
||||
<InfoSearch
|
||||
brand={result ? result.brand : brandQuery}
|
||||
articleNumber={result ? result.articleNumber : searchQuery}
|
||||
|
@ -5,23 +5,19 @@ import CatalogSubscribe from "@/components/CatalogSubscribe";
|
||||
import Footer from "@/components/Footer";
|
||||
import MobileMenuBottomSection from "@/components/MobileMenuBottomSection";
|
||||
import Link from 'next/link';
|
||||
import MetaTags from "@/components/MetaTags";
|
||||
import { getMetaByPath } from "@/lib/meta-config";
|
||||
|
||||
export default function ThankYouPage() {
|
||||
const metaData = getMetaByPath('/thankyoupage');
|
||||
|
||||
return (
|
||||
<>
|
||||
<MetaTags {...metaData} />
|
||||
<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 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);`}} />
|
||||
<link href="images/favicon.png" rel="shortcut icon" type="image/x-icon" />
|
||||
<link href="images/webclip.png" rel="apple-touch-icon" />
|
||||
</Head>
|
||||
|
||||
<ThankInfo />
|
||||
|
@ -19,6 +19,8 @@ import KnotParts from '@/components/vin/KnotParts';
|
||||
import VinQuick from '@/components/vin/VinQuick';
|
||||
import CatalogSubscribe from '@/components/CatalogSubscribe';
|
||||
import MobileMenuBottomSection from '@/components/MobileMenuBottomSection';
|
||||
import MetaTags from '@/components/MetaTags';
|
||||
import { getMetaByPath } from '@/lib/meta-config';
|
||||
|
||||
|
||||
interface LaximoVehicleInfo {
|
||||
@ -290,16 +292,24 @@ const VehicleDetailsPage = () => {
|
||||
const hasError = vehicleError && !vehicleData?.laximoVehicleInfo;
|
||||
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 (
|
||||
<>
|
||||
<Head>
|
||||
<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>
|
||||
<MetaTags {...metaData} />
|
||||
|
||||
{/* ====== ВРЕМЕННЫЙ МАКЕТ ДЛЯ ВЕРСТКИ (начало) ====== */}
|
||||
<InfoVin
|
||||
|
@ -8,6 +8,8 @@ import VinLeftbar from "@/components/vin/VinLeftbar";
|
||||
import VinCategory from "@/components/vin/VinCategory";
|
||||
import VinKnot from "@/components/vin/VinKnot";
|
||||
import React, { useState } from "react";
|
||||
import MetaTags from "@/components/MetaTags";
|
||||
import { getMetaByPath } from "@/lib/meta-config";
|
||||
|
||||
export default function Vin() {
|
||||
const [showKnot, setShowKnot] = useState(false);
|
||||
@ -31,18 +33,11 @@ export default function Vin() {
|
||||
return () => document.removeEventListener("click", handler);
|
||||
}, []);
|
||||
|
||||
const metaData = getMetaByPath('/vin');
|
||||
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
<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>
|
||||
<MetaTags {...metaData} />
|
||||
<InfoVin />
|
||||
<section className="main">
|
||||
<div className="w-layout-blockcontainer container-vin w-container">
|
||||
|
@ -9,25 +9,16 @@ import WhyWholesale from "@/components/wholesale/WhyWholesale";
|
||||
import ServiceWholesale from "@/components/wholesale/ServiceWholesale";
|
||||
import HowToBuy from "@/components/wholesale/HowToBuy";
|
||||
import Help from "@/components/Help";
|
||||
import MetaTags from "@/components/MetaTags";
|
||||
import { getMetaByPath } from "@/lib/meta-config";
|
||||
|
||||
|
||||
export default function Wholesale() {
|
||||
const metaData = getMetaByPath('/wholesale');
|
||||
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
<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>
|
||||
<MetaTags {...metaData} />
|
||||
|
||||
<InfoWholesale />
|
||||
<section className="main">
|
||||
|
Reference in New Issue
Block a user