Updates

See the latest product improvements, feature releases, and roadmap updates to our Hydrogen + Oxygen stack

September 2, 2026

Developer preview release notes: September 2, 2026

New

Variant links

Hydrogen now reads Shopify's ?variant= product links and sends the shopper to that variant. It used to ignore the parameter and show the default variant at the default price. Pass routeTemplates to handleShopifyRoutes to turn it on.

Read more

August 18, 2026

Developer preview release notes: August 18, 2026

New

Carts can now have session attribution

Cart handlers accept a customerSession. New carts are created with the signed-in customer's buyer identity, and authenticated cart reads mark the checkout URL so shoppers aren't handed a guest checkout.

Pass customerSession to createCartServerHandlers(), then pass those handlers back as cartServerHandlers to createCustomerAccountServerHandlers(). The two stay in step from there: login and token refresh attach the customer to the browser cart; logout, or a refresh that fails for good, detaches them.

Sync never blocks the route's redirect. A failed detach on logout expires the cart cookie instead.

Cart attributes

Cart-level attributes are new: attributes-update is a cart action for order-wide data like a gift message, and form fields register with register("attributeValue", {key}). Line attributes, already accepted on add and update, now come back in cart queries and count toward line identity. The same variant added with different attributes produces separate lines instead of merging into one.

Standard page view events

ShopifyScripts emits shopify:page:view on the first page load and on every client-side navigation, tagged with the page template resolved from your routes. A Hydrogen storefront used to look like a single page load to analytics and performance tooling; it now reports the way a themed store does.

Development builds can load Shopify's standard events inspector to watch the stream. Production builds don't include it.

Storefront ID for cart analytics

createStorefrontClient accepts an optional storefrontId and sends it as a trusted header on Storefront API requests. Cart activity is attributed from the server rather than the browser. On Oxygen, a linked storefront injects the ID as an environment variable.

Custom paths for more Shopify routes

Route templates map Shopify's canonical resource URLs onto the paths your storefront actually serves. Without them, Shopify's redirects and attribution parameters point at URLs you don't have: a cart at /basket gets sent to /cart.

createShopifyRouteTemplates() accepts cart, search, policy, and collectionList alongside the product, collection, page, blog, and article templates. Predictive search suggestions follow the configured search route.

Pluggable logging

configureLogging({level, logger}) sets how much Hydrogen logs and where the logs go. The level runs from trace to fatal, plus silent, and defaults to info. The logger accepts anything with matching level methods, so warnings and errors reach your own observability tooling instead of the console. Console output stays the default, prefixed [hydrogen:<level>:<scope>], for example [hydrogen:warn:cart].

Local HTTPS for Customer Account development

Customer Account OAuth needs an HTTPS origin that isn't localhost, which made login the one flow you couldn't test without a tunnel or your own certificates. Hydrogen uses local.tryhydrogen.dev:5173, a Shopify-owned hostname that resolves to 127.0.0.1.

Vite apps configure it with localHttps() from the new @shopify/hydrogen/vite entrypoint; Next.js uses next dev --experimental-https. Register the origin in your Customer Account API settings. The new hydrogen-local-https skill has the per-framework setup.

Changed

Shopify script traffic goes through your domain

Scripts loaded by ShopifyScripts send their API calls to your domain, which forwards them to Shopify. Resources under /.well-known/ are served from your origin too, so services verifying your customer-facing domain aren't bounced to myshopify.com. There's nothing to configure: handleShopifyRoutes serves the proxy, and ShopifyScripts points the runtime at it.

Checkout, cart permalinks, and Customer Account handoffs are full document navigations now: a client-side router would intercept those server redirects before the request reached your server.

Shop Pay renders locally

The Shop Pay button no longer loads shop-js from Shopify's CDN. It renders as a custom element with styles sealed in a shadow root, so it displays correctly before JavaScript runs. Page CSS can't reach in. renderShopPayButton returns the server HTML, and getShopPayButtonUrl returns the checkout URL on its own.

Styling is limited to width and borderRadius. If your style-src has no 'unsafe-inline', the button stays at its default width: both properties apply as an inline style attribute, which a nonce can't cover.

Cart correctness under concurrent mutations

Overlapping cart mutations could leave totals and quantities wrong. Hydrogen's optimistic cart updates are rebuilt around per-mutation transactions: cancellation is reliable, and an update that gets superseded no longer leaves a stale total on screen.

CartState.revalidating and pending.cost are new, so you can tell a background refresh apart from a pending change and hold totals steady while a cost-affecting mutation settles.

Route handling

handleShopifyRoutes() returns null synchronously when no route matches, and framework routing continues without an async hop. Matched routes still return Promise<Response>.

Responses from handleShopifyRoutes and handleShopifyRedirects come back with the storefront headers Hydrogen requires already applied; if you were setting those headers yourself, remove that code. handleShopifyRedirects also accepts public clients, even ones without a token, since the redirect lookup only queries urlRedirects.

Shopify.navigate is deprecated. Use Shopify.routes.navigate.

Vue parity

The Vue binding gets useCartAnalytics(), matching the React hook. Vue's ShopifyScripts forwards every core option, including shopifyAnalytics, and no longer warns when routes is omitted.

Fixes

The API proxy no longer forwards Cloudflare's client IP header to Shopify, and a redundant client IP header was dropped from Storefront API requests. Locale path prefixes with stray whitespace normalize instead of leaking into resolved URLs. createStorefrontClient autocomplete covers every client type, not just the first overload.

Versioned preview releases

Previews publish through changesets prerelease mode, and version numbers name their target release: 2026.10.0-preview.1 is the first preview of what becomes 2026.10.0.

Agent skills

Two new skills: hydrogen-customer-account for logged-in account pages, and hydrogen-local-https for Customer Account development. The hydrogen-setup skill was reworked into a sequenced walkthrough, and generated projects now recommend the Shopify AI Toolkit.

Removed

  • loadShopJs, getShopPayButtonAttributes, and getShopPayButtonStyleProperties are gone, along with the loadScript prop on the React and Vue Shop Pay components.
  • buyerIp is no longer accepted in private Storefront client config. Build a request context that carries the buyer IP, createShopifyRequestContext({buyerIp}), and pass that.
  • createEmptyPending, CART_API_PATH, CART_GET_METHOD, and CART_POST_METHOD are no longer exported.
  • The manual bridge to PerfKit, Shopify's performance monitoring, is gone. PerfKit reads shopify:page:view directly.
  • @0no-co/graphqlsp is no longer a direct dependency. The bundled TypeScript plugin covers it.

Migration

For migration guidance, compare the commits that bracket this release. The diff shows the changes between the previous preview and this release:

Code Example

git diff 116d5d7ea..d91af14a4

July 30, 2026

Developer preview release notes: July 30, 2026

New

Vue bindings

@shopify/hydrogen/vue is a new entrypoint that mirrors the React API: providers and composables for the cart, products, collections, and search. Vue 3.5+ is an optional peer dependency, same as React.

Typed factories work the same way as in React: createCartComponents<typeof cartHandlers>() returns CartProvider, useCart, and useCartForm, with cart state typed from your server handlers. Product forms get the same treatment through createProductComponents; collections and search use plain providers and composables.

GraphQL TypeScript tooling in the package

Apps no longer install gql.tada or repeat Shopify schema paths in tsconfig.json. A bundled TypeScript plugin gives you autocomplete and type errors across both the Storefront and Customer Account schemas, and it takes one tsconfig entry:

Code Example

{"compilerOptions": {"plugins": [{"name": "@shopify/hydrogen/ts-plugin"}]}}

The same validation runs headlessly with hydrogen gql check --fail-on-warn, so CI can catch schema drift without an editor.

Analytics and consent through ShopifyScripts

ShopifyScripts now inlines the analytics bus into the rendered HTML, so it's there before framework code hydrates. The bus lives at window.Shopify.analytics, which means any part of the app can publish to it without the bus being passed around. The consent and Shopify analytics scripts load on every page now; pass shopifyAnalytics: false to skip the analytics one.

Consent starts up as part of the same bootstrap. consent: {mode: "default-banner"} uses Shopify's privacy banner; an explicit consent config supports a custom one.

Cart tracking is a subscription now: trackCartAnalytics(cartStore) works from any framework, and React gets a useCartAnalytics() hook.

Shopify Inbox support

Hydrogen now supports Shopify Inbox. Shoppers can chat with your store's AI agent and get handed off to staff when they need a human, all without signing in.

With inbox enabled on ShopifyScripts, the Inbox module loads, and <shopify-chat /> controls where the widget appears. The store needs the Inbox app with the Agent feature enabled, and "Require sign-in to chat with staff" turned off.

Suspense cart reads in React

createCartComponents() now returns useSuspenseCart, and the cart store exposes the in-flight full-cart load. Cart content can suspend behind its own fallback while the rest of the page renders immediately. For Next.js apps, that means the app shell can stay static and CDN-cacheable while the cart streams in.

Changed

ShopifyScripts asks for your shop identity

Features like Inbox and analytics bootstrap from your shop's permanent domain, so the shop option is now required and includes myshopifyDomain alongside shopId and storefrontId. If you passed only IDs before, adding the domain is the whole migration.

Analytics and consent config shapes

The analytics config now asks for an explicit channel ("hydrogen" or "headless"), and fields Hydrogen can resolve on its own went away:

  • acceptedLanguage, currency, and hydrogenSubchannelId from ShopAnalytics
  • consentDomain and publicStorefrontAccessToken from ConsentConfig

Consent gating is stricter too: events now wait for customerPrivacy.consentStatus to reach loaded before firing. prevCart also moved off cart_viewed payloads; it stays on cart-update and cart-line-update payloads.

Product option selection

Variant matching now accounts for the full set of selected options, and variants from other products no longer leak into the result. The helper signature changed to take one object, { searchParams, allowedOptionNames? }; the URL and Request overloads are gone.

Private Storefront API calls now need buyerIp

If you call the Storefront API with a private token, directly or through the proxy, requestContext.buyerIp is now required: the proxy throws without it, and the client throws if it disagrees with the client's own buyerIp. Public-token setups aren't affected.

New window.Shopify globals

Shopify.currency.active tracks the active currency. The initial value comes from the new i18n.currency option; after that it stays in sync with the cart. Shopify.customerPrivacy.consentStatus flips to loaded once consent resolves, which is also when analytics events start firing. window.privacyBanner lets a "manage cookies" link reopen the banner.

Typed collection filters

Filter types are generic now, so API-provided value fields like swatch keep their types through to your UI.

Cart and search behavior fixes

Search results no longer go stale when shoppers navigate away and back: the predictive search store gained connect(), and the React provider reconnects on mount.

reset() on the cart store now reloads the cart from the server instead of leaving the store empty. When a shopper updates their consent, the cart refreshes its checkout URL to match.

Shopify CLI only shows commands this package supports

In a dev-preview project, the Shopify CLI now hides the classic hydrogen:* commands this package doesn't support, instead of offering ones that fail when you run them.

Agent skills

Updated across the board, with new framework references for Vue, Nuxt, SvelteKit, and Solid Start. Two new skills: hydrogen-image for CDN image URLs and hydrogen-oxygen for Oxygen and MiniOxygen setup. The starter templates now ship the full skill set under .agents/skills/.

Removed

  • Hydrogen no longer exports createStorefrontAnalytics(). ShopifyScripts creates the analytics bus now, so the factory had nothing left to do, and the bus's updateCart() method went with it. Cart tracking comes from trackCartAnalytics(cartStore), or useCartAnalytics() in React.
  • The canTrack and cookieDomain analytics options are gone. Consent gating is owned by the ShopifyScripts bootstrap now.
  • quantityAvailable is no longer fetched by the default cart fragment. If you show stock availability, pass a custom cart fragment that adds it back.
  • Shopify.customerPrivacy.shouldShowGDPRBanner() went away, along with config.storefrontAccessToken and config.injectedConsent. Use shouldShowBanner(), or the new window.privacyBanner API, instead.
  • InitializeShopifyScriptsOptions is no longer exported. Routing config uses ShopifyRoutesOptions, and webMcp is a prop on ShopifyScripts.

Migration

For migration guidance, compare the commits that bracket this release. The diff shows the changes between the previous preview and this release:

Code Example

git diff 8a708a87f..116d5d7ea

July 9, 2026

Developer preview release notes: July 8, 2026

This developer preview update adds Storefront API caching, a Customer Account API, predictive search, typed routing, and storefront tooling for in-browser AI agents, plus a round of changes that unify how requests, carts, and analytics are handled.

New

Subrequest caching for the Storefront API

You can now cache Storefront API responses for catalog data (products, collections, and pages) at the edge and serve repeat visits from the cache. Caching is opt in per query. It's built for Oxygen and other edge runtimes that expose a cache store and a waitUntil hook, which keeps the runtime alive long enough to finish cache writes after the response is sent. The cache layer also accepts a get/set interface for Node.js and other platforms that don't expose a Web Cache API.

  • Opt in per query with client.graphql(QUERY, { cache: Cache.long() }). createFetchWithCache() and createRunWithCache() are also available for custom caching of other APIs.
  • Built-in strategies: Cache.short, Cache.long, Cache.none, or a custom mix of maxAge, staleWhileRevalidate, and staleIfError. Adapters ship for both the Web Cache API and KV stores. A Cache-Status header reports whether each response was a hit, miss, or stale.
  • Caching is opt in, so nothing is cached unless you ask. Mutations and private cache mode are refused, and customer data is never cached.

WebMCP: storefront tools for AI agents

WebMCP lets a storefront expose tools to AI agents running in the browser, so an agent can search the catalog, browse, view a product or variant, update the cart, start checkout, and view orders. Cart actions use Standard Actions.

The tools load by default through ShopifyScripts (opt out with webMcp={false}), or call initializeShopifyScripts() yourself for frameworks without a Hydrogen binding. The script is delivered from Shopify's CDN and injected automatically, so you don't install or import it. It only activates in browsers that expose model-context APIs.

Customer Account API support

This release adds a typed Customer Account API client, for logged-in experiences like order history and profile pages. It lives on its own entrypoint, @shopify/hydrogen/customer-account, with its own gql() and generated schema and types.

createCustomerSession() handles login, the OAuth callback, refresh, and logout. It's framework-neutral and ships default route handlers that plug into handleShopifyRoutes.

Personalized account and session responses are marked private, no-store automatically, so customer data can't land in a shared or CDN cache.

Predictive search

Predictive search gives you same-origin autocomplete. The browser calls your origin (/api/predictive-search), and your server runs the Storefront API predictiveSearch query, so the public storefront token stays server-side.

  • Register createPredictiveSearchServerHandlers() (defaults to GET /api/predictive-search), drive it with createPredictiveSearchStore(), which handles debounce, aborts, and stale responses, and consume it through React hooks like usePredictiveSearch and usePredictiveSearchForm.
  • getPredictiveSearchItemUrl() builds result URLs that keep Shopify's attribution parameters intact.
  • You build the dropdown UI. It degrades to a plain GET /search?q= form when JavaScript isn't available.

Standard routes and redirects

A typed route manifest lets your app describe its URL structure once and reuse it for redirects and predictive-search URLs. This matters when your paths don't match Shopify's defaults, for example /productos/camisa instead of /products/camisa, where Shopify's redirects and attribution parameters would otherwise point at the wrong URL.

createShopifyRouteTemplates() maps Shopify-standard resource locations (products, collections, pages, blogs, articles) onto your app's real paths, and keeps attribution and redirect behavior consistent across the two.

Cart server route handlers

createCartServerHandlers() returns cartHandlers.get() and cartHandlers.post() that register into handleShopifyRoutes, so cart routes use the same registration model as everything else and work the same across frameworks. It replaces the old framework-specific shopifyCartGet bootstrap helper.

ShopifyScripts for SSR runtime tags

ShopifyScripts renders the Shopify browser runtime's <script> and <link> tags plus the window.Shopify bootstrap (preconnects, country/locale/routes globals, Standard Actions, and optionally WebMCP) in one place, instead of hand-wiring those per framework. Use getShopifyScriptTags() / renderShopifyScriptTags() for framework-agnostic setups, or the ShopifyScripts component in React.

Deploy buttons

Generated starters now include deploy buttons for Oxygen and Vercel in their README.

Changed

Unified Shopify request context

There's now a single request context, createShopifyRequestContext, that you reuse for the Storefront client, the Customer Account client, sessions, and handleShopifyRoutes. Everything in a request shares the same headers, locale, and cache policy.

  • i18n on the request context now only carries the language and country codes common to both APIs. pathPrefix is optional routing metadata.
  • requestContext is now required by the Storefront client, the Customer Account client, session methods, and handleShopifyRoutes, and handleShopifyRoutes must receive the same object as the Storefront client. This is a migration step if you're on an earlier dev-preview.

Typed carts, end to end

Pass a typed gql cart fragment to createCartServerHandlers({ fragment }) and derive typed React bindings with createCartComponents<typeof cartHandlers>(). Cart state types come from your handler definition instead of being written by hand.

Cart initial data can be a promise

Cart initialData now accepts a Promise as well as a resolved payload, so you can return a loader promise directly and let the store hydrate when it resolves. Bindings no longer fire a second fetch. This works with deferred and streaming loaders.

Product forms

React product forms can register an add-to-cart submit button with register("addToCart"), which keeps the button name from drifting and wires submission to the cart store.

Normalized option state exposes Storefront API option value swatches at option.values[n].swatch, so you can render merchant-provided color and image swatches instead of styling from the label text.

Build

React components are now marked "use client", so they import directly into server components without a hand-written client wrapper. GraphQL query strings are minified at build time, so they ship smaller.

Framework examples

Refreshed the framework starter examples, including customer-account login and logout flows for React Router and Next.js.

Agent skills

Updated the skills that ship with the package (product pages, search and collection browsing, cart, analytics, and query validation). Added new skills and refreshed the rest.

Removed

  • createStorefrontRequestContext. Renamed to createShopifyRequestContext. No alias is kept.
  • shopifyCartGet bootstrap helper. Use cartHandlers.get() from createCartServerHandlers() instead.
  • country and language on the analytics consent config. Pass the resolved market to ShopifyScripts or getShopifyScriptTags({ i18n }) instead.
  • The WebMCP export from @shopify/hydrogen/cdn. WebMCP now loads from Shopify's CDN through ShopifyScripts or initializeShopifyScripts().
  • Request-local in-flight cache dedupe. Concurrent cold misses now run independently. The per-request dedupe made stale-while-revalidate and stale-if-error behavior hard to reason about for little gain.

Migration

For migration guidance, compare the commits that bracket this release. The diff shows the changes between the previous preview and this release:

Code Example

git diff 0c3bff8fd..8a708a87f

June 30, 2026

Deploy a Hydrogen storefront to Vercel in one click

Starting today, the Deploy to Vercel button automatically creates an example Next.js + Hydrogen storefront on Vercel. Go ahead, give it a try:

Deploy with Vercel

Hydrogen recently evolved from a framework to a toolkit, so you can power a headless storefront with Shopify no matter how or where it was built.

What better place to start than Vercel, whose Next.js team collaborated with us on the new Hydrogen.

The following was originally published on Vercel’s blog.


Hydrogen made headless storefronts easy to ship, but not portable. At Vercel Ship 26 in New York, we announced that we are working with Shopify to rebuild it from the ground up, aligning with our shared goal of making the web more open.

The new version is open source and runtime agnostic, meaning it can run anywhere JavaScript does. You can choose to build with Svelte, Nuxt, Next.js or even bring your own custom framework.

Our strategy includes three layers: core, client and server.

The core

Core is the JavaScript we all used to write, but never shared. It’s the layer for working with the Shopify API in any runtime, with the boring-but-important opinions centralized.

Take formatMoney. The open web already solved most of this with Intl.NumberFormat.

Code Example

const price = new Intl.NumberFormat("en-US", {
  style: "currency",
  currency: "USD",
}).format(19.99); // "$19.99"

But the Shopify API doesn't hand you a number. It responds with a custom type, MoneyV2, and the amount is a signed decimal number serialized as a string.

Code Example

import { formatMoney, type MoneyV2 } from "@shopify/hydrogen";

export function formatPrice(money: MoneyV2, locale = "en-US") {
  return formatMoney(money, { locale }).toString(); // $19.99
}

The result is the same, but you’re not writing or maintaining the glue code anymore. When the API changes, the upgrade is trivial.

Centralize the core and we fix each bug once, ship improvements to everyone, and get back to building.

The client

Rendering what the core returns involves the same repeated decisions. Cart state is the obvious one.

Code Example

import { createContext, useContext, useState, useCallback } from "react";

const CartContext = createContext(null);

export function CartProvider({ children }) {
  const [cart, setCart] = useState(null);

  const addLine = useCallback(async (variantId, quantity) => {
    // custom code that we all wrote ourselves
  }, []);
  const updateLine = useCallback(async (variantId, quantity) => {
    // custom code that we all wrote ourselves
  }, []);
  const removeLine = useCallback(async (variantId, quantity) => {
    // custom code that we all wrote ourselves
  }, []);

  // applyDiscount, note, currency, error state, cross-tab sync, refetch on focus, etc.

  return (
    <CartContext.Provider value={{ cart, pending, addLine }}>
      {children}
    </CartContext.Provider>
  );
}

export const useCart = () => useContext(CartContext);

Custom code for managing cart state with React

Anyone who's built a commerce app has written a version of this. Different code every time, all chasing the same things.

With Hydrogen, the client layer now handles the cart. State management becomes one import.

Code Example

import { createCartComponents } from "@shopify/hydrogen/react";

const { useCartForm } = createCartComponents();

function AddToCartButton({ variantId }) {
  const { formProps, register } = useCartForm();

  return (
    <form {...formProps()}>
      <input
        type="hidden"
        {...register("merchandiseId", { value: variantId })}
      />
      <button {...register("add")}>Add to cart</button>
    </form>
  );
}

With Hydrogen the cart state management is a single import

Centralize this and you get the best practices for free, so you can spend your time on the parts that are actually yours to build. It's available for React today on the Hydrogen preview branch, with more frameworks coming.

The server

Developers need full-stack access to build storefronts that scale without sacrificing performance. Static content should serve instantly from a CDN while dynamic data like inventory streams in.

The open-source community solved this with frameworks like Next.js, Nuxt, and SvelteKit: full-stack capabilities with no lock-in to a proprietary runtime.

Say your storefront caches product queries with on-demand revalidation. You write the GraphQL query. Hydrogen gives you a type-safe client. Next.js handles caching, and you get full-stack frameworks plus the headless Shopify API with none of the glue code.

Code Example

import { PRODUCT_QUERY } from "@/lib/gql";
import { storefrontConfig } from "@/lib/config";
import { cacheTag } from 'next/cache'
import { createStorefrontClient } from "@shopify/hydrogen";

// A cacheable function for product data that can be revalidated on demand
export async function getProductData({ handle }) {
  "use cache";
  cacheTag(handle);

  const client = createStorefrontClient({
    type: "private_shared_rate_limit",
    config: storefrontConfig,
  });

  const { data } = await client.graphql(PRODUCT_QUERY, {
    variables: { handle },
  });

  return data
}

Shopify already supports these frameworks through its Headless sales channel, but until now we’ve each written our own bindings to the same API contract. At this layer, the fix is guidance, not more code. Humans and agents both need to know how to use what these frameworks already do, instead of reinventing it for Shopify.

That guidance ships as documentation, templates, and skills.

Code Example

---
name: enable-i18n
description: >
  Enable next-intl-based i18n in the shop template — locale-prefixed URLs,
  per-locale message catalogs, and a locale switcher. Use when the user wants
  "locale URLs", "multi-language", or "i18n" without Shopify Markets
  integration. For full Shopify Markets multi-region commerce (region-aware
  pricing, inventory, payments), use `enable-shopify-markets` instead — this
  skill is the routing/i18n layer only.
---

# Enable i18n (next-intl, no Markets)

Wire next-intl into the template so the storefront serves locale-prefixed
URLs (`/en-US/products/foo`), loads per-locale message catalogs, and exposes
a locale switcher. The template ships single-locale by default with clean
URLs (`/products/foo`) — this skill restores the i18n machinery.

## What this skill turns on

1. `lib/i18n/routing.ts` and `lib/i18n/navigation.ts` (next-intl)
2. Route segment `app/[locale]/` containing every page
3. `proxy.ts` middleware running `next-intl/middleware`
4. `lib/params.ts` `getLocale()` reading from `next/root-params`
5. `lib/i18n/request.ts` loading messages by resolved locale
6. Locale-prefixed canonicals + hreflang alternates in `lib/seo.ts`
7. Sitemap entries per locale
8. `next.config.ts` rewrites/redirects on `/:locale/*` sources
   …

# … (truncated)

A skill that teaches agents how to properly use i18n with Next.js App Router

[Editor’s note from the Hydrogen team: this code sample has been shortened for length. Vercel’s original post shows the skill in full as published; the current version lives in the vercel/shop repo.]

How does this relate to vercel.shop?

Before Hydrogen, we built vercel.shop, our own template for agentic commerce with Shopify, to make going headless with Next.js and Shopify easier.

It worked, and now we're going further. We'll fold everything we learned building vercel.shop into Hydrogen at the client and server layers. When Hydrogen is stable, vercel.shop adopts it and becomes our reference for building storefronts with Hydrogen and Next.js.

Going Forward

Vercel’s goal is simple: build a better web, for everyone.

With Hydrogen, that means the best developer experience without locking you into a runtime, framework, or platform.

We're building this in the open. Follow along on GitHub: try it, fork it, and help shape what comes next.

Get building

Spin up a new Hydrogen app in minutes.

See documentation