Выберите язык

Динамическое формирование ключей кэша на границе для обеспечения SEO‑последовательности в многоязычных сайтах

Когда веб‑сайт обслуживает один и тот же контент на нескольких языках, слой edge становится критической точкой управления. Хорошо продуманная стратегия ключей кэша может мгновенно доставлять нужную языковую версию и сохранять доверие поисковых систем к сайту. В этой статье мы разберём, почему традиционные статические ключи не подходят, как работает динамическое составление ключей на границе и какие шаблоны позволяют сохранять сигналы SEO в разных регионах.

Проблема «один размер подходит всем» для ключей

Большинство CDN‑провайдеров по умолчанию используют простой хеш запрашиваемого URL. Это работает для монолитных (одноязычных) сайтов, но когда пользователь запрашивает /en/about, а другой — /fr/about, хеш отличается лишь языковым сегментом. CDN сохраняет два отдельные объекта, что, в принципе, нормально, однако такой ключ всё равно не учитывает нюансы hreflang и canonical. Поисковые системы рассматривают эти объекты как отдельные ресурсы; если одна и та же страница кэшируется под несколькими ключами без корректных сигналы, могут возникнуть штрафы за дублирующий контент, а бюджет обхода (crawl budget) будет тратиться впустую на повторную загрузку одинаковых ресурсов.

Основные компоненты многоязычного ключа кэша

Надёжный многоязычный ключ кэша обычно комбинирует следующие измерения:

  • Код языка — извлекается из пути URL, субдомена или заголовка Accept-Language.
  • Подсказка о регионе — опционально, берётся из данных GeoIP, чтобы учитывать региональные различия (валюта, единицы измерения).
  • Класс устройства — мобильный vs. десктоп, важно для адаптивного дизайна.
  • Вариативные заголовки запроса — например Accept-Encoding для gzip vs. brotli или User‑Agent для A/B‑тестов.

Эти измерения конкатенируются в детерминированном порядке и хешируются только после нормализации. В результате получается лёгкая строка, которую edge‑сервер использует для поиска, при этом полностью отражая контекст запроса.

Конвейер нормализации на границе

Прежде чем собрать ключ, edge‑функция должна нормализовать запрос:

  1. Убрать параметры слежения — удалить строки запроса utm_*, чтобы аналитические метки не фрагментировали кэш.
  2. Канонизировать путь — устранить дублирующиеся слеши, относительные сегменты (../) и завершающие слеши в соответствии с политикой URL сайта.
  3. Сопоставить алиасы языков — считать /en-us и /en эквивалентными, если сайт обслуживает одну английскую версию.
  4. Привести к нижнему регистру — URL обычно нечувствительны к регистру; принудительное приведение к нижнему устраняет лишние варианты.

Нормализованный запрос затем передаётся генератору ключа. Ниже — упрощённый пример псевдокода, который может работать в Cloudflare Workers, AWS Lambda@Edge или любой другой V8‑базированной среде edge.

// edge-key-generator.js
export async function handle(event) {
  const { request } = event;
  const url = new URL(request.url);

  // 1️⃣ Remove analytics parameters
  for (const param of url.searchParams.keys()) {
    if (param.startsWith('utm_')) url.searchParams.delete(param);
  }

  // 2️⃣ Normalize pathname
  url.pathname = decodeURI(url.pathname)
                    .replace(/\/{2,}/g, '/')
                    .replace(/\/$/, '');

  // 3️⃣ Detect language from path or header
  const langMatch = url.pathname.match(/^\/([a-z]{2})(?:-[A-Z]{2})?(?=\/|$)/);
  const language = langMatch ? langMatch[1] : request.headers.get('Accept-Language')?.split(',')[0]?.slice(0,2) || 'en';

  // 4️⃣ Build key components
  const region = request.headers.get('CF-IPCountry') || 'XX';
  const device = request.headers.get('User-Agent')?.includes('Mobile') ? 'mobile' : 'desktop';

  // 5️⃣ Assemble deterministic key
  const rawKey = `${language}|${region}|${device}|${url.pathname}`;
  const cacheKey = crypto.subtle.digest('SHA-256', new TextEncoder().encode(rawKey))
                    .then(buf => [...new Uint8Array(buf)].map(b => b.toString(16).padStart(2, '0')).join(''));

  // Attach the cache key for downstream caching logic
  request.headers.set('X-Edge-Cache-Key', await cacheKey);
  return request;
}
Вверх
© Scoutize Pty Ltd 2025. All Rights Reserved.