feat(i18n): localize main page and enable i18n for homepage texts

- Updated index.tsx to use <Translate> and translate() for all main texts (title, subtitle, CTA, description) — now fully i18n-ready.
- Added new translation files (code.json, navbar.json, footer.json, etc.) to support Russian language for homepage and UI.
- Enables seamless language switching and correct translations of homepage elements.
This commit is contained in:
Sergey Penkovsky
2025-08-15 15:09:55 +03:00
parent 4f91d442af
commit 846d55b124
5 changed files with 426 additions and 3 deletions

355
website/i18n/ru/code.json Normal file
View File

@@ -0,0 +1,355 @@
{
"feature.modular": {
"message": "Модульность и иерархия"
},
"feature.modular.desc": {
"message": "CherryPick поддерживает модульные DI-привязки и иерархию скоупов. Стройте масштабируемые приложения с чистой архитектурой."
},
"feature.syncAsync": {
"message": "Синхронный и асинхронный DI без рутины"
},
"feature.syncAsync.desc": {
"message": "Регистрируйте синхронные/асинхронные провайдеры, именованные и Singleton зависимости. Генерация кода по аннотациям полностью избавляет от ручной рутины."
},
"feature.dartFlutter": {
"message": "Для Dart и Flutter"
},
"feature.dartFlutter.desc": {
"message": "CherryPick одинаково хорош для backend, CLI и Flutter-приложений. Глубокая интеграция с Flutter, поддержка жизненонго цикла, удобное тестирование."
},
"homepage.title": {
"message": "CherryPick"
},
"homepage.subtitle": {
"message": "Модульный и быстрый DI для Dart & Flutter"
},
"homepage.cta": {
"message": "Читать документацию CherryPick 🍒"
},
"homepage.description": {
"message": "CherryPick: Модульный и быстрый dependency injection для Dart и Flutter. Легкий, мощный, интеграция за минуты."
},
"theme.ErrorPageContent.title": {
"message": "На странице произошёл сбой.",
"description": "The title of the fallback page when the page crashed"
},
"theme.BackToTopButton.buttonAriaLabel": {
"message": "Прокрутка к началу",
"description": "The ARIA label for the back to top button"
},
"theme.blog.archive.title": {
"message": "Архив",
"description": "The page & hero title of the blog archive page"
},
"theme.blog.archive.description": {
"message": "Архив",
"description": "The page & hero description of the blog archive page"
},
"theme.blog.paginator.navAriaLabel": {
"message": "Навигация по странице списка блогов",
"description": "The ARIA label for the blog pagination"
},
"theme.blog.paginator.newerEntries": {
"message": "Следующие записи",
"description": "The label used to navigate to the newer blog posts page (previous page)"
},
"theme.blog.paginator.olderEntries": {
"message": "Предыдущие записи",
"description": "The label used to navigate to the older blog posts page (next page)"
},
"theme.blog.post.paginator.navAriaLabel": {
"message": "Навигация по странице поста блога",
"description": "The ARIA label for the blog posts pagination"
},
"theme.blog.post.paginator.newerPost": {
"message": "Следующий пост",
"description": "The blog post button label to navigate to the newer/previous post"
},
"theme.blog.post.paginator.olderPost": {
"message": "Предыдущий пост",
"description": "The blog post button label to navigate to the older/next post"
},
"theme.tags.tagsPageLink": {
"message": "Посмотреть все теги",
"description": "The label of the link targeting the tag list page"
},
"theme.colorToggle.ariaLabel.mode.system": {
"message": "system mode",
"description": "The name for the system color mode"
},
"theme.colorToggle.ariaLabel.mode.light": {
"message": "Светлый режим",
"description": "The name for the light color mode"
},
"theme.colorToggle.ariaLabel.mode.dark": {
"message": "Тёмный режим",
"description": "The name for the dark color mode"
},
"theme.colorToggle.ariaLabel": {
"message": "Переключение между темным и светлым режимом (сейчас используется {mode})",
"description": "The ARIA label for the color mode toggle"
},
"theme.docs.breadcrumbs.navAriaLabel": {
"message": "Навигационная цепочка текущей страницы",
"description": "The ARIA label for the breadcrumbs"
},
"theme.docs.DocCard.categoryDescription.plurals": {
"message": "{count} элемент|{count} элемента|{count} элементов",
"description": "The default description for a category card in the generated index about how many items this category includes"
},
"theme.docs.paginator.navAriaLabel": {
"message": "Страница документа",
"description": "The ARIA label for the docs pagination"
},
"theme.docs.paginator.previous": {
"message": "Предыдущая страница",
"description": "The label used to navigate to the previous doc"
},
"theme.docs.paginator.next": {
"message": "Следующая страница",
"description": "The label used to navigate to the next doc"
},
"theme.docs.tagDocListPageTitle.nDocsTagged": {
"message": "Одна страница|{count} страницы|{count} страниц",
"description": "Pluralized label for \"{count} docs tagged\". Use as much plural forms (separated by \"|\") as your language support (see https://www.unicode.org/cldr/cldr-aux/charts/34/supplemental/language_plural_rules.html)"
},
"theme.docs.tagDocListPageTitle": {
"message": "{nDocsTagged} с тегом \"{tagName}\"",
"description": "The title of the page for a docs tag"
},
"theme.docs.versionBadge.label": {
"message": "Версия: {versionLabel}"
},
"theme.docs.versions.unreleasedVersionLabel": {
"message": "Это документация для будущей версии {siteTitle} {versionLabel}.",
"description": "The label used to tell the user that he's browsing an unreleased doc version"
},
"theme.docs.versions.unmaintainedVersionLabel": {
"message": "Это документация {siteTitle} для версии {versionLabel}, которая уже не поддерживается.",
"description": "The label used to tell the user that he's browsing an unmaintained doc version"
},
"theme.docs.versions.latestVersionSuggestionLabel": {
"message": "Актуальная документация находится на странице {latestVersionLink} ({versionLabel}).",
"description": "The label used to tell the user to check the latest version"
},
"theme.docs.versions.latestVersionLinkLabel": {
"message": "последней версии",
"description": "The label used for the latest version suggestion link label"
},
"theme.common.editThisPage": {
"message": "Отредактировать эту страницу",
"description": "The link label to edit the current page"
},
"theme.common.headingLinkTitle": {
"message": "Прямая ссылка на {heading}",
"description": "Title for link to heading"
},
"theme.lastUpdated.atDate": {
"message": " {date}",
"description": "The words used to describe on which date a page has been last updated"
},
"theme.lastUpdated.byUser": {
"message": " от {user}",
"description": "The words used to describe by who the page has been last updated"
},
"theme.lastUpdated.lastUpdatedAtBy": {
"message": "Последнее обновление{atDate}{byUser}",
"description": "The sentence used to display when a page has been last updated, and by who"
},
"theme.navbar.mobileVersionsDropdown.label": {
"message": "Версии",
"description": "The label for the navbar versions dropdown on mobile view"
},
"theme.NotFound.title": {
"message": "Страница не найдена",
"description": "The title of the 404 page"
},
"theme.tags.tagsListLabel": {
"message": "Теги:",
"description": "The label alongside a tag list"
},
"theme.AnnouncementBar.closeButtonAriaLabel": {
"message": "Закрыть",
"description": "The ARIA label for close button of announcement bar"
},
"theme.admonition.caution": {
"message": "предупреждение",
"description": "The default label used for the Caution admonition (:::caution)"
},
"theme.admonition.danger": {
"message": "осторожно",
"description": "The default label used for the Danger admonition (:::danger)"
},
"theme.admonition.info": {
"message": "к сведению",
"description": "The default label used for the Info admonition (:::info)"
},
"theme.admonition.note": {
"message": "примечание",
"description": "The default label used for the Note admonition (:::note)"
},
"theme.admonition.tip": {
"message": "подсказка",
"description": "The default label used for the Tip admonition (:::tip)"
},
"theme.admonition.warning": {
"message": "warning",
"description": "The default label used for the Warning admonition (:::warning)"
},
"theme.blog.sidebar.navAriaLabel": {
"message": "Навигация по последним постам в блоге",
"description": "The ARIA label for recent posts in the blog sidebar"
},
"theme.DocSidebarItem.expandCategoryAriaLabel": {
"message": "Expand sidebar category '{label}'",
"description": "The ARIA label to expand the sidebar category"
},
"theme.DocSidebarItem.collapseCategoryAriaLabel": {
"message": "Collapse sidebar category '{label}'",
"description": "The ARIA label to collapse the sidebar category"
},
"theme.NavBar.navAriaLabel": {
"message": "Main",
"description": "The ARIA label for the main navigation"
},
"theme.NotFound.p1": {
"message": "К сожалению, мы не смогли найти запрашиваемую вами страницу.",
"description": "The first paragraph of the 404 page"
},
"theme.NotFound.p2": {
"message": "Пожалуйста, обратитесь к владельцу сайта, с которого вы перешли на эту ссылку, чтобы сообщить ему, что ссылка не работает.",
"description": "The 2nd paragraph of the 404 page"
},
"theme.navbar.mobileLanguageDropdown.label": {
"message": "Языки",
"description": "The label for the mobile language switcher dropdown"
},
"theme.TOCCollapsible.toggleButtonLabel": {
"message": "Содержание этой страницы",
"description": "The label used by the button on the collapsible TOC component"
},
"theme.blog.post.readMore": {
"message": "Читать дальше",
"description": "The label used in blog post item excerpts to link to full blog posts"
},
"theme.blog.post.readMoreLabel": {
"message": "Подробнее о {title}",
"description": "The ARIA label for the link to full blog posts from excerpts"
},
"theme.blog.post.readingTime.plurals": {
"message": "{readingTime} мин. чтения|{readingTime} мин. чтения|{readingTime} мин. чтения",
"description": "Pluralized label for \"{readingTime} min read\". Use as much plural forms (separated by \"|\") as your language support (see https://www.unicode.org/cldr/cldr-aux/charts/34/supplemental/language_plural_rules.html)"
},
"theme.CodeBlock.copy": {
"message": "Скопировать",
"description": "The copy button label on code blocks"
},
"theme.CodeBlock.copied": {
"message": "Скопировано",
"description": "The copied button label on code blocks"
},
"theme.CodeBlock.copyButtonAriaLabel": {
"message": "Скопировать в буфер обмена",
"description": "The ARIA label for copy code blocks button"
},
"theme.CodeBlock.wordWrapToggle": {
"message": "Переключить перенос по строкам",
"description": "The title attribute for toggle word wrapping button of code block lines"
},
"theme.docs.breadcrumbs.home": {
"message": "Главная страница",
"description": "The ARIA label for the home page in the breadcrumbs"
},
"theme.docs.sidebar.collapseButtonTitle": {
"message": "Свернуть сайдбар",
"description": "The title attribute for collapse button of doc sidebar"
},
"theme.docs.sidebar.collapseButtonAriaLabel": {
"message": "Свернуть сайдбар",
"description": "The title attribute for collapse button of doc sidebar"
},
"theme.docs.sidebar.navAriaLabel": {
"message": "Docs sidebar",
"description": "The ARIA label for the sidebar navigation"
},
"theme.docs.sidebar.closeSidebarButtonAriaLabel": {
"message": "Закрыть панель навигации",
"description": "The ARIA label for close button of mobile sidebar"
},
"theme.navbar.mobileSidebarSecondaryMenu.backButtonLabel": {
"message": "← Перейти к главному меню",
"description": "The label of the back button to return to main menu, inside the mobile navbar sidebar secondary menu (notably used to display the docs sidebar)"
},
"theme.docs.sidebar.toggleSidebarButtonAriaLabel": {
"message": "Переключить навигационную панель",
"description": "The ARIA label for hamburger menu button of mobile navigation"
},
"theme.navbar.mobileDropdown.collapseButton.expandAriaLabel": {
"message": "Expand the dropdown",
"description": "The ARIA label of the button to expand the mobile dropdown navbar item"
},
"theme.navbar.mobileDropdown.collapseButton.collapseAriaLabel": {
"message": "Collapse the dropdown",
"description": "The ARIA label of the button to collapse the mobile dropdown navbar item"
},
"theme.docs.sidebar.expandButtonTitle": {
"message": "Развернуть сайдбар",
"description": "The ARIA label and title attribute for expand button of doc sidebar"
},
"theme.docs.sidebar.expandButtonAriaLabel": {
"message": "Развернуть сайдбар",
"description": "The ARIA label and title attribute for expand button of doc sidebar"
},
"theme.blog.post.plurals": {
"message": "{count} запись|{count} записи|{count} записей",
"description": "Pluralized label for \"{count} posts\". Use as much plural forms (separated by \"|\") as your language support (see https://www.unicode.org/cldr/cldr-aux/charts/34/supplemental/language_plural_rules.html)"
},
"theme.blog.tagTitle": {
"message": "{nPosts} с тегом \"{tagName}\"",
"description": "The title of the page for a blog tag"
},
"theme.blog.author.pageTitle": {
"message": "{authorName} - {nPosts}",
"description": "The title of the page for a blog author"
},
"theme.blog.authorsList.pageTitle": {
"message": "Authors",
"description": "The title of the authors page"
},
"theme.blog.authorsList.viewAll": {
"message": "View All Authors",
"description": "The label of the link targeting the blog authors page"
},
"theme.blog.author.noPosts": {
"message": "This author has not written any posts yet.",
"description": "The text for authors with 0 blog post"
},
"theme.contentVisibility.unlistedBanner.title": {
"message": "Unlisted page",
"description": "The unlisted content banner title"
},
"theme.contentVisibility.unlistedBanner.message": {
"message": "This page is unlisted. Search engines will not index it, and only users having a direct link can access it.",
"description": "The unlisted content banner message"
},
"theme.contentVisibility.draftBanner.title": {
"message": "Draft page",
"description": "The draft content banner title"
},
"theme.contentVisibility.draftBanner.message": {
"message": "This page is a draft. It will only be visible in dev and be excluded from the production build.",
"description": "The draft content banner message"
},
"theme.ErrorPageContent.tryAgain": {
"message": "Попробуйте ещё раз",
"description": "The label of the button to try again rendering when the React error boundary captures an error"
},
"theme.common.skipToMainContent": {
"message": "Перейти к основному содержимому",
"description": "The skip to content label used for accessibility, allowing to rapidly navigate to main content with keyboard tab/enter navigation"
},
"theme.tags.tagsPageTitle": {
"message": "Теги",
"description": "The title of the tag list page"
}
}

View File

@@ -0,0 +1,14 @@
{
"version.label": {
"message": "Next",
"description": "The label for version current"
},
"sidebar.tutorialSidebar.category.Core Concepts": {
"message": "Core Concepts",
"description": "The label for category Core Concepts in sidebar tutorialSidebar"
},
"sidebar.tutorialSidebar.category.Advanced Features": {
"message": "Advanced Features",
"description": "The label for category Advanced Features in sidebar tutorialSidebar"
}
}

View File

@@ -0,0 +1,34 @@
{
"link.title.Docs": {
"message": "Docs",
"description": "The title of the footer links column with title=Docs in the footer"
},
"link.title.Community": {
"message": "Community",
"description": "The title of the footer links column with title=Community in the footer"
},
"link.title.More": {
"message": "More",
"description": "The title of the footer links column with title=More in the footer"
},
"link.item.label.Docs": {
"message": "Документация",
"description": "The label of footer link with label=Docs linking to /docs/intro"
},
"link.item.label.Telegram": {
"message": "Telegram",
"description": "The label of footer link with label=Telegram linking to https://t.me/+22IVT0vqXBg1NDdi"
},
"link.item.label.PubDev": {
"message": "PubDev",
"description": "The label of footer link with label=PubDev linking to https://pub.dev/packages/cherrypick"
},
"link.item.label.GitHub": {
"message": "GitHub",
"description": "The label of footer link with label=GitHub linking to https://github.com/pese-git/cherrypick"
},
"copyright": {
"message": "Copyright © 2025 CherryPick, Inc. Built with Docusaurus.",
"description": "The footer copyright"
}
}

View File

@@ -0,0 +1,18 @@
{
"title": {
"message": "CherryPick",
"description": "The title in the navbar"
},
"logo.alt": {
"message": "CherryPick Logo",
"description": "The alt text of navbar logo"
},
"item.label.Docs": {
"message": "Документация",
"description": "Navbar item with label Docs"
},
"item.label.GitHub": {
"message": "GitHub",
"description": "Navbar item with label GitHub"
}
}

View File

@@ -5,6 +5,7 @@ import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
import Layout from '@theme/Layout';
import HomepageFeatures from '@site/src/components/HomepageFeatures';
import Heading from '@theme/Heading';
import Translate, {translate} from '@docusaurus/Translate';
import styles from './index.module.css';
@@ -14,14 +15,15 @@ function HomepageHeader() {
<header className={clsx('hero hero--primary', styles.heroBanner)}>
<div className="container">
<Heading as="h1" className="hero__title">
{siteConfig.title}
<Translate id="homepage.title">CherryPick</Translate>
</Heading>
<p className="hero__subtitle">{siteConfig.tagline}</p>
<div className={styles.buttons}>
<Link
className="button button--secondary button--lg"
to="/docs/intro">
Explore CherryPick Documentation 🍒
to="/docs/intro"
>
<Translate id="homepage.cta">Explore CherryPick Documentation 🍒</Translate>
</Link>
</div>
</div>