Обновлены страницы с мета-тегами: заменены статические мета-теги на компонент 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

@ -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 />

View File

@ -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 />

View File

@ -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 || 'Запчасти') :

View File

@ -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 = () => (
<>
<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>
const Contacts = () => {
const metaData = getMetaByPath('/contacts');
return (
<>
<MetaTags {...metaData} />
<InfoContacts />
<section className="main">
<div className="w-layout-blockcontainer container w-container">
@ -38,7 +36,8 @@ const Contacts = () => (
</section>
<Footer />
<MobileMenuBottomSection />
</>
);
</>
);
};
export default Contacts;

View File

@ -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">

View File

@ -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}

View File

@ -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 />

View File

@ -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

View File

@ -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">

View File

@ -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">