Senior Frontend Architect, 10+ лет опыта построения production-проектов на Next.js. Contentful Certified Professional (2024). Специализация: React Server Components, headless eCommerce, инженерия Core Web Vitals.
Headless Shopify на Next.js стал основной архитектурой для быстрой электронной коммерции в 2026 году - не потому что он проще, а потому что отвязывает слой рендеринга и SEO от ограничений платформы Shopify так, что это даёт измеримо лучшие Core Web Vitals и конверсию. В этом гайде я разбираю три вещи, которые большинство туториалов пропускает: полную поверхность API Shopify - все три уровня (Storefront API, Admin API, Customer Account API), их модели аутентификации, лимиты запросов и контракты пагинации; слой данных Next.js App Router - как RSC, Data Cache и generateStaticParams убирают клиентские водопады запросов на каталожных страницах; и модель границ состояния - что относится к серверным компонентам, чему нужен 'use client' и какие именно механизмы (хранение корзины в куке, OAuth PKCE, оптимистичные обновления) заставляют интерактивный слой работать. Всё это основано на продакшен-паттернах из международных eCommerce-проектов, включая мультивитринные развёртывания Shopify Plus.
Часть I - Поверхность API Shopify: три уровня, три разных контракта
Самая частая архитектурная ошибка в headless-проектах на Shopify - считать Storefront API «тем самым API Shopify» и полностью игнорировать Admin API и более новый Customer Account API. Для корректной продакшен-архитектуры нужно понимать все три.
- Storefront API (GraphQL, публичный): Эндпоинт
https://{shop}.myshopify.com/api/{version}/graphql.json. Аутентификация через заголовокX-Shopify-Storefront-Access-Token- токен с правами на чтение витрины. Лимиты стоимостные: у каждого поля GraphQL свой вес; бюджет одного запроса - 1000 единиц стоимости; корзина лимитов на уровне магазина пополняется на 500 единиц в секунду. Запрос 250 узлов товаров по 4 поля каждый стоит ровно 1000 единиц - максимум за один раз. Это вынуждает использовать курсорную пагинацию (first: N,after: $cursor), а не смещения. Shopify фиксирует версии API:2024-10,2025-01,2025-04- квартальные релизы. Каждая версия поддерживается 12 месяцев, ломающие изменения появляются только в новых. Версию нужно фиксировать явно:unstableдля продакшена не годится. - Admin API (GraphQL и REST, приватный): Полное управление магазином: остатки, отгрузка заказов, запись данных покупателей, метаполя, вебхуки. Аутентификация через
X-Shopify-Access-Token(приватное приложение) или сессионный токен OAuth (кастомное приложение). Никогда не отдавайте учётные данные Admin API в браузер. Admin API живёт исключительно в Route Handlers Next.js или в серверных утилитах заimport 'server-only'. Лимиты: дырявое ведро, 40 запросов в секунду на приложение для REST; 1000 единиц стоимости на запрос для GraphQL с пополнением 500 в секунду - пропускная способность выше, чем у Storefront API при том же размере ведра. - Customer Account API (OAuth 2.0, с 2024): В середине 2024 года Shopify объявил устаревшими прежние мутации покупателей в Storefront API (
customerCreate,customerAccessTokenCreate,customerRecover). Замена - Customer Account API, отдельный сервис OAuth 2.0 по адресуshopify.com/authentication/{shop-id}. Он использует поток PKCE (Proof Key for Code Exchange, RFC 7636) для публичных клиентов, включая браузер и SSR, выдаёт короткоживущие токены доступа (час) с refresh-токенами (скоуп офлайн-доступа) и открывает отдельные GraphQL-запросы для заказов, адресов и управления аккаунтом. Любая новая headless-реализация в 2026 году обязана использовать именно его: старые мутации выключены.
Фиксация версии API на практике: В слое данных версия задаётся одной константой и используется везде: const SHOPIFY_API_VERSION = '2025-01'. Она подставляется сегментом пути в каждый вызов. Когда Shopify выпускает новую квартальную версию, вы запускаете npx @shopify/api-codegen@latest против её схемы, просматриваете диффы сгенерированных типов TypeScript, обновляете константу и проверяете на стенде. Это правильная церемония обновления. unstable в продакшене недопустим: между ежедневными сборками там бывают ломающие изменения.
Часть II - Слой данных: типизированный GraphQL с кодогенерацией
Голые вызовы fetch со строками GraphQL прямо в коде - вторая по частоте архитектурная ошибка в headless-проектах на Shopify. Проблема не в эргономике, а в корректности. Ответы GraphQL не типизированы; изменение в API Shopify, которое переименует поле или сменит тип, молча даст undefined в продакшене без единого сигнала на этапе компиляции. Правильная архитектура генерирует типы TypeScript из схемы Shopify.
- Инструменты:
@graphql-codegen/cliплюс@graphql-codegen/typescript,@graphql-codegen/typescript-operationsи@shopify/api-codegen-preset. Пресет скачивает схему Storefront API для вашей зафиксированной версии и генерирует типы для всех файлов операций.graphql. Командаnpm run codegenв CI - и типы всегда совпадают с заявленной версией схемы. - Стратегия фрагментов: Опишите переиспользуемые фрагменты под формы данных, которые потребляют компоненты:
fragment ProductCardFields on Product { id handle title featuredImage { url altText } priceRange { minVariantPrice { amount currencyCode } } }. Запросы карточки товара собираются из этого фрагмента плюс расширенные поля. Так вы избегаете расползания запросов, когда PDP и PLP независимо описывают чуть разные формы товара, а пропсы компонентов начинают расходиться. - Слой данных только для сервера: Все функции обращения к Shopify живут в
lib/shopify/сimport 'server-only'в начале индексного файла. Это не даёт случайно затащить серверные утилиты с ключами API в клиентские компоненты: TypeScript уронит сборку на любом нарушении границы импорта. - Токен приватного приложения и переменные окружения:
process.env.SHOPIFY_STOREFRONT_ACCESS_TOKEN- единственное место, где живёт токен. В App Router переменные окружения без префиксаNEXT_PUBLIC_серверные: в клиентский JS они не попадают никогда. Это граница безопасности, которую фреймворк обеспечивает на уровне сборщика, а не соглашением.
Часть III - Архитектура каталога: generateStaticParams и ISR
Каталог - страницы товаров (PDP) и страницы коллекций (PLP) - самая посещаемая и самая чувствительная к скорости поверхность любой витрины. В headless-реализации на App Router правильная архитектура пререндерит все каталожные страницы на сборке через generateStaticParams, а свежесть обеспечивает ISR (инкрементальная статическая регенерация). Это убирает серверный round-trip на каждый просмотр, отдаёт готовый HTML прямо с края CDN и стабильно даёт LCP ниже 1,2 секунды на p75 для страниц из кеша.
- generateStaticParams для PDP:
export async function generateStaticParams() { const products = await getAllProductHandles(); return products.map((handle) => ({ handle })); }. ФункцияgetAllProductHandles()листает Storefront API курсорной пагинацией:products(first: 250, after: $cursor) { edges { node { handle } } pageInfo { hasNextPage endCursor } }. Для каталога на 5000 товаров это 20 запросов - один раз на сборке, а не на каждый показ страницы. - Настройка ISR:
export const revalidate = 3600;на уровне сегмента маршрута перегенерирует страницу в фоне, когда закешированный ответ старше часа. Изменения цены и остатков в Shopify доезжают в течение часа. Для страниц, критичных по остаткам (флеш-распродажи, ограниченные партии), снижайте доrevalidate = 300и добавляйте ревалидацию по требованию: вебхук → Route Handler →revalidateTag('product-' + handle). - Паттерн RSC для PDP: Компонент страницы асинхронный. Данные запрашиваются прямо в теле компонента:
const product = await getProduct(params.handle);. Название, описание, картинки и характеристики рендерятся как вывод серверного компонента - ноль байт этого кода уходит в клиентский бандл. Клиентскими остаются только<AddToCartButton>и<VariantSelector>. Модель RSC полностью убирает водопадuseEffect → fetch → setState → условный рендер, который был стандартом в реализациях PDP на Pages Router. dynamicParams = true(по умолчанию): Товары, добавленные в Shopify после последней сборки, вgenerateStaticParamsне попали. ПриdynamicParams = trueзапрос неизвестного хендла запускает серверный рендер на первом визите, а дальше страница кешируется. Так новые товары доступны сразу, без полной пересборки.
Механика пагинации коллекций: API коллекций Shopify курсорный: products(first: 24, after: $cursor). В реализации на Next.js каждая «страница» коллекции - отдельный статический маршрут: app/collections/[handle]/page/[page]/page.tsx. Курсор страницы N хранится строкой в base64 и передаётся параметром запроса в ссылку на следующую. Такая архитектура кешируется на CDN, потому что у каждой страницы уникальный стабильный URL, в отличие от клиентской бесконечной прокрутки, которая даёт один некешируемый маршрут.
Часть IV - Состояние корзины: хранение в куке и оптимистичные обновления
Корзина - самая сложная часть клиентского состояния в headless-реализации на Shopify, потому что она должна быть доступна и на сервере (счётчик в шапке рендерится серверным компонентом), и на клиенте (интерактивное добавление и удаление). Правильное решение - хранить идентификатор корзины в куке и читать его на сервере.
- Cart API против Checkout API: У Shopify два API вокруг корзины. Checkout API (устаревший) создаёт объект чекаута с URL; Cart API (актуальный, с 2022) создаёт корзину с отдельным свойством
checkoutUrl. Для всех мутаций корзины берите Cart API: это текущий стандарт и он согласован с Headless Channel. Ключевые мутации:cartCreate(создаёт корзину, возвращаетcart.id),cartLinesAdd(добавляет позиции),cartLinesUpdate(меняет количество),cartLinesRemove(удаляет позицию),cartBuyerIdentityUpdate(привязывает покупателя после входа). - Хранение идентификатора корзины в куке:
cartCreateвозвращаетcart.id- глобально уникальный идентификатор в формате GID (gid://shopify/Cart/{random}). Он должен переживать переходы между страницами и серверные рендеры. Кука тут единственный верный вариант:localStorageнедоступен в серверных компонентах, аsessionStorageне переживает закрытие вкладки. Ставьте куку сhttpOnly: false(клиентскому JS нужно её читать для мутаций),sameSite: 'lax',path: '/',maxAge: 30 * 24 * 60 * 60- тридцать дней, как TTL корзины у Shopify. На сервере читайте черезcookies()в серверном компоненте или Route Handler, чтобы отрисовать счётчик в шапке без клиентского запроса. - Граница
'use client':<CartProvider>- контекст React, который держит состояние корзины и функции мутаций, - клиентский компонент. Его импортируетapp/layout.tsx(серверный компонент), создавая для него Client Reference Object. Поддерево внутри<CartProvider>рендерится на клиенте.<AddToCartButton>- клиентский компонент, который вызываетcartLinesAddчерез Route Handler (/api/cart/lines/add). Никогда не вызывайте мутации Shopify прямо из браузера: токен Storefront API окажется в сетевых запросах. Route Handlers проксируют мутации на сервере. - Оптимистичные обновления через
useOptimistic(React 19):useOptimisticдаёт мгновенную реакцию интерфейса до подтверждения мутации сервером. Паттерн:const [optimisticCart, addOptimistic] = useOptimistic(cart, (state, newLine) => ({ ...state, lines: [...state.lines, newLine] }));. ВызовитеaddOptimisticсинхронно по клику «В корзину», затем дождитесь ответа Route Handler. Если мутация упадёт, React сам откатит состояние к серверному. Это убирает спиннер на 200–400 мс при добавлении в корзину.
Часть V - Аутентификация покупателей: поток OAuth в Customer Account API
Прежние мутации покупателей в Storefront API (customerCreate, customerAccessTokenCreate) объявлены устаревшими начиная с версии API 2024-04. Любая headless-реализация, стартующая с 2025 года, обязана внедрять Customer Account API с потоком OAuth 2.0 PKCE. Это существенный архитектурный сдвиг от простого обмена токенами, к которому разработчики привыкли.
- Механика потока PKCE (RFC 7636): (1) Сгенерируйте криптографически случайный
code_verifier- строку ASCII длиной 43–128 символов. (2) Посчитайтеcode_challenge = BASE64URL(SHA-256(code_verifier)). (3) Отправьте пользователя наhttps://shopify.com/authentication/{shop-id}/oauth/authorize?client_id={id}&scope=openid+email+customer-account-api:full&redirect_uri={uri}&response_type=code&code_challenge={challenge}&code_challenge_method=S256&state={random}. (4) После аутентификации Shopify возвращает наredirect_uri?code={code}&state={state}. (5) Обменяйтеcodeвместе сcode_verifierна токены в token-эндпоинте. Поток PKCE применяется потому, что client_secret нельзя безопасно хранить в браузерном приложении: доказательством личности выступаетcode_verifier. - Работа с токенами в Next.js:
code_verifierгенерируется в Route Handler (app/api/auth/shopify/route.ts), кладётся в кукуhttpOnly(клиентскому JS недоступна) и считывается обратно при обмене на токены. Токены доступа (TTL час) и refresh-токены хранятся в сессионных кукахhttpOnly. Сессия покупателя читается на сервере черезcookies()в серверных компонентах - работать с токенами на клиенте не нужно вовсе. - Паттерн адаптера Auth.js v5: Auth.js (next-auth) v5 поддерживает кастомных OAuth-провайдеров. Customer Account API настраивается как провайдер с
authorization.url,token.urlиuserinfo.url, указывающими на соответствующие эндпоинты. Auth.js берёт на себя обновление токенов, сериализацию сессии и жизненный цикл PKCE-верификатора. Реализация сводится к конфигурации провайдера, а не к написанию конечного автомата OAuth. cartBuyerIdentityUpdateпосле входа: Когда гость набрал корзину и затем авторизовался, корзину нужно привязать к его аккаунту. ВызовитеcartBuyerIdentityUpdate, передав токен доступа покупателя как buyer identity. Это включает историю заказов, сохранённые адреса и начисление баллов лояльности за ранее анонимную активность.
Часть VI - SEO-архитектура: схема товара и каноникал вариантов
У SEO headless-витрины на Shopify есть две особенности, которых нет у обычного приложения на Next.js: разметка товаров и коллекций, которая должна точно отражать модель данных Shopify, и канонизация URL вариантов, которая не даёт системе параметров Shopify наплодить дубли в промышленных масштабах.
- Разметка товара: Каждая PDP отдаёт схему
ProductсOffer(текущая цена, валюта, наличие изproduct.variants.availableForSale),AggregateRating(если подключены отзывы - Yotpo, Judge.me и подобные) иBreadcrumbList. СвойствоProduct.urlобязано быть каноническим URL без параметра?variant=.Offer.priceCurrencyберётся из поляprice.currencyCodeStorefront API по ISO 4217 - хардкодить нельзя.Offer.availabilityмапится так:availableForSale: true→InStock;availableForSale: falseприtotalInventory > 0→PreOrder; иначе →OutOfStock. - Канонизация URL вариантов: Выбор варианта в Shopify добавляет к URL
?variant={variantId}. Без явной канонизации каждый такой URL - индексируемый дубль базовой страницы товара. ВgenerateMetadata()всегда возвращайтеalternates: { canonical: '/products/' + params.handle }и никогда не включайте параметр варианта в каноникал. Так все сигналы вариантов сходятся на базовый URL, а не размазываются по сотням сочетаний. - Каноникал пагинации коллекций: У второй страницы коллекции (
/collections/shirts?cursor=abc) каноникал должен указывать на саму себя, а не на первую страницу: это разное содержимое. Подсказкиrel=prevиrel=next(Google отказался от них в 2019, но Bing использует, и как подсказка обходу они полезны) можно добавить тегами<link>в<head>. Важнее другое: у каждой страницы должен быть уникальный стабильный URL. Курсорная пагинация это обеспечивает, а пагинация по смещению (?page=2) - нет, если порядок товаров меняется. - hreflang для мультирегиональных витрин: Shopify Markets позволяет держать несколько сочетаний страны и валюты на одном магазине. Локаль каждого рынка (en-US, en-GB, fr-FR) соответствует хендлу рынка в Shopify. В
generateMetadata()полеalternates.languagesзаполняется из конфигурации Markets, и URL каждого рынка ведёт на правильный путь локали. Это стандартная связкаnext-intlиgenerateMetadata- подробный разбор в гайде по миграции на App Router.
Часть VII - Инженерия производительности: границы бандла и конвейер картинок
Преимущество headless Shopify перед темами Shopify (Liquid плюс их CDN) не появляется само: оно требует осознанных архитектурных решений. Критичных измерения два - размер клиентского бандла (задаётся расстановкой границ 'use client') и доставка изображений (задаётся работой с URL-параметрами CDN Shopify).
- Поверхность
'use client'на PDP: Интерактивных компонентов на странице товара ровно три:<VariantSelector>(меняет выбранный вариант и вместе с ним цену и наличие),<AddToCartButton>(запускает мутацию корзины) и<ImageGallery>(переключение по миниатюрам, при желании рендерится на сервере с прогрессивным улучшением). Всё остальное - название, описание, характеристики, блок отзывов, хлебные крошки, похожие товары - серверные компоненты. Суммарная клиентская поверхность: примерно 15–25 КБ gzip. Общий бандл грамотно собранной PDP: 80–120 КБ gzip против 350–500 КБ у типичной темы на Liquid с Alpine.js или у наивной клиентской реализации на React. Как это сокращение переводится в улучшение INP, подробно разобрано в гайде по архитектуре веб-производительности. - Работа с URL картинок в CDN Shopify: Shopify отдаёт изображения товаров с
cdn.shopify.com. CDN умеет преобразования на лету через параметры URL:?width=800&height=800&crop=center&format=avif&quality=80. Внешний CDN картинок или отдельный обработчик дляnext/imageне нужны. Вnext.config.tsдобавьтеimages.remotePatternsдляcdn.shopify.com, а в компонентах передавайте URL картинки Shopify прямо вnext/image- он запросит нужный размер через строку запроса. Для AVIF добавьте&format=avif: Shopify сгенерирует вариант при первом запросе и закеширует навсегда. - Preconnect к CDN Shopify:
<link rel='preconnect' href='https://cdn.shopify.com' />вapp/layout.tsx. Это снимает задержку резолва DNS и TLS-рукопожатия (около 150–200 мс) на первом запросе картинки со стороны Shopify. На PDP с шестью изображениями это заметно улучшает LCP: запрос hero-картинки стартует сразу после разбора HTML. - Семантика кеширования на краю: Страницы коллекций и товаров отдают
Cache-Control: public, s-maxage=3600, stale-while-revalidate=86400. Директиваs-maxageвелит краевым узлам CDN (Vercel Edge Network, Cloudflare) отдавать кеш час, аstale-while-revalidateразрешает отдавать устаревшую копию ещё сутки, пока в фоне идёт регенерация. Route Handlers мутаций корзины (/api/cart/*) обязаны явно ставитьCache-Control: no-store: ответы корзины персональные и на CDN кешироваться не должны никогда.
Часть VIII - Продакшен-архитектура: паттерны из проектов
Архитектурные паттерны из этого гайда взяты из продакшен-реализаций headless Shopify. Два показательных проекта из портфолио показывают, где теория встречается с продакшен-ограничениями.
- Международный магазин товаров для дома (гибрид Shopify Plus и Magento 2): Проект с мультивитринной архитектурой Shopify Plus, обслуживающей B2B и B2C в 12 странах, плюс каталог Magento 2 для оптового канала. Headless-фронтенд на Next.js потреблял и Storefront API Shopify, и GraphQL API Magento через единый слой данных: одни и те же React-компоненты рисовали товары независимо от коммерческого бэкенда. Абстракция - типизированный интерфейс
Product, который возвращали иgetShopifyProduct(), иgetMagentoProduct(). Это композируемая headless-архитектура в самой требовательной форме: два бэкенда, одно дерево компонентов, одинаковая производительность на обоих. - Ритейл под всплесками нагрузки: Здесь витрина должна была выдерживать всплески на флеш-распродажах (десятикратный трафик в окне 60 секунд) без деградации TTFB и без падения мутаций корзины. Решение:
generateStaticParamsпререндерит все PDP и PLP на сборке, и всплеск целиком принимает край CDN, вообще не обращаясь к origin за содержимым страниц. В origin во время всплеска идут только мутации корзины через/api/cart/*, а они проксируются в Cart API Shopify, у которого свои лимиты и очередь. Лимиты Storefront API (1000 единиц на запрос, пополнение 500 в секунду) узким местом не стали, потому что на статических страницах витрина не делала к Shopify ни одного запроса. Продвинутые паттерны корпоративной коммерции - в услуге enterprise eCommerce. - Схема выбора архитектуры: Берите этот подход, когда: (1) каталог большой, от 500 товаров, - пререндер через
generateStaticParamsокупается; (2) нужны витрины в нескольких регионах - связка Shopify Markets и i18n в Next.js тут верна; (3) дизайн-система должна быть полностью своей - темы на Liquid произвольную фронтенд-архитектуру не потянут. Берите Shopify Hydrogen, когда: (1) Shopify - единственный бэкенд, и нативная интеграция убирает весь шаблонный код слоя данных; (2) команде ближе паттерны Remix; (3) Oxygen (хостинг Shopify на V8-изолятах) вписывается в ваши ограничения по деплою. Полное сравнение обеих архитектур - в разборе Shopify Hydrogen против Next.js Commerce.
Заключение
Продакшен-витрина headless Shopify на App Router задевает четыре инженерные области, и каждую нужно сделать правильно: поверхность API Shopify (три уровня, фиксация версии, стоимостные лимиты), модель данных App Router (RSC для каталога, 'use client' только для интерактивного состояния), поток OAuth 2.0 PKCE в Customer Account API и работу над производительностью, которая держит клиентский бандл маленьким, а попадание в кеш CDN высоким.
Команды, которые подходят к задаче как к «дёрнуть API Shopify и отрисовать данные», стабильно получают витрину медленнее темы на Liquid, баги сессии в корзине и авторизации и проблемы с позициями из-за дублей URL вариантов. Архитектура из этого гайда - типизированный слой данных, каталог через generateStaticParams, корзина в куке, авторизация по PKCE, 'use client' на листьях дерева - от всего этого и защищает. Тот же headless-инстинкт работает и вне коммерции: когда бэкендом контента выступает WordPress, а не Shopify, ход тот же - перейти на нативную для Next.js альтернативу вроде Payload CMS.
Скоупинг архитектуры, внедрение или аудит существующей headless-витрины на Shopify - услуга композируемой headless-архитектуры | кейсы | обсудить проект.
Частые вопросы
- Нужна собственная реализация на Next.js или лучше взять Shopify Hydrogen? Hydrogen верен, когда Shopify - ваш единственный коммерческий бэкенд и вам комфортно с архитектурой Remix и Vite. Собственная реализация на Next.js выигрывает, когда бэкендов несколько (Shopify плюс Magento или Shopify плюс свой PIM), когда дизайн-система и библиотека компонентов уже на React и Next.js или когда требования к хостингу исключают Oxygen. Фреймворк выбора - в полном сравнении.
- Почему нельзя просто держать идентификатор корзины в
localStorage?localStorage- браузерное API: оно недоступно в серверных компонентах, при SSR и в middleware. А счётчик товаров в шапке должен рендериться на сервере, потому что он попадает в исходный HTML. Кука - единственный механизм, доступный и серверу (cookies()в Next.js), и клиенту. Правильный вариант хранения - кука сhttpOnly: falseиsameSite: 'lax'. - Как жить с лимитами Storefront API на масштабе? Стоимостная система (1000 единиц на запрос, пополнение 500 в секунду) означает, что одно приложение на Next.js может бесконечно делать около 1,7 запроса в секунду при 500 единицах на запрос. Для сборки каталога от 5000 товаров нужен билд-тайм конвейер, который листает товары на максимально допустимой скорости, а не запрос на каждый показ. В реальном трафике паттерн ISR означает, что на закешированных страницах сервер вообще не ходит в Storefront API, и лимиты касаются только фоновой регенерации.
- Как сделать ревалидацию ISR по требованию, когда товар обновили в Shopify? Настройте вебхук Shopify на событие
products/updateс адресом Route Handler в Next.js. Обработчик проверяет HMAC-подпись вебхука, достаёт хендл товара и вызываетrevalidateTag('product-' + handle). Следующий запрос этой PDP запустит регенерацию. Обработчик должен быть открыт для доставки вебхуков Shopify, но защищён проверкой HMAC. - Как правильно обходиться с параметром
?variant=для SEO? Каноникал всегда указывает на базовый URL товара без параметра варианта:alternates: { canonical: '/products/' + handle }вgenerateMetadata(). Сам выбор варианта можно держать в URL параметром запроса ради возможности поделиться ссылкой - на SEO это не влияет, потому что Google уважает каноникал и сводит сигналы к базовому URL. В карту сайта URL с?variant=не включайте никогда.
Источники
- Shopify. «Storefront API Reference»
- Shopify. «Customer Account API»
- Shopify. «Shopify API Rate Limits»
- Shopify. «Shopify Markets»
- RFC 7636. «Proof Key for Code Exchange by OAuth Public Clients»
- Next.js Team. «generateStaticParams»
- Next.js Team. «Data Fetching and Caching»
- Next.js Team. «Incremental Static Regeneration»
- GraphQL Code Generator. «TypeScript Operations Plugin»
- Auth.js. «Custom OAuth Providers»
- Shopify. «Storefront API changelog 2025-01»
- HTTP Archive. «Web Almanac 2025 - eCommerce»
Строить самому или стартовать с production-темплейта?
Стартуйте с темплейта, если только сама витрина не является вашим продуктом. Этот гайд показывает полную сборку, потому что понимать, что у вас работает, вы обязаны. Но заново писать всю обвязку большинству команд не нужно. Production-темплейт уже везёт витрину, адаптеры, тесты и CI: вы подключаете свой бэкенд и кастомизируете, а не пересобираете корзину, чекаут, поиск и SEO с нуля.
| Измерение | Сборка с нуля | Production-темплейт |
|---|---|---|
| Витрина, корзина, чекаут | Строите сами | Уже внутри |
| CMS для контента и поиск | Подключаете сами | Sanity/Contentful/Payload/AEM плюс Algolia или встроенный |
| Тесты и доступность | Заводите сами | 460+ тестов, WCAG 2.2 AA, гейт Lighthouse |
| Время до продакшена | Недели и месяцы | Дни и недели |
| Дальнейшая поддержка | Целиком на вас | Поддерживаемое ядро, которое вы расширяете |
Сколько времени занимает сборка headless-магазина на Shopify?
С нуля продакшен-витрина headless Shopify обычно занимает от нескольких недель до нескольких месяцев в зависимости от размера каталога и интеграций. Старт с проверенного темплейта сокращает это до дней и недель, потому что корзина, чекаут, поиск, контент и CI уже готовы, а вам остаётся подключить бэкенд и наложить свой бренд.
Какой самый быстрый путь к продакшен-витрине headless Shopify?
Стартовать с проверенного основания, а не с пустого репозитория. Headless Commerce Template - это витрина, описанная в этом гайде, уже собранная: Shopify или Magento позади, контент, поиск, лояльность и подарочные карты в коробке, и CI, который не пропустит мердж с просадкой доступности или скорости. Наводите на свой бэкенд, выходите за недели, код остаётся у вас.
