← Назад к вопросам

Как реализовывал SEO-требования?

1.8 Middle🔥 211 комментариев
#Браузер и сетевые технологии#Оптимизация и производительность

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI3 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Как реализовывал SEO-требования на фронтенде

SEO - это комплекс мер для оптимизации веб-сайта для поисковых систем. На фронтенде это включает правильную разметку, мета-теги, производительность и структурированные данные. Расскажу о моём опыте реализации.

1. Метатеги и Open Graph

// В Next.js (app router)
// app/products/[id]/page.tsx

import { Metadata } from 'next';

interface Product {
  id: string;
  title: string;
  description: string;
  image: string;
  price: number;
}

async function getProduct(id: string): Promise<Product> {
  const res = await fetch(`/api/products/${id}`);
  return res.json();
}

// Динамические метаданные
export async function generateMetadata(
  { params }: { params: { id: string } }
): Promise<Metadata> {
  const product = await getProduct(params.id);

  return {
    title: `${product.title} | Shop`,
    description: product.description,
    openGraph: {
      title: product.title,
      description: product.description,
      images: [
        {
          url: product.image,
          width: 1200,
          height: 630,
          alt: product.title,
        },
      ],
      type: 'product',
    },
    twitter: {
      card: 'summary_large_image',
      title: product.title,
      description: product.description,
      images: [product.image],
    },
  };
}

export default function ProductPage({ params }: { params: { id: string } }) {
  return (
    <div>
      <h1>{product.title}</h1>
      <p>{product.description}</p>
      <span>${product.price}</span>
    </div>
  );
}

2. Структурированные данные (Schema.org)

// Schema.org JSON-LD для поисковых систем

function ProductSchema({ product }) {
  const schema = {
    '@context': 'https://schema.org/',
    '@type': 'Product',
    name: product.title,
    description: product.description,
    image: product.image,
    brand: {
      '@type': 'Brand',
      name: product.brand,
    },
    offers: {
      '@type': 'Offer',
      url: `https://example.com/products/${product.id}`,
      priceCurrency: 'USD',
      price: product.price,
      availability: 'https://schema.org/InStock',
      seller: {
        '@type': 'Organization',
        name: 'Example Shop',
      },
    },
    aggregateRating: {
      '@type': 'AggregateRating',
      ratingValue: product.rating,
      ratingCount: product.reviewCount,
    },
  };

  return (
    <script
      type="application/ld+json"
      dangerouslySetInnerHTML={{ __html: JSON.stringify(schema) }}
    />
  );
}

3. Семантическая HTML разметка

// ПЛОХО: div везде
function BadArticle() {
  return (
    <div className="article">
      <div className="header">Article Title</div>
      <div className="content">Article body...</div>
      <div className="author">By John Doe</div>
      <div className="date">2024-01-15</div>
    </div>
  );
}

// ХОРОШО: Семантические теги
function GoodArticle() {
  return (
    <article>
      <header>
        <h1>Article Title</h1>
      </header>
      <main>
        <p>Article body...</p>
        <section>
          <h2>Section Title</h2>
          <p>Section content...</p>
        </section>
      </main>
      <footer>
        <p>By <span itemProp="author">John Doe</span></p>
        <time dateTime="2024-01-15">January 15, 2024</time>
      </footer>
    </article>
  );
}

4. Исправление заголовков (Heading Structure)

// ПЛОХО: Неправильная иерархия
function BadHeadings() {
  return (
    <div>
      <h1>Page Title</h1>
      <h3>Subsection (пропущен h2!)</h3>
      <h2>Another section</h2>
      <h4>Nested</h4>
    </div>
  );
}

// ХОРОШО: Правильная иерархия
function GoodHeadings() {
  return (
    <div>
      <h1>Page Title</h1>
      <section>
        <h2>Main Section</h2>
        <h3>Subsection</h3>
        <p>Content...</p>
      </section>
      <section>
        <h2>Another Section</h2>
        <p>Content...</p>
      </section>
    </div>
  );
}

5. URL структура и Canonical URLs

// В Next.js
export const metadata: Metadata = {
  // Canonical URL предотвращает дублирование
  other: {
    canonical: 'https://example.com/products/laptop',
  },
};

// Для динамических страниц
export async function generateMetadata({ params }) {
  return {
    other: {
      canonical: `https://example.com/products/${params.id}`,
    },
  };
}

// Правильные URL структуры:
// https://example.com/blog/how-to-optimize-seo/
// https://example.com/products/laptop-pro/
// https://example.com/category/electronics/

6. Robots.txt и Sitemap

// public/robots.txt
User-agent: *
Allow: /
Disallow: /admin/
Disallow: /private/
Disallow: /*.pdf$
Allow: /public/
Crawl-delay: 5

Sitemap: https://example.com/sitemap.xml

// Генерация sitemap в Next.js
// app/sitemap.ts
import { MetadataRoute } from 'next';

export default async function sitemap(): Promise<MetadataRoute.Sitemap> {
  const products = await fetch('https://example.com/api/products').then(r => r.json());
  
  const productEntries = products.map(product => ({
    url: `https://example.com/products/${product.id}`,
    lastModified: product.updatedAt,
    changeFrequency: 'weekly' as const,
    priority: 0.8,
  }));
  
  return [
    {
      url: 'https://example.com',
      lastModified: new Date(),
      changeFrequency: 'daily',
      priority: 1,
    },
    {
      url: 'https://example.com/blog',
      lastModified: new Date(),
      changeFrequency: 'weekly',
      priority: 0.9,
    },
    ...productEntries,
  ];
}

7. Image SEO оптимизация

import Image from 'next/image';

function ProductImage() {
  return (
    <>
      {/* Плохо */}
      <img src="/product.jpg" />
      
      {/* Хорошо */}
      <Image
        src="/product.jpg"
        alt="High-quality laptop with 16GB RAM and 512GB SSD"
        width={800}
        height={600}
        priority // Загружает раньше
        quality={85} // Оптимизация размера
      />
      
      {/* С figure и figcaption */}
      <figure>
        <Image
          src="/article-image.jpg"
          alt="Example of proper image optimization"
          width={1200}
          height={800}
        />
        <figcaption>Proper image optimization for SEO</figcaption>
      </figure>
    </>
  );
}

8. Core Web Vitals оптимизация

// LCP (Largest Contentful Paint)
// Оптимизируем критические ресурсы

// app/layout.tsx
import { Metadata } from 'next';

export const metadata: Metadata = {
  metadataBase: new URL('https://example.com'),
};

export default function RootLayout() {
  return (
    <html>
      <head>
        {/* Preload критических шрифтов */}
        <link
          rel="preload"
          as="font"
          href="/fonts/inter.woff2"
          type="font/woff2"
          crossOrigin="anonymous"
        />
        
        {/* Preconnect к CDN */}
        <link rel="preconnect" href="https://cdn.example.com" />
        <link rel="dns-prefetch" href="https://api.example.com" />
      </head>
      <body>{/* content */}</body>
    </html>
  );
}

// CLS (Cumulative Layout Shift)
// Зарезервировать место для изображений
function ResponsiveImage() {
  return (
    <div style={{ aspectRatio: '16/9' }}>
      <Image
        src="/image.jpg"
        alt="Example"
        fill
        style={{ objectFit: 'cover' }}
      />
    </div>
  );
}

// FID (First Input Delay)
// Избегать блокирующего JavaScript
import dynamic from 'next/dynamic';

const HeavyComponent = dynamic(() => import('./Heavy'), {
  ssr: false,
});

9. Внутренние ссылки

// Правильная внутренняя сетка ссылок

function Navigation() {
  return (
    <nav>
      <a href="/">Home</a>
      <a href="/blog">Blog</a>
      <a href="/products">Products</a>
      <a href="/contact">Contact</a>
    </nav>
  );
}

function ArticleRelated() {
  return (
    <aside>
      <h3>Related Articles</h3>
      <ul>
        <li><a href="/blog/seo-tips">SEO Tips</a></li>
        <li><a href="/blog/web-performance">Web Performance</a></li>
        <li><a href="/blog/javascript-optimization">JS Optimization</a></li>
      </ul>
    </aside>
  );
}

10. Динамическое мета-описание

// app/page.tsx
export const metadata: Metadata = {
  title: 'Best Tech Products | TechShop',
  description: 'Discover the best tech products with expert reviews. High-quality electronics at competitive prices.',
  keywords: ['tech products', 'electronics', 'gadgets', 'reviews'],
  robots: {
    index: true,
    follow: true,
    noimageindex: false,
    'max-image-preview': 'large',
    'max-snippet': -1,
    'max-video-preview': -1,
  },
};

// Для динамических страниц
export async function generateMetadata({ params }): Promise<Metadata> {
  const product = await getProduct(params.id);
  
  return {
    title: `${product.title} - Shop`,
    description: product.description.substring(0, 160),
    openGraph: {
      url: `https://example.com/products/${product.id}`,
      images: [product.image],
    },
  };
}

Ключевые моменты при внедрении SEO

  1. Мета-теги (title, description, OG теги)
  2. Структурированные данные (Schema.org JSON-LD)
  3. Семантическая HTML (правильные теги)
  4. Правильная иерархия заголовков (h1-h6)
  5. Оптимизированные изображения с alt-текстом
  6. Быстрая загрузка (Core Web Vitals)
  7. Мобильная оптимизация (responsive design)
  8. Правильные URL структуры
  9. Robots.txt и Sitemap
  10. Internal linking strategy
  11. Canonical URLs
  12. Next.js Server Components для лучшего SEO

SEO на фронтенде - это комбинация правильной разметки, производительности и следования лучшим практикам. Next.js с Server Components делает это значительно проще благодаря встроенной поддержке метаданных и SSR.

Как реализовывал SEO-требования? | PrepBro