Создание по-настоящему интернационального веб-приложения - задача не из простых. Особенно когда речь заходит о правильной настройке SEO для разных языковых версий. Сегодня мы разберём, как грамотно внедрить поддержку hreflang в приложение на Next.js с помощью getServerSideProps.
Почему это важно?
Представьте: вы создали отличное приложение, которое работает на нескольких языках. Но поисковики почему-то путаются в версиях, а пользователи из разных стран не всегда попадают на страницы на своём родном языке. Знакомая ситуация?
Атрибут hreflang как раз и решает эту проблему. Он говорит поисковым системам, какая версия страницы предназначена для какого языка или региона. Давайте разберёмся, как правильно его внедрить в Next.js-приложение.
Основы работы с hreflang
Начнём с простого примера. Допустим, у нас есть страница, доступная на трёх языках:
html<link rel="alternate" hreflang="en" href="https://example.com/en" />
<link rel="alternate" hreflang="es" href="https://example.com/es" />
<link rel="alternate" hreflang="ru" href="https://example.com/ru" />
Эти строки говорят поисковикам: "Эй, у этой страницы есть версии на английском, испанском и русском языках, и вот где их найти!"
Реализация в Next.js
В Next.js мы можем добавить поддержку hreflang через getServerSideProps. Это позволит динамически генерировать правильные ссылки для каждой страницы. Вот как это можно сделать:
export async function getServerSideProps(context) {
const { locale } = context;
const supportedLocales = ['en', 'es', 'ru'];
const hreflangLinks = supportedLocales.map(lang => ({
rel: 'alternate',
hreflang: lang,
href: `https://example.com/${lang}${context.resolvedUrl}`
}));
return {
props: {
hreflangLinks
}
};
}
А теперь давайте добавим эти ссылки в head секцию нашего приложения:
jsximport Head from 'next/head';
function Page({ hreflangLinks }) {
return (
<>
<Head>
{hreflangLinks.map(({ rel, hreflang, href }) => (
<link key={hreflang} rel={rel} hreflang={hreflang} href={href} />
))}
</Head>
{/* Остальной контент страницы */}
</>
);
}
Продвинутые техники
Иногда нам нужно учитывать не только язык, но и регион. Например, разные версии английского для США и Великобритании:
const localeConfig = {
'en-US': {
hreflang: 'en-us',
defaultForLanguage: true
},
'en-GB': {
hreflang: 'en-gb'
}
};
Также полезно добавить x-default для случаев, когда нет подходящей языковой версии:
const hreflangLinks = [
...supportedLocales.map(/* ... */),
{
rel: 'alternate',
hreflang: 'x-default',
href: `https://example.com/en${context.resolvedUrl}`
}
];
Обработка ошибок и edge cases
При работе с мультиязычностью всегда найдутся особые случаи. Давайте рассмотрим типичные проблемы и их решения:
1. Отсутствующие переводы:const checkTranslationExists = async (locale, path) => {
// Проверяем наличие перевода
return true; // Ваша логика проверки
};
const getValidHreflangLinks = async (locales, path) => {
const links = [];
for (const locale of locales) {
if (await checkTranslationExists(locale, path)) {
links.push({
rel: 'alternate',
hreflang: locale,
href: `https://example.com/${locale}${path}`
});
}
}
return links;
};
2. Канонические URL:
jsx
<Head>
<link
rel="canonical"
href={`https://example.com/${currentLocale}${currentPath}`}
/>
{/* hreflang links */}
</Head>
Тестирование реализации
Крайне важно проверить работу hreflang на реальных сценариях:
describe('Hreflang implementation', () => {
it('generates correct links for all supported locales', async () => {
const { props } = await getServerSideProps({
locale: 'en',
resolvedUrl: '/about'
});
expect(props.hreflangLinks).toContainEqual({
rel: 'alternate',
hreflang: 'en',
href: 'https://example.com/en/about'
});
});
});
Оптимизация производительности
Генерация hreflang-ссылок может влиять на производительность, особенно при большом количестве языков. Вот несколько советов по оптимизации:
1. Кэширование результатов:const cache = new Map();
const getCachedHreflangLinks = (key, generator) => {
if (!cache.has(key)) {
cache.set(key, generator());
}
return cache.get(key);
};
2. Параллельная обработка:const generateHreflangLinks = async (locales, path) => {
const linkPromises = locales.map(async locale => ({
rel: 'alternate',
hreflang: locale,
href: await generateLocalizedUrl(locale, path)
}));
return Promise.all(linkPromises);
};
Заключение
Правильная реализация hreflang - это важный шаг к созданию качественного мультиязычного приложения. Используя getServerSideProps в Next.js, мы можем гибко и эффективно управлять языковыми версиями наших страниц.
Помните о тестировании реализации и мониторинге её работы в production. Регулярно проверяйте отчёты в Google Search Console и других инструментах, чтобы убедиться, что поисковые системы правильно понимают структуру ваших языковых версий.
А как вы решаете задачи мультиязычности в своих проектах? Возможно, у вас есть свои интересные находки и решения?