Интеграция Vendure GraphQL API с фронтендом

Мы решали задачу интеграции headless e-commerce на React с бэкендом Vendure. Типичные проблемы: настройка аутентификации, работа с корзиной через GraphQL, SSR с Next.js. В этой статье — готовое решение с кодом, конфигами и пояснениями. Наш опыт — более 5 лет работы с Vendure и 50+ успешных интеграци

Разработка и обслуживание любых видов сайтов:

Информационные сайты или веб-приложения
Сайты визитки, landing page, корпоративные сайты, онлайн каталоги, квиз, промо-сайты, блоги, новостные ресурсы, информационные порталы, форумы, агрегаторы
Сайты или веб-приложения электронной коммерции
Интернет-магазины, B2B-порталы, маркетплейсы, онлайн-обменники, кэшбэк-сайты, биржи, дропшиппинг-платформы, парсеры товаров
Веб-приложения для управления бизнес-процессами
CRM-системы, ERP-системы, корпоративные порталы, системы управления производством, парсеры информации
Сайты или веб-приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, конструкторы сайтов, порталы предоставления электронных услуг, видеохостинги, тематические порталы

Это лишь некоторые из технических типов сайтов, с которыми мы работаем, и каждый из них может иметь свои специфические особенности и функциональность, а также быть адаптированным под конкретные потребности и цели клиента

Услуги, которые мы предлагаем
Показано 1 из 1Все 2062 услуг
Интеграция Vendure GraphQL API с фронтендом
Средний
~5 дней

Наши компетенции:

Часто задаваемые вопросы

Последние работы

  • image_website-b2b-advance_0.webp
    Разработка сайта компании B2B ADVANCE
    1422
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1288
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    984
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1250
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    988
  • image_bitrix-bitrix-24-1c_fixper_448_0.webp
    Разработка веб-сайта для компании ФИКСПЕР
    1001

Мы решали задачу интеграции headless e-commerce на React с бэкендом Vendure. Типичные проблемы: настройка аутентификации, работа с корзиной через GraphQL, SSR с Next.js. В этой статье — готовое решение с кодом, конфигами и пояснениями. Наш опыт — более 5 лет работы с Vendure и 50+ успешных интеграций. Средняя экономия бюджета при переходе на headless — до 40%, сроки вывода на рынок сокращаются до 2 недель. Гарантируем стабильность и производительность. Свяжитесь с нами для оценки вашего проекта — получите консультацию и коммерческое предложение.

Vendure предоставляет два отдельных GraphQL endpoint: Shop API (/shop-api) для покупателей и Admin API (/admin-api) для администраторов. Фронтенд использует только Shop API. Аутентификация — через cookie-based сессии или Bearer token, выбор делается на уровне конфига сервера. В этой статье мы покажем, как подключить Vendure к кастомному фронтенду на React/Next.js, настроить генерацию типов, работу с корзиной и checkout. Также разберём типичные ошибки и паттерны их обработки. В конце — что входит в интеграцию под ключ.

API Назначение Эндпоинт Аутентификация
Shop API Покупательские запросы /shop-api Cookie/Bearer
Admin API Админка /admin-api Bearer token

Как работает аутентификация в Shop API?

Аутентификация в Shop API реализована через сессии на основе токенов. При cookie-аутентификации токен сессии создаётся при входе и хранится на сервере, клиент получает куку. Этот метод оптимален для SSR — Next.js де-факто стандарт. Bearer token подходит для SPA, но требует хранения токена в localStorage и внимательного управления временем жизни. В наших проектах за 50+ интеграций мы выработали чёткие рекомендации: для магазинов с высокой долей SEO трафика — cookie, для внутренних панелей — Bearer.

Настройка клиента Vendure

Для подключения к Shop API используем urql. Он легче Apollo и лучше подходит для работы с cookie-сессиями. Ниже — пример клиента для SSR (с cookie) и для SPA (с Bearer token).

// lib/vendureClient.ts import { createClient, fetchExchange, dedupExchange, cacheExchange } from "urql"; // Для SSR с cookie export const shopClient = createClient({ url: `${process.env.NEXT_PUBLIC_VENDURE_API_URL}/shop-api`, exchanges: [dedupExchange, cacheExchange, fetchExchange], fetchOptions: { credentials: "include", headers: { "vendure-token": process.env.NEXT_PUBLIC_CHANNEL_TOKEN! } }, }); // Для SPA с Bearer token export const spaClient = createClient({ url: `${process.env.NEXT_PUBLIC_VENDURE_API_URL}/shop-api`, exchanges: [dedupExchange, cacheExchange, fetchExchange], fetchOptions: () => ({ headers: { authorization: localStorage.getItem("authToken") ? `Bearer ${localStorage.getItem("authToken")}` : "" } }), }); 
Метод Хранение токена Подходит для
Cookie Сессия на сервере SSR (Next.js, Nuxt)
Bearer localStorage SPA без SSR

Генерация типов TypeScript

Для типизации GraphQL-запросов используем GraphQL Code Generator. Настройка описана в codegen.yml:

# codegen.yml schema: - ${VENDURE_API_URL}/shop-api: headers: vendure-token: ${CHANNEL_TOKEN} documents: "src/**/*.graphql" generates: src/generated/shop-types.ts: plugins: - typescript - typescript-operations - typescript-urql config: withHooks: true scalars: DateTime: "string" JSON: "Record<string, unknown>" Money: "number" 

Запуск генерации: VENDURE_API_URL=http://localhost:3000 CHANNEL_TOKEN=my-token npx graphql-codegen. Полученные типы автоматически интегрируются с urql через хуки.

Запросы к Shop API

Все основные операции — получение товаров, корзины, аутентификация — выполняются через Shop API. Ниже приведены ключевые GraphQL-запросы и мутации.

# Каталог: список товаров query GetProductList($options: ProductListOptions) { products(options: $options) { totalItems items { id name slug featuredAsset { preview } variants { id name priceWithTax currencyCode stockLevel } } } } # Каталог: детальная карточка query GetProduct($slug: String!) { product(slug: $slug) { id name slug description featuredAsset { preview source } assets { preview source } variants { id name sku priceWithTax currencyCode stockLevel options { code name group { code name } } } facetValues { code name facet { code name } } } } # Корзина: добавление товара mutation AddItemToOrder($variantId: ID!, $quantity: Int!) { addItemToOrder(productVariantId: $variantId, quantity: $quantity) { ... on Order { id code state totalWithTax currencyCode lines { id quantity linePriceWithTax productVariant { id name sku featuredAsset { preview } } } } ... on OrderModificationError { errorCode message } ... on OrderLimitError { errorCode message maxItems } ... on NegativeQuantityError { errorCode message } ... on InsufficientStockError { errorCode message quantityAvailable } } } # Корзина: получение активного заказа query GetActiveOrder { activeOrder { id code state totalWithTax subTotalWithTax shippingWithTax lines { id quantity linePriceWithTax productVariant { id name } } shippingLines { shippingMethod { name description } priceWithTax } discounts { description amountWithTax } } } # Аутентификация mutation Login($email: String!, $password: String!, $rememberMe: Boolean) { login(username: $email, password: $password, rememberMe: $rememberMe) { ... on CurrentUser { id identifier } ... on InvalidCredentialsError { errorCode message } ... on NotVerifiedError { errorCode message } } } 

Реализация checkout

Процесс оформления заказа включает установку адреса доставки, выбор метода доставки, переход к оплате и выполнение платежа. Пример хука:

// hooks/useCheckout.ts import { useMutation } from "urql"; import { SetShippingAddressDocument, SetShippingMethodDocument, AddPaymentToOrderDocument, TransitionOrderToStateDocument } from "@/generated/shop-types"; export function useCheckout() { const [, setAddress] = useMutation(SetShippingAddressDocument); const [, setShipping] = useMutation(SetShippingMethodDocument); const [, addPayment] = useMutation(AddPaymentToOrderDocument); const [, transition] = useMutation(TransitionOrderToStateDocument); async function completeCheckout(params: CheckoutParams) { const addr = await setAddress({ input: params.address }); if (addr.data?.setOrderShippingAddress.__typename !== "Order") throw new Error(addr.data?.setOrderShippingAddress.message); await setShipping({ id: [params.shippingMethodId] }); await transition({ state: "ArrangingPayment" }); const payment = await addPayment({ input: { method: "yookassa", metadata: { returnUrl: `${window.location.origin}/checkout/confirm` } } }); if (payment.data?.addPaymentToOrder.__typename === "Order") return payment.data.addPaymentToOrder; throw new Error(payment.data?.addPaymentToOrder.message); } return { completeCheckout }; } // Обработка ошибок Vendure function assertIsOrder(result: AddItemToOrderResult): asserts result is Order { if (result.__typename !== "Order") throw new VendureError(result.errorCode, result.message); } 

Vendure использует union types для ошибок — каждая мутация возвращает Result | ErrorType1 | ErrorType2. Паттерн assertIsOrder упрощает работу с TypeScript.

SSR с Next.js App Router

Для серверного рендеринга необходим отдельный клиент, который передаёт токен сессии через заголовок cookie, а не через credentials: "include".

// app/shop/page.tsx import { createServerClient } from "@/lib/vendureServerClient"; export default async function ShopPage() { const client = createServerClient(); // клиент с credentials для SSR const result = await client.query(GetProductListDocument, { options: { take: 24 } }).toPromise(); return <ProductGrid initialData={result.data} />; } 

Это позволяет избежать проблем с гидратацией и улучшить SEO.

Почему стоит выбрать headless Vendure?

Headless-подход с Vendure даёт гибкость в выборе фронтенд-технологий и масштабировании. Вы получаете изолированный бэкенд с GraphQL API, готовый к интеграции с любыми сервисами — CMS, PIM, поиском. В наших проектах это сократило time-to-market на 40% и позволило обрабатывать до 10 000 запросов в секунду на стандартном VPS. Стек: Node.js + PostgreSQL + Redis — даёт 99.9% uptime.

Что входит в интеграцию под ключ?

  • Настройка Vendure (развёртывание, конфигурация API, настройка каналов)
  • Разработка кастомного фронтенда на React/Next.js
  • Интеграция Shop API (каталог, корзина, checkout, аутентификация)
  • Генерация TypeScript-типов и подключение urql
  • SSR с Next.js App Router
  • Обработка ошибок и unit-тесты
  • Документация по API и коду
  • Передача доступов и обучение команды
  • Поддержка в течение 1 месяца после запуска

Сроки: от 14 рабочих дней в зависимости от сложности. Стоимость интеграции под ключ — от $2 000 за типовой проект. Экономия на эксплуатации — до $5 000 в год за счёт оптимизации.

Наш опыт и гарантии

Мы специализируемся на headless e-commerce с использованием Vendure более 5 лет. Реализовали более 50 проектов — от интернет-магазинов до сложных маркетплейсов. Гарантируем стабильную работу API, производительность и соблюдение сроков. Закажите интеграцию Vendure прямо сейчас — получите консультацию и оценку проекта. Свяжитесь с нами через форму на сайте.