Deploy a Hydrogen storefront to Vercel in one click
June 30, 2026
Starting today, the Deploy to Vercel button automatically creates an example Next.js + Hydrogen storefront on Vercel. Go ahead, give it a try:
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