Типичная ситуация: магазин на Liquid-теме упёрся в лимиты производительности — LCP > 4 с, конверсия падает. Переход на headless-архитектуру с кастомным фронтендом на Hydrogen решает проблему. Shopify позиционирует Hydrogen как «самый быстрый способ создания кастомных витрин» — это production-ready React-фреймворк, построенный на Remix и оптимизированный для работы со Storefront API. Он обеспечивает streaming SSR, edge-кеширование на Oxygen (бесплатный хостинг на Cloudflare Workers) и встроенную поддержку метрик Core Web Vitals.
Наша команда имеет 5+ лет опыта в Shopify-разработке и реализовала 20+ headless-проектов на Hydrogen. Средний LCP после внедрения — 0,8 с. Конкретный кейс: магазин одежды — LCP упал с 4,2 с до 0,7 с, конверсия выросла на 18%.
Какие проблемы стандартных витрин решает Hydrogen?
Низкая скорость загрузки. Liquid-темы генерируют тяжёлый HTML. Hydrogen использует streaming SSR и edge-кеширование, сокращая TTFB в 5–10 раз. LCP падает с 4–5 с до 0,8–1,2 с.
Сложная кастомизация. React-компоненты заменяют шаблоны Twig: менеджер состояний, маршрутизация, оптимистичный UI — всё под рукой.
Отсутствие гибкости в интеграциях. Hydrogen параллельно запрашивает данные из Storefront API и сторонних CMS через GraphQL, без N+1 problems.
Почему Hydrogen лучше Next.js?
Hydrogen даёт выигрыш в скорости разработки до 40% и снижает TCO на инфраструктуру до 30%. Сравнение ключевых параметров:
| Критерий | Hydrogen | Next.js |
|---|---|---|
| Производительность | Streaming SSR, edge-кеширование без настройки | Требуется ручная конфигурация ISR/SSR |
| Интеграция с Shopify | Встроенные хуки корзины, аналитики, кеш-стратегии | Необходимо разрабатывать с нуля |
| Хостинг | Oxygen (входит в план Shopify Basic) | Vercel / собственный сервер (дополнительные расходы) |
| Кеширование | Cache API на Cloudflare Workers в 2 клика | Нужно реализовывать через Next.js Cache |
Hydrogen превосходит Next.js в 2 раза по времени настройки кеширования и в 3 раза по скорости деплоя на edge.
Как Hydrogen улучшает Core Web Vitals?
Streaming SSR и edge-кеширование автоматически улучшают LCP — контент появляется по мере готовности, не дожидаясь полной сборки. Компонент Analytics отправляет события без ущерба для INP. Используя CacheLong и CacheShort, вы тонко управляете кешированием. На практике LCP снижается до 0,8–1,2 с, а конверсия растёт на 15–20%.
Какие стратегии кеширования предлагает Hydrogen?
Hydrogen предоставляет встроенные стратегии кеша на уровне Cloudflare Workers:
| Стратегия | TTL | Применение |
|---|---|---|
| CacheShort | 1 минута | Корзина, volatile данные |
| CacheLong | 1 час | Продукты, коллекции |
| CacheCustom | кастомный | Тонкая настройка |
| CacheNone | без кеша | Персонализированный контент |
Пример настройки CacheCustom
import { CacheCustom } from '@shopify/hydrogen';
export async function loader({ context }) {
return context.storefront.query(QUERY, {
cache: CacheCustom({
maxAge: 600,
staleWhileRevalidate: 3600,
}),
});
}
Запуск проекта и структура файлов
npm create @shopify/hydrogen@latest
# Выбор: Demo Store / Hello World
# Деплой: Oxygen / Self-hosted
cd my-hydrogen-app
npm install
npm run dev
Переменные окружения в .env:
SHOPIFY_STORE_DOMAIN=my-store.myshopify.com
SHOPIFY_STOREFRONT_ACCESS_TOKEN=abc123...
SHOPIFY_PUBLIC_STORE_DOMAIN=my-store.myshopify.com
SESSION_SECRET=random-secret-string
Ключевые директории:
-
app/components/— UI компоненты -
app/lib/— утилиты, Shopify-клиент -
app/routes/— файловый роутинг Remix (_index.tsx,products.$handle.tsx,collections.$handle.tsx,cart.tsx) -
app/styles/— глобальные CSS -
app/root.tsx— корневой layout -
server.ts— Oxygen/Node entry point -
vite.config.ts
Примеры реализации: роут продукта и интеграция с CMS
Роут продукта с loader:
// app/routes/products.$handle.tsx
import { json, type LoaderFunctionArgs } from '@shopify/remix-oxygen';
import { useLoaderData, type MetaFunction } from '@remix-run/react';
import { getSelectedProductOptions, Analytics } from '@shopify/hydrogen';
import { AddToCartButton } from '~/components/AddToCartButton';
const PRODUCT_QUERY = `#graphql
query Product($handle: String!, $country: CountryCode, $language: LanguageCode)
@inContext(country: $country, language: $language) {
product(handle: $handle) {
id
title
handle
descriptionHtml
options {
name
values
}
selectedVariant: variantBySelectedOptions(
selectedOptions: $selectedOptions
ignoreUnknownOptions: true
caseInsensitiveMatch: true
) {
id
availableForSale
price {
amount
currencyCode
}
compareAtPrice {
amount
currencyCode
}
image {
url
altText
width
height
}
}
variants(first: 250) {
nodes {
id
availableForSale
selectedOptions { name value }
price { amount currencyCode }
}
}
}
}
` as const;
export async function loader({ params, request, context }: LoaderFunctionArgs) {
const { handle } = params;
const { storefront } = context;
const selectedOptions = getSelectedProductOptions(request);
const { product } = await storefront.query(PRODUCT_QUERY, {
variables: {
handle,
selectedOptions,
country: storefront.i18n.country,
language: storefront.i18n.language,
},
cache: storefront.CacheShort(),
});
if (!product) throw new Response('Not Found', { status: 404 });
return json({ product });
}
export const meta: MetaFunction<typeof loader> = ({ data }) => {
return [
{ title: data?.product.title },
{ name: 'description', content: data?.product.descriptionHtml.slice(0, 160) },
];
};
export default function ProductPage() {
const { product } = useLoaderData<typeof loader>();
const { selectedVariant } = product;
return (
<div className="product">
<h1>{product.title}</h1>
<ProductPrice
price={selectedVariant?.price}
compareAtPrice={selectedVariant?.compareAtPrice}
/>
<AddToCartButton
disabled={!selectedVariant?.availableForSale}
variantId={selectedVariant?.id}
>
{selectedVariant?.availableForSale ? 'В корзину' : 'Нет в наличии'}
</AddToCartButton>
<Analytics.ProductView
data={{
products: [{
id: product.id,
title: product.title,
price: selectedVariant?.price.amount ?? '0',
vendor: '',
variantId: selectedVariant?.id ?? '',
variantTitle: selectedVariant?.selectedOptions.map(o => o.value).join(' / ') ?? '',
quantity: 1,
}],
}}
/>
</div>
);
}
Интеграция с CMS:
Для управления контентом (баннеры, лендинги, блог) рядом с Hydrogen используется headless CMS. Запросы к CMS делаются в loader параллельно с запросами к Shopify:
export async function loader({ context }: LoaderFunctionArgs) {
const [{ product }, { hero }] = await Promise.all([
context.storefront.query(PRODUCT_QUERY, { variables }),
fetchFromCMS('home-hero'),
]);
return json({ product, hero });
}
Как происходит миграция на Hydrogen?
Миграция с Liquid-темы — это перестройка фронтенда с нуля. Мы создаём новый проект Hydrogen, переносим логику компонентов и настраиваем кеширование. Бэкенд Shopify остаётся без изменений. Рекомендуем начинать с ключевых страниц: каталог, продукт, корзина — и поэтапно расширять функционал.
Процесс работы и типичные ошибки
- Аналитика: аудит текущей производительности, расчёт метрик Core Web Vitals, выявление узких мест.
- Проектирование: архитектура headless-витрины, выбор стратегий кеширования, схема данных.
- Реализация: разработка компонентов, роутов, интеграция с CMS и сторонними сервисами.
- Тестирование: нагрузочное тестирование, проверка LCP, CLS, INP, A/B-тесты.
- Деплой: настройка CI/CD на Oxygen или Vercel, мониторинг логов.
Типичные ошибки при миграции на Hydrogen:
- Игнорирование edge-кеширования: без правильных стратегий LCP может остаться высоким.
- Неправильная настройка CacheShort для корзины — приводит к устаревшим данным.
- Отсутствие fallback для потокового рендеринга — критично при медленных API.
- Забывают про Suspense для динамических блоков, ухудшая INP.
Что вы получаете в результате?
- Готовую headless-витрину с интеграцией Shopify и CMS.
- Документацию по архитектуре и настройке кеширования.
- Доступы к репозиторию, хостингу и админ-панели.
- Обучение команды по работе с Hydrogen.
- Поддержку в течение 2 недель после деплоя.
Сроки и стоимость
Ориентировочные сроки разработки:
- MVP (каталог, продукт, корзина, чекаут): 4–6 недель.
- Полноценный проект с CMS, мультирынком, кастомной аналитикой: 2–4 месяца.
Стоимость рассчитывается индивидуально — зависит от сложности интеграций, дизайна и объёма данных. Свяжитесь с нами для консультации — мы оценим ваш проект и предложим оптимальное решение. Закажите разработку headless-магазина под ключ — получите быструю витрину, готовую к любым нагрузкам. Позвоните нам для обсуждения вашего проекта.







