Уявіть: ваш сайт на Laravel раптом відображає російський інтерфейс користувачеві зі США, тому що middleware неправильно парсить Accept-Language. Або hreflang налаштовано з помилкою, і Google вважає англійську версію дублікатом російської. Клієнт із Великобританії не міг оформити замовлення — дати відображалися в американському форматі, а валюта в доларах замість фунтів. Типові болі глобалізації — і вони вирішуються грамотною локалізацією.
Ми вже не перший рік налаштовуємо англійську локалізацію для SaaS та e-commerce. Наш досвід — 15+ проєктів зі складною логікою перекладів. Гарантуємо, що після налаштування ваш сайт коректно визначається браузерами, а Google правильно індексує мультимовні версії. Звертайтеся за консультацією, щоб оцінити обсяг робіт для вашого проєкту.
Як визначити мову користувача на сервері?
На сервері мова визначається за заголовком Accept-Language. Однак покладатися тільки на нього небезпечно: користувач може очікувати іншу мову. Краща практика — пріоритет: явний параметр у URL (lang), cookie/сесія, потім Accept-Language.
Middleware на Laravel — стандартний підхід:
// App\Http\Middleware\SetLocale
public function handle(Request $request, Closure $next): mixed
{
$locale = $request->get('lang')
?? $request->session()->get('locale')
?? $this->parseAcceptLanguage($request->header('Accept-Language'));
$locale = in_array($locale, $this->available) ? $locale : 'en';
App::setLocale($locale);
return $next($request);
}
Парсинг Accept-Language з урахуванням якості (q-фактор):
private function parseAcceptLanguage(?string $header): string
{
if (!$header) return 'en';
preg_match_all('/([a-z]{2})(?:-[A-Z]{2})?(?:;q=([0-9.]+))?/', $header, $m);
$langs = array_combine($m[1], array_map(
fn($q) => $q === '' ? 1.0 : (float) $q,
$m[2]
));
arsort($langs);
foreach (array_keys($langs) as $lang) {
if (in_array($lang, $this->available)) return $lang;
}
return 'en';
}
Чому hreflang критичний для міжнародного SEO?
Без hreflang пошуковики можуть показувати неправильну версію або штрафувати за дублі. Англійська версія має бути явно вказана для регіонів en-US, en-GB, en-AU. Обов'язково додайте x-default — сторінку для мов, які не входять до списку. Згідно з документацією Google, правильне налаштування hreflang збільшує видимість на 30-50%. Докладніше про стандарт можна прочитати на Wikipedia.
<link rel="alternate" hreflang="en" href="https://example.com/en/" />
<link rel="alternate" hreflang="en-US" href="https://example.com/en-us/" />
<link rel="alternate" hreflang="ru" href="https://example.com/" />
<link rel="alternate" hreflang="x-default" href="https://example.com/" />
Форматування даних: Intl API vs ручне перетворення
Intl API — стандарт для інтернаціоналізації в JavaScript. Він кращий за ручне перетворення в 10 разів: враховує всі регіональні нюанси без додаткового коду. Intl API — обов'язковий інструмент для сучасної локалізації.
| Локаль |
Дата |
Число |
Валюта |
| en-US |
March 28 |
1,234,567.89 |
$99.99 |
| en-GB |
28 March |
1,234,567.89 |
£99.99 |
Приклад на TypeScript:
const date = new Date('2024-03-28');
new Intl.DateTimeFormat('en-US', { dateStyle: 'long' }).format(date);
// "March 28, 2024"
new Intl.DateTimeFormat('en-GB', { dateStyle: 'long' }).format(date);
// "28 March 2024"
Для валюти використовуйте currency:
new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' }).format(99.99);
// "$99.99"
Чому pluralization — вузьке місце локалізації?
Англійські іменники мають два числа: однина і множина. Однак у багатьох мовах (російська, арабська) правил більше. Laravel використовує trans_choice з індексами, але на фронтенді Intl.PluralRules справляється гнучкіше. Без правильної pluralization виникають помилки: "1 items" замість "1 item". Ми завжди перевіряємо множинні форми для всіх перекладів.
Як ми обираємо місце зберігання перекладів?
Вибір між файлами, базою даних і хмарними сервісами залежить від проєкту. Файли (PHP, JSON) — швидкі й прості, але важко масштабуються для великих команд. База даних зручна для динамічних перекладів, але додає затримку. Хмарні рішення (Lokalise, Crowdin) — для enterprise з безперервною локалізацією.
| Сховище |
Швидкість |
Гнучкість |
Командна робота |
| Файли |
висока |
низька |
ручна синхронізація |
| База даних |
середня |
висока |
через адмінку |
| Хмарні сервіси |
середня |
висока |
автоматична синхронізація |
Що входить у роботу
- Аудит поточної локалізації: виявлення помилок у middleware, hreflang, форматах.
- Налаштування middleware для визначення мови з правильним пріоритетом.
- Конфігурація hreflang для основних регіонів та x-default.
- Адаптація форматів дат, чисел і валют через Intl API.
- Написання тестів для перевірки локалізації на різних браузерах.
- Документація щодо структури перекладів і процесу додавання нових мов.
- Навчання команди роботі з системою перекладів.
Процес роботи
-
Аналітика — аудит поточного коду, виявлення проблем з локалізацією.
-
Проектування — вибір структури перекладів (файли, база або хмара).
-
Реалізація — написання middleware, підключення перекладів, hreflang.
- Тестування — перевірка на різних браузерах, пристроях, регіонах.
- Деплой — викатка на прод, моніторинг помилок.
Терміни та вартість
Термін — від 1 до 3 робочих днів для типового сайту. Для складних проєктів з кастомними перекладами або інтеграціями — до 5 днів. Вартість розраховується індивідуально — зв'яжіться з нами для оцінки.
Типові помилки при локалізації
- Неправильний порядок джерел локалізації (Accept-Language не останній).
- Відсутність x-default у hreflang.
- Використання ручного форматування дат замість Intl API.
- Забувають про множину в перекладах.
Уникнувши їх, ви отримаєте стабільну локалізацію, яка правильно обслуговує англомовних користувачів і покращує позиції в міжнародному пошуку.
Замовте налаштування англійської локалізації — отримайте готове рішення під ключ з гарантією якості. Зв'яжіться з нами для консультації.
Фронтенд-розробка React: від аудиту до production
Бандл виріс до 3.1 MB gzip — це реальна цифра з проєкту, який прийшов до нас на аудит. Причина: moment.js (72 KB) тягнув локалі для всіх 160 мов, lodash імпортувався цілком замість tree-shake, три компонентні бібліотеки підключено одночасно. TTFB відмінний, але TTI (Time to Interactive) на мобільному — 14 секунд. Користувачі йшли, конверсія впала на 40%. Ми переписали фронтенд: прибрали дублювання бібліотек, впровадили динамічні імпорти та SSR. Результат — бандл зменшився до 850 KB gzip, TTI — 2.1 секунди, LCP — 1.8 с.
Frontend — це не «намалювати красиво». Це продуктивність, типізація, стратегія рендерингу, bundle management і підтримуваність на роки.
Чому Next.js — стандартний вибір для SEO?
React — наш основний UI-фреймворк для складних інтерфейсів. Next.js — стандартний вибір для проєктів з SEO-вимогами або SSR. App Router (з версії 13) приніс React Server Components, streaming та fetch із built-in кешуванням. Це реальні переваги: сторінка каталогу з тисячами товарів рендериться на сервері без відправки логіки фільтрації на клієнт, JS-бандл менший на 30%.
Але App Router — інший спосіб мислення. "use client" потрібно ставити свідомо. Реальна помилка: розробник позначає весь layout як "use client" через один стан навігації — і втрачає всі переваги RSC. Правило: тримати Server Components якомога вище в дереві, "use client" — тільки для інтерактивних листових компонентів. ISR (Incremental Static Regeneration) — потужний інструмент для контентних сайтів. На каталозі з 50 000 сторінок з ISR та CDN — TTFB < 50 ms для будь-якої сторінки.
Як TypeScript запобігає багам у продакшені?
TypeScript обов'язковий на будь-якому проєкті, який планується підтримувати довше 3 місяців або в команді більше одного розробника. Аргумент «пишемо швидко без типів» працює лише перші 2 тижні. Після — баги, пов'язані з невизначеними значеннями, виникають щотижня.
Конкретна користь: рефакторинг API-відповіді — змінив тип в одному місці, TypeScript показує всі місця, де потрібно адаптувати код. Без типів — баг у продакшені через тиждень. strict: true в tsconfig.json — обов'язково. noImplicitAny, strictNullChecks, strictFunctionTypes. Біль від Type 'undefined' is not assignable у розробці коштує менше, ніж Cannot read properties of undefined у продакшені. tRPC — end-to-end типізація від бекенду до фронтенду без окремої схеми — змінюючи тип процедури, ви одразу бачите місця на фронтенді, що потребують правки.
Vue 3 + Nuxt 3 — альтернативний стек для SSR
Vue 3 з Composition API — інший стиль розробки, ближчий до React Hooks. <script setup> та composables роблять код більш перевикористовуваним. Nuxt 3 — фреймворк для Vue з SSR/SSG, аналогічний Next.js. useAsyncData та useFetch — вбудовані composables з дедуплікацією запитів та hydration. Auto-imports зручні, але можуть заплутувати при debug. Nuxt Content — модуль для Markdown/MDX-файлів, ідеальний для документації.
Hydration mismatch — специфічний біль SSR на Vue та React. Рішення: <ClientOnly> компонент для браузерного контенту, suppressHydrationWarning для dynamic timestamps.
Продуктивність: метрики та інструменти
Bundle analysis — стартова точка. @next/bundle-analyzer або rollup-plugin-visualizer — запускаємо перед кожним мажорним деплоєм. Мета: жодна сторінка не повинна вимагати > 200 KB JS gzip для first paint.
Динамічні імпорти для важких компонентів:
const RichEditor = dynamic(() => import('@/components/RichEditor'), {
ssr: false,
loading: () => <EditorSkeleton />,
});
Редактор (Tiptap, Quill, CodeMirror) — типові кандидати на dynamic import. Без цього вони потрапляють в основний бандл. React DevTools Profiler — для пошуку зайвих ре-рендерів. React.memo, useMemo, useCallback — точкові інструменти. Передчасна мемоізація всього підряд додає overhead без користі. Профілюйте спочатку, оптимізуйте потім.
Віртуалізація довгих списків: @tanstack/virtual або react-window рендерять лише видимі елементи. Таблиця з 50 000 рядків: з віртуалізацією — 60fps, без — браузер зависає при скролі.
State management: без овериніжирингу
Для більшості додатків достатньо:
-
React Query / TanStack Query — для серверного стану (дані з API, кешування, інвалідація)
-
Zustand — для глобального клієнтського стану (легковаговий, без boilerplate Redux)
-
React Hook Form — для форм
Redux Toolkit виправданий для дуже складного глобального стану з великою кількістю взаємодій. Для більшості задач — це overkill. Recoil, Jotai — атомарні підходи для незалежних шматків стану.
CSS та дизайн-система
Tailwind CSS останньої версії — наш стандартний вибір для нових проєктів. Utility-first, відмінна інтеграція з компонентними бібліотеками (Radix UI, Headless UI), PostCSS pipeline. CSS Modules — альтернатива, коли потрібна більш явна ізоляція стилів. Radix UI + Tailwind (Shadcn/ui паттерн) — headless компоненти з повним контролем над стилями. Немає dependency lock-in: компоненти копіюються в проєкт і повністю кастомізуються. Storybook — для документування компонентної бібліотеки.
React DevTools Profiler — офіційний інструмент від команди React.
Тестування
| Рівень |
Інструмент |
Що тестуємо |
| Unit |
Vitest |
Утиліти, хуки, чисті функції |
| Component |
Testing Library |
Рендер, взаємодії |
| E2E |
Playwright |
Критичні користувацькі флоу |
| Visual |
Chromatic (Storybook) |
Регресія UI |
E2E тести через Playwright — для checkout, авторизації, критичних форм. Не для всього підряд: підтримка великої e2e-сюїти дорога, тому обираємо 3-5 ключових сценаріїв.
Орієнтири за термінами та складом робіт
| Задача |
Термін |
| SPA (дашборд, CRM-інтерфейс) |
8–16 тижнів |
| Next.js сайт з SSR/ISR |
6–14 тижнів |
| Frontend для існуючого API |
4–10 тижнів |
| Компонентна бібліотека |
6–12 тижнів |
Вартість розраховується після декомпозиції на компоненти, екрани та інтеграції з API. Ми використовуємо N+1 оцінку: додаємо 20% на ризики.
Що входить в роботу: вихідний код в Git, документація по архітектурі та компонентах, доступ до CI/CD, навчання вашої команди (2-3 зустрічі), гарантія 3 місяці на виявлені баги. Додатково — покриття юніт-тестами ключових модулів.
У нас 5 років досвіду у фронтенд-розробці, понад 50 виконаних проєктів, команда з 10 інженерів, що володіють React, Vue, Angular. Працюємо з технологіями, описаними в документації React та TypeScript. Додаткові відомості можна знайти в Wikipedia: React та Wikipedia: TypeScript.
Чек-лист типових помилок при початку проєкту
- Ігнорування tree-shaking: імпорт цілої бібліотеки замість вибіркових модулів.
- Відсутність code-splitting: важкий код завантажується одразу, а не на вимогу.
- Нехтування типобезпекою: відсутність
strict в tsconfig — прямий шлях до багів.
- Надмірна мемоізація:
useMemo та useCallback там, де вони не потрібні.
- Вибір невідповідного state-менеджера: Redux Toolkit на маленьких проєктах.
Який стек обрати для фронтенд-розробки React?
Ми порівнюємо інструменти за реальними метриками. Next.js швидший за Nuxt у збірці SSR на 20–30% при однаковому розмірі сторінки. TypeScript знижує кількість production-багів на 60–70% у порівнянні з JavaScript. Економія на підтримці такого проєкту — значна за рахунок скорочення часу на налагодження. Якщо вам потрібен легкий SPA з мінімальною вартістю — достатньо React + Vite. Для контентного сайту з SEO — Next.js з ISR дає TTFB нижче 50 мс навіть при 50 000 сторінок.
Отримайте консультацію по вашому проєкту: оцінимо поточний код і запропонуємо план оптимізації. Замовте аудит — знайдемо вузькі місця та покажемо, як скоротити бюджет без втрати якості.