@weaverse/hydrogen 6. Once it’s in, merchants build pages visually in Weaverse Studio, edit theme settings, and use the sections you register.
Pick the guide that matches your project. Check
package.json (or run npm ls @shopify/hydrogen):A 2026.10 project has a
server.ts that composes the request lifecycle with handleShopifyRoutes(), and queries Shopify with storefront.graphql(). If yours still calls createHydrogenContext() or storefront.query(), it is classic Hydrogen.@weaverse/hydrogen 6.1. // ... marks omitted code. When a sample and Pilot disagree, Pilot main wins.
Prerequisites
- A Hydrogen 2026.10 storefront that runs locally (
@shopify/hydrogen^2026.10, React Router 7.18 or later 7.x, Vite 8). - Node.js
^22.18.0 || ^24.11.0, the range Pilot’senginesfield allows. - A Weaverse account and a Weaverse project for the storefront.
@shopify/cli4.4.0 or later as a dev dependency if you deploy to Oxygen (Step 10).
Step 1: Install the SDK
@weaverse/hydrogen 6 has @shopify/hydrogen >=2026.10.0 as a peer dependency, and depends on exactly @weaverse/react 6.1.0 and @weaverse/next 1.1.1. You don’t need to install those yourself. If your package.json already lists @weaverse/react or @weaverse/next, align them to those versions: two copies of @weaverse/react have separate React contexts, and components stop finding their data. From 6.2.0, @weaverse/hydrogen no longer depends on @weaverse/next, which is deprecated; remove it if your package.json lists it.
Hydrogen themes import everything from one entry point:
@weaverse/hydrogen entry holds schemas, data helpers and types without React or a router; you don’t need it in a Hydrogen theme.
Step 2: Configure Environment Variables
Add your project ID to.env:
HydrogenEnv, so env.d.ts lists every variable your theme reads. Extend the SDK’s WeaverseEnv, which declares the Weaverse variables:
Step 3: Add the Weaverse Files
Createapp/weaverse/. It holds the theme schema, the component registry, the global styles and the content renderer.
Theme Schema (app/weaverse/schema.server.ts)
The theme’s metadata, the global settings shown under Theme > Customize in Studio, and the i18n configuration:
DEFAULT_LOCALE and SUPPORTED_LOCALES are your market list (Pilot’s lives in app/utils/locale.ts). Pilot also sets translation: true and staticContent in i18n to turn on the Translation Manager, and keeps one file per settings group under app/weaverse/settings/.
Component Registry (app/weaverse/components.ts)
Every component Studio can place, each a module that exports a default component and a schema (and optionally a loader):
Global Styles (app/weaverse/style.tsx)
Turns theme settings into CSS variables:
Content Renderer (app/weaverse/index.tsx)
WeaverseContent renders the page a route loaded. validateWeaverseData turns a missing page into a 404, except in Studio’s design mode, where the editor needs the fallback page to start from:
Step 4: Create the WeaverseClient in the App Context
Hydrogen 2026.10 has no createHydrogenContext(). Your app builds the per-request values itself, usually in app/.server/context.ts, and server.ts puts them on React Router’s context. Add a WeaverseClient built from the request’s Storefront client:
createRequestStorefront, resolveRequestLocale and AppSession are app code: Pilot’s live in app/.server/storefront.ts and app/.server/session.ts, and Step 4 of the v6 migration guide walks through them. If your project already creates its Storefront client with createStorefrontClient(), pass that client; WeaverseClient only needs it per request.
WeaverseClient arguments:
The locale Option
Weaverse uses the request’s market for the locale it sends with page requests, the Translation Manager overrides it loads (keyed by ${language}-${country}, lowercased), and the requestInfo.i18n Studio reads. Without locale, it takes all three from storefront.i18n.
Pass locale when the Storefront client’s i18n.language is a Shopify LanguageCode that differs from the market’s public language. A Traditional Chinese Hong Kong market sends ZH_TW to Shopify; given to Weaverse, it asks for zh_tw-hk translations, which match nothing and silently fall back to the theme defaults. The value is a WeaverseI18n (language, country, and optional pathPrefix, label and other market fields); include pathPrefix, which Weaverse passes to Studio. Pilot passes resolveRequestLocale(request), the request’s entry from its market list. weaverse.storefront stays the request’s own client, so Shopify keeps receiving ZH_TW.
If storefront.i18n already carries the public language and the pathPrefix, leave locale out.
Step 5: Wire the Request Lifecycle in server.ts
In Hydrogen 2026.10, server.ts owns the request: it builds the context, lets Hydrogen’s handlers answer the routes they own, renders the app with React Router, and finishes the response. Weaverse only needs the context it puts on React Router to include weaverse. If your server.ts already copies the app context onto RouterContextProvider, adding weaverse to createAppContext() is enough.
Pilot’s server.ts, trimmed:
Object.assign(new RouterContextProvider(), appContext)keeps React Router’s context instance and adds your values to it. Don’t spread it into a plain object.handleShopifyRoutesdecides synchronously: it returns aPromise<Response>for a path one of its handlers owns, andnullotherwise.routeTemplatescomes fromcreateShopifyRouteTemplates()(app/utils/route-templates.tsin Pilot). Both it andapplyResponseHeaders()fail silently when missing.- Pilot’s full
server.tsadds its own cart, predictive search and Customer Account handlers, market-aware redirects and an HTTPS fix for tunnels. See Step 3 of the v6 migration guide.
Step 6: Cache Explicitly
Hydrogen 2026.10 has no default cache: astorefront.graphql() call without cache hits the Storefront API on every request. Pilot keeps its strategies in app/utils/cache.ts:
graphql() returns { data, errors } and doesn’t throw on GraphQL errors; Pilot’s unwrapStorefront() (app/utils/storefront.ts) throws instead, so a failed query reaches the route’s error boundary. See Data Fetching for query patterns.
Weaverse caches its own content in the cache you gave WeaverseClient: fresh for 60 seconds, then served stale for up to a day while it revalidates or when the Weaverse API fails. Studio’s design and preview modes skip the cache. To change it for one call, pass a strategy: context.weaverse.loadPage({ type, handle, strategy: CACHE_LONG }) or context.weaverse.loadThemeSettings(CACHE_LONG). For a third-party API in a section loader, weaverse.fetchWithCache(url, { ...init, strategy }) goes through the same cache; it replaces v5’s weaverse.withCache.
Pilot also sets Cache-Control per route with export const headers = routeHeaders from the same file, and keeps loaders free of per-shopper data so Oxygen can cache whole documents.
Step 7: Own the Content Security Policy
Hydrogen 2026.10 removescreateContentSecurityPolicy, NonceProvider and useNonce. The theme builds the header and the nonce itself, with two files from Pilot:
app/utils/csp.ts:generateNonce,createContentSecurityPolicy(nonce, directives, shop),NonceProvideranduseNonce, with the same header semantics as Hydrogen 2026.4’s helper. Copy it as is.app/weaverse/csp.ts:getWeaverseCsp(request, env), the directives Weaverse Studio and your third-party services need. In design mode it allows Studio to frame the storefront (frame-ancestors *) and adds'unsafe-eval'for the Studio bridge. Copy it and add your own sources.
app/entry.server.tsx, and pass the same nonce to the renderer, ServerRouter and NonceProvider:
context.env is typed because RouterContextProvider extends AppContext (Step 2). In app/entry.client.tsx, wrap <HydratedRouter /> in <NonceProvider value={existingNonce}>, reading the nonce from document.querySelector<HTMLScriptElement>("script[nonce]")?.nonce. Then pass useNonce() to <Scripts>, <ScrollRestoration> and <ShopifyScripts> in the root route. A dropped nonce leaves hydration silently dead. See Content Security Policy for each source and for rolling out an enforced policy.
Step 8: Wrap the Root Layout and Load Theme Settings
Weaverse wraps the component that renders the HTML document, which is theLayout export. The root loader must return the theme settings as weaverseTheme: withWeaverse and useThemeSettings() read them from the root route’s data.
- Wrap
Layout, not the defaultAppexport. WrappingAppleaves the Weaverse providers below the document, so theme settings and Studio’s design mode don’t initialize. withWeaversetakes no component list;WeaverseContentrenders the registered components.- Pilot’s root loader passes the theme through
localizedThemePayload()andneutralThemeWhenUnavailable()before returning it, and answersno-storewhen the settings failed to load (app/.server/root.tsandapp/weaverse/load-failure.ts). Start with the plain call and add those when you need them.
Step 9: Load Weaverse Pages in Your Routes
Hydrogen 2026.10 has nohydrogenRoutes(); app/routes.ts exports the route array directly. Add a catch-all so pages created in Studio resolve at any handle:
context.weaverse.loadPage() and render <WeaverseContent />. The homepage, from Pilot:
<WeaverseContent /> in Hydrogen’s ProductProvider, so every section shares one variant selection; see Step 9 of the v6 migration guide. WeaverseContent renders the page you loaded with the components from components.ts.
Step 10: Run, Connect and Deploy
- Start the dev server:
npm run dev. Pilot’s script isvite dev --port 3456; use the URL your terminal prints. - Open Weaverse Studio: go to your project at studio.weaverse.io.
- Set the Preview URL to your local dev server.
deploy script, with buildDirectory: "dist" in react-router.config.ts. The flags need @shopify/cli 4.4.0 or later. See Deploy to Oxygen.
Next Steps
Create Custom Components
Build React components that merchants can edit in Weaverse.
Data Fetching
Query Shopify from section loaders with
gql() and an explicit cache.WeaverseClient Reference
Every argument and method of the server-side client.
v6 Migration Guide
Move a classic Hydrogen storefront to Hydrogen 2026.10 and Weaverse 6.