关于 weaverse-hydrogen
weaverse-hydrogen 是面向 Shopify Hydrogen 店面的 Agent 技能,帮助开发者使用 Weaverse 可视化页面构建器开发店面。它涵盖组件结构、编辑器 Schema、数据获取、样式及路由集成,并提供文档查询脚本和离线参考。
主要功能
- 01构建 Weaverse 页面组件
- 02定义编辑器 Schema 与设置
- 03通过 Storefront API 获取数据
- 04配置主题样式与全局设置
- 05集成 Hydrogen 路由与页面加载
- 06查询在线文档并查阅离线参考
适用场景
- 01为 Hydrogen 店面创建可编辑页面区块
- 02配置组件的编辑器字段与可用页面
- 03加载 Shopify 商品或集合数据
- 04查找 Weaverse API 和组件开发指南
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ weaverse/ shopify-hydrogen-skills --skill weaverse-hydrogen安装后在 Claude Code 中输入/weaverse-hydrogen确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
examples/components-registry.tsfeatured-collection.tsxhero-banner.tsxproduct-card.tsxreferences/01-project-structure.md02-creating-components.md03-component-schema.md04-input-settings.md05-data-fetching.md06-styling-theming.md07-react-router-7.md08-hydrogen-fundamentals.md09-deployment.md10-weaverse-api.md11-advanced-features.md12-pilot-theme.md13-migration-v5.md14-sdk-caching-and-diagnostics.md详细介绍
Weaverse Hydrogen — Agent 技能
使用 Weaverse 可视化页面构建器构建 Shopify Hydrogen 店面。 文档:https://docs.weaverse.io | GitHub:https://github.com/Weaverse
在线文档
请在此技能自身的文件夹中运行以下命令。辅助脚本随同级的
shopify-hydrogen 技能一起提供,只要安装了完整的技能包,../shopify-hydrogen/scripts/ 就会存在。
如果你单独安装了此技能,该文件夹就不存在,以下命令会因 MODULE_NOT_FOUND 而失败。请添加一次辅助脚本:
npx skills add Weaverse/shopify-hydrogen-skills --skill shopify-hydrogen
此技能中的 references/ 文件仍可作为离线备用资料使用,如果你不想安装该技能。
如需获取最新的 Weaverse 文档,请使用以下脚本:
node ../shopify-hydrogen/scripts/search_weaverse_docs.mjs "<query>"— 搜索 Weaverse 文档node ../shopify-hydrogen/scripts/get_weaverse_page.mjs "<page-path>"— 获取指定页面(使用搜索结果中的路径)- Weaverse 文档:https://docs.weaverse.io
示例:
node ../shopify-hydrogen/scripts/search_weaverse_docs.mjs "component schema"
node ../shopify-hydrogen/scripts/search_weaverse_docs.mjs "data fetching"
node ../shopify-hydrogen/scripts/get_weaverse_page.mjs "development-guide/component-schema"
node ../shopify-hydrogen/scripts/get_weaverse_page.mjs "api-reference/weaverse-client"
以下参考文件提供离线背景信息,但可能无法反映最新更改。
什么是 Weaverse?
Weaverse 是适用于 Shopify Hydrogen 的可视化页面构建器。商家可以通过拖放式 Studio 自定义店面,开发者则可以构建类型安全的 React 组件,并使用定义编辑器 UI 的架构。
技术栈: React 19 · React Router v7 · Shopify Hydrogen · TypeScript · Tailwind CSS · Vite
1. 项目结构
app/
├── components/ # Reusable UI components
├── graphql/ # GraphQL queries & fragments
├── hooks/ # Custom React hooks
├── routes/ # React Router v7 route files
├── sections/ # Weaverse section components ← YOUR WORK GOES HERE
├── styles/ # Global styles + Tailwind
├── weaverse/
│ ├── components.ts # Component registry
│ ├── schema.server.ts # Theme schema (global settings)
│ └── csp.ts # Content Security Policy for Weaverse
├── entry.client.tsx
├── entry.server.tsx
└── root.tsx # Wrapped with withWeaverse(App)
server.ts # WeaverseClient initialization
vite.config.ts
react-router.config.ts
tailwind.config.js
.env
2. 组件结构
每个 Weaverse 组件最多可从单个文件(或目录)导出 3 项内容:
// app/sections/my-section/index.tsx
// 1. Default export — React component
function MySection(props: MySectionProps) { ... }
export default MySection;
// 2. Schema export — editor configuration
export let schema = createSchema({ ... });
// 3. Loader export (optional) — server-side data fetching
export let loader = async (args: ComponentLoaderArgs<DataType>) => { ... };
最简示例
import { createSchema } from '@weaverse/hydrogen';
import type { HydrogenComponentProps } from '@weaverse/hydrogen';
interface BannerProps extends HydrogenComponentProps {
heading: string;
description: string;
}
function Banner({ heading, description, children, ...rest }: BannerProps) {
return (
<section {...rest} className="py-16 px-4 text-center">
<h2 className="text-3xl font-bold">{heading}</h2>
<p className="mt-4 text-lg text-gray-600">{description}</p>
{children}
</section>
);
}
export default Banner;
export let schema = createSchema({
type: 'banner',
title: 'Banner',
settings: [
{
group: 'Content',
inputs: [
{ type: 'text', name: 'heading', label: 'Heading', defaultValue: 'Hello World' },
{ type: 'textarea', name: 'description', label: 'Description', defaultValue: 'Welcome to our store.' },
],
},
],
presets: {
heading: 'Hello World',
description: 'Welcome to our store.',
},
});
关键规则
- 根元素上必须展开
{...rest},以支持 Weaverse Studio 交互。 - 如果组件接受子组件(
childTypes),则必须渲染{children}。 - 在 React 19 中,
forwardRef是可选的。如果使用 React 18,请用forwardRef包装,并将ref附加到根元素上。 - 所有组件的
type必须唯一,并使用 kebab-case(例如,hero-banner)。
3. 组件注册
必须在 app/weaverse/components.ts 中注册组件:
import type { HydrogenComponent } from '@weaverse/hydrogen';
// MUST use namespace imports (import * as X), NOT default imports
import * as HeroBanner from '~/sections/hero-banner';
import * as FeaturedCollection from '~/sections/featured-collection';
import * as ProductCard from '~/sections/product-card';
export let components: HydrogenComponent[] = [
HeroBanner,
FeaturedCollection,
ProductCard,
];
常见错误: 使用 import HeroBanner from ...——这样无法正常工作。请始终使用 import * as HeroBanner from ...。
4. 使用 createSchema() 定义架构
import { createSchema } from '@weaverse/hydrogen';
export let schema = createSchema({
type: 'my-component', // Unique kebab-case identifier
title: 'My Component', // Display name in Studio
limit: 1, // Max instances per page (optional)
enabled: ({ page, group }) => // Dynamic insertion availability (optional)
['PRODUCT', 'COLLECTION'].includes(page.type) && group === 'body',
settings: [ // Editor UI groups
{
group: 'Content',
inputs: [
{ type: 'text', name: 'heading', label: 'Heading', defaultValue: 'Title' },
{ type: 'richtext', name: 'body', label: 'Body' },
{ type: 'image', name: 'image', label: 'Image' },
{
type: 'select', name: 'layout', label: 'Layout',
configs: {
options: [
{ value: 'grid', label: 'Grid' },
{ value: 'list', label: 'List' },
],
},
defaultValue: 'grid',
},
],
},
],
childTypes: ['product-card', 'button'], // Allowed child component types
presets: { // Defaults when component is added to page
heading: 'Title',
layout: 'grid',
children: [
{ type: 'product-card' },
{ type: 'product-card' },
],
},
});
inspector 已弃用——请始终使用 settings。
enabledOn 已弃用——请将页面/分组检查移至 enabled。此回调为同步函数,在店面预览中运行,并接收 { page: { id, type, handle, locale }, group }。错误、Promise 和非布尔值会阻止新插入组件的显示,但不会影响已有实例。Studio 目前会评估 body 分组。
enabled 的页面类型: INDEX、PRODUCT、ALL_PRODUCTS、COLLECTION、COLLECTION_LIST、PAGE、BLOG、ARTICLE、CUSTOM
5. 输入类型(速查)
| 类型 | 返回值 | 用途 |
|---|---|---|
text | string | 单行文本 |
textarea | string | 多行文本 |
richtext | string (HTML) | 带格式的富文本 |
url | string | URL/链接 |
image | WeaverseImage object | 从 Shopify Files 选择图片 |
video | WeaverseVideo object | 从 Shopify Files 选择视频 |
color | string (#hex) | 颜色选择器 |
range | number | 滑块(需要 configs: { min, max, step }) |
switch | boolean | 开关 |
select | string | 下拉菜单(需要 configs: { options }) |
toggle-group | string | 按钮组(需要 configs: { options }) |
heading | — | 设置面板中的分区标题(无数据) |
datepicker | number (timestamp) | 日期/时间选择器 |
product | Shopify product | 商品选择器 |
collection | Shopify collection | 集合选择器 |
blog | Shopify blog | 博客选择器 |
article | Shopify article | 文章选择器 |
metaobject | Shopify metaobject | Metaobject 选择器 |
product-list | Shopify products[] | 多商品选择器 |
collection-list | Shopify collections[] | 多集合选择器 |
→ 完整详情:references/04-input-settings.md
6. 数据获取
import type { ComponentLoaderArgs, HydrogenComponentProps } from '@weaverse/hydrogen';
type MyData = { collectionHandle: string };
export let loader = async ({ weaverse, data }: ComponentLoaderArgs<MyData>) => {
let { storefront } = weaverse;
return await storefront.query(COLLECTION_QUERY, {
variables: { handle: data.collectionHandle },
});
};
// Derive props type from loader return
type Props = HydrogenComponentProps<Awaited<ReturnType<typeof loader>>> & MyData;
function MyComponent({ loaderData, ...rest }: Props) {
let collection = loaderData?.collection;
return <section {...rest}>{collection?.title}</section>;
}
export default MyComponent;
关键模式:
weaverse.storefront.query()— Shopify Storefront APIweaverse.fetchWithCache(url, options)— 带缓存的外部 APIPromise.all([...])— 并行获取- 在会影响 loader 的架构输入上设置
shouldRevalidate: true
→ 完整详情:references/05-data-fetching.md
7. 样式与主题
Tailwind CSS 是主要的样式方案。
全局主题设置定义在 app/weaverse/schema.server.ts 中,并通过 CSS 变量应用:
// app/components/GlobalStyle.tsx
import { useThemeSettings } from '@weaverse/hydrogen';
export function GlobalStyle() {
let settings = useThemeSettings();
if (!settings) return null;
return (
<style dangerouslySetInnerHTML={{ __html: `
:root {
--color-primary: ${settings.colorPrimary};
--body-base-size: ${settings.bodyBaseSize}px;
--heading-base-size: ${settings.headingBaseSize}px;
}
`}} />
);
}
组件变体使用 CVA (Class Variance Authority):
import { cva } from 'class-variance-authority';
let buttonVariants = cva('inline-flex items-center rounded font-medium', {
variants: {
variant: { primary: 'bg-blue-600 text-white', secondary: 'bg-gray-200' },
size: { sm: 'h-8 px-3 text-sm', md: 'h-10 px-4', lg: 'h-12 px-6' },
},
defaultVariants: { variant: 'primary', size: 'md' },
});
→ 完整详情:references/06-styling-theming.md
8. Weaverse API(关键 Hooks 与工具)
| API | 用途 |
|---|---|
createSchema() | 使用 Zod 验证定义组件架构 |
WeaverseClient | 服务端客户端(在 server.ts 中初始化) |
weaverse.loadPage({ type, handle }) | 在路由 loader 中加载页面数据 |
weaverse.loadThemeSettings() | 加载全局主题设置 |
weaverse.fetchWithCache(url) | 获取并缓存外部 API 数据 |
withWeaverse(App) | 在 root.tsx 中包装根 App 的高阶组件 |
useWeaverse() | 访问全局 Weaverse 实例 |
useThemeSettings() | 访问全局主题设置 |
useItemInstance() | 访问特定组件实例 |
useParentInstance() | 访问父组件实例 |
useChildInstances() | 访问子组件实例 |
→ 完整详情:references/10-weaverse-api.md
9. 服务端设置(server.ts)
import { WeaverseClient } from '@weaverse/hydrogen';
import { components } from '~/weaverse/components';
import { themeSchema } from '~/weaverse/schema.server';
export async function createAppLoadContext(request, env, executionContext) {
let hydrogenContext = createHydrogenContext({ env, request, cache, waitUntil, session, /* ... */ });
return {
...hydrogenContext,
weaverse: new WeaverseClient({
...hydrogenContext,
request,
cache,
themeSchema,
components,
}),
};
}
10. 路由集成
// app/routes/($locale)._index.tsx
import { WeaverseHydrogenRoot } from '@weaverse/hydrogen';
export async function loader({ context }: LoaderFunctionArgs) {
let weaverseData = await context.weaverse.loadPage({ type: 'INDEX' });
return { weaverseData };
}
export default function Homepage() {
return <WeaverseHydrogenRoot />;
}
对于商品页面:
export async function loader({ context, params }: LoaderFunctionArgs) {
let weaverseData = await context.weaverse.loadPage({
type: 'PRODUCT',
handle: params.productHandle,
});
return { weaverseData, /* other data */ };
}
参考索引
如需详细了解特定主题,请阅读以下参考文件:
| # | 文件 | 主题 |
|---|---|---|
| 01 | references/01-project-structure.md | 项目结构与文件组成 |
| 02 | references/02-creating-components.md | 组件创建与注册 |
| 03 | references/03-component-schema.md | createSchema()、设置、childTypes、预设、enabled |
| 04 | references/04-input-settings.md | 所有输入类型与配置 |
| 05 | references/05-data-fetching.md | 加载器、Storefront API、缓存 |
| 06 | references/06-styling-theming.md | Tailwind、主题设置、CVA、CSS 变量 |
| 07 | references/07-react-router-7.md | React Router v7 约定 |
| 08 | references/08-hydrogen-fundamentals.md | Hydrogen 框架基础知识 |
| 09 | references/09-deployment.md | Oxygen、Docker、环境变量 |
| 10 | references/10-weaverse-api.md | 所有钩子与 WeaverseClient API |
| 11 | references/11-advanced-features.md | 本地化、数据连接器、CSP |
| 12 | references/12-pilot-theme.md | Pilot 主题模式与约定 |
| 13 | references/13-migration-v5.md | 从 Remix 迁移到 React Router v7 |
| 14 | references/14-sdk-caching-and-diagnostics.md | SDK 5.15.x 缓存、Builder 诊断标头、嵌套多实例页面、客户端升级 |
示例
| 文件 | 内容 |
|---|---|
| examples/hero-banner.tsx | 包含架构、设置组、childTypes 和预设的完整区块 |
| examples/featured-collection.tsx | 包含加载器和 Storefront API 查询的区块 |
| examples/product-card.tsx | 子组件示例 |
| examples/components-registry.ts | 注册模式 |