Skip to main content

Hydrogen とヘッドレスコマース

すべてのストアフロントが Liquid テーマモデルに適合するわけではありません。ブランドがピクセルパーフェクトなカスタムデザイン、アプリのようなインタラクティビティ、または Shopify 以外のデータソースとの統合を必要とする場合、ヘッドレスを選択します。Hydrogen は Shopify の答えです -- ヘッドレス Shopify コマース専用に構築された、Remix をベースとした React フレームワークです。このレッスンでは、Hydrogen をいつ、どのように使用するか、そのアーキテクチャ、最初のヘッドレスストアフロントの構築方法をカバーします。

ヘッドレスコマースとは?

従来の Shopify セットアップでは、ストアフロント(顧客が見るもの)とバックエンド(データが存在する場所)は密結合されています。Shopify はサーバー上で Liquid テンプレートをレンダリングし、完全な HTML ページを配信します。

ヘッドレスコマースでは、ストアフロントがバックエンドから分離されます。カスタムフロントエンドが Storefront API を通じて Shopify からデータを取得し、任意の方法で UI をレンダリングします。Shopify は引き続き商品、注文、チェックアウト、決済を処理します -- あなたはプレゼンテーションレイヤーのみを制御します。

Hydrogen vs Liquid テーマの使い分け

シナリオ推奨
標準的な EC ストアLiquid テーマ
マーチャントがテーマエディターでコンテンツ管理Liquid テーマ
予算を抑えたプロジェクトLiquid テーマ
完全にカスタムなデザインシステムHydrogen
アプリのようなインタラクション(アニメーション、トランジション)Hydrogen
マルチソースコンテンツ(CMS + Shopify + カスタム API)Hydrogen
React の専門知識を持つ開発チームHydrogen
1つの Shopify バックエンドから複数のストアフロントHydrogen
高パフォーマンス要件(ストリーミング SSR)Hydrogen
ほとんどのストアは Liquid を使うべき

Hydrogen は強力ですが、常に正しい選択とは限りません。Liquid テーマは構築が速く、マーチャントが保守しやすく、ユースケースの90%をカバーします。Liquid では対応できない具体的なニーズがあり、React アプリケーションを長期的にサポートできるチームがある場合に Hydrogen を選択してください。

Hydrogen アーキテクチャ

Hydrogen はフルスタック React フレームワークである Remix の上に構築されています。Remix を知っていれば、Hydrogen のほとんどを既に知っています。Shopify はコマース固有のユーティリティレイヤーを追加しています。

主要な Hydrogen パッケージ

  • @shopify/hydrogen: コアコマースコンポーネントとユーティリティ(Cart、Analytics、SEO、Money、Image)
  • @shopify/hydrogen-react: フレームワーク非依存の Shopify 用 React フック(Hydrogen 外でも使用可能)
  • @shopify/remix-oxygen: Oxygen ホスティング用の Remix アダプター
  • @shopify/cli-hydrogen: Hydrogen プロジェクトの作成と管理用 CLI コマンド

Hydrogen プロジェクトの作成

# 新しい Hydrogen ストアフロントを作成
npm create @shopify/hydrogen@latest -- --template demo-store

# CLI のプロンプト:
# ? Where would you like to create your app? hydrogen-store
# ? Choose a language: TypeScript
# ? Connect to Shopify: Use mock.shop (or connect your store)

プロジェクト構造

hydrogen-store/
├── app/
│ ├── components/ # 再利用可能な UI コンポーネント
│ │ ├── Header.tsx
│ │ ├── Footer.tsx
│ │ ├── ProductCard.tsx
│ │ └── CartDrawer.tsx
│ ├── routes/ # ファイルベースルーティング(Remix)
│ │ ├── ($locale)._index.tsx # ホームページ
│ │ ├── ($locale).products.$handle.tsx # 商品ページ
│ │ ├── ($locale).collections.$handle.tsx
│ │ ├── ($locale).cart.tsx
│ │ ├── ($locale).account.tsx
│ │ └── [sitemap.xml].tsx
│ ├── lib/
│ │ └── fragments.ts # 再利用可能な GraphQL フラグメント
│ ├── styles/
│ │ └── app.css
│ ├── entry.server.tsx # サーバーエントリーポイント
│ └── root.tsx # ルートレイアウト
├── public/
│ └── favicon.svg
├── server.ts # Oxygen/Node サーバー
├── storefrontapi.generated.d.ts # 自動生成された型定義
├── .env # 環境変数
└── hydrogen.config.ts # Hydrogen 設定

Storefront API 統合

Hydrogen はすべてのデータ取得に Storefront API を使用します。API クライアントはサーバーエントリーでセットアップされ、Remix コンテキストを通じてルートローダーに渡されます。

クライアントの設定

// server.ts
import {createStorefrontClient} from '@shopify/hydrogen';

const {storefront} = createStorefrontClient({
storeDomain: env.PUBLIC_STORE_DOMAIN,
publicStorefrontToken: env.PUBLIC_STOREFRONT_API_TOKEN,
privateStorefrontToken: env.PRIVATE_STOREFRONT_API_TOKEN,
storefrontApiVersion: '2026-04',
});

ルートローダーでのデータ取得

Hydrogen は Remix のパターンに従い、サーバーで実行されるローダー関数でデータをロードします:

// app/routes/($locale).products.$handle.tsx
import {json, type LoaderFunctionArgs} from '@shopify/remix-oxygen';
import {useLoaderData} from '@remix-run/react';
import {Image, Money, ShopPayButton} from '@shopify/hydrogen';

const PRODUCT_QUERY = `#graphql
query Product($handle: String!) {
product(handle: $handle) {
id
title
description
descriptionHtml
vendor
tags
featuredImage {
url
altText
width
height
}
priceRange {
minVariantPrice {
amount
currencyCode
}
}
variants(first: 100) {
nodes {
id
title
availableForSale
price {
amount
currencyCode
}
selectedOptions {
name
value
}
image {
url
altText
width
height
}
}
}
seo {
title
description
}
}
}
`;

export async function loader({params, context}: LoaderFunctionArgs) {
const {handle} = params;
const {storefront} = context;

const {product} = await storefront.query(PRODUCT_QUERY, {
variables: {handle},
cache: storefront.CacheLong(),
});

if (!product) {
throw new Response('Product not found', {status: 404});
}

return json({product});
}

export default function ProductPage() {
const {product} = useLoaderData<typeof loader>();
const firstVariant = product.variants.nodes[0];

return (
<div className="product-page">
<div className="product-grid">
<div className="product-image">
{product.featuredImage && (
<Image
data={product.featuredImage}
sizes="(min-width: 768px) 50vw, 100vw"
/>
)}
</div>

<div className="product-info">
<h1>{product.title}</h1>
<p className="vendor">{product.vendor}</p>

<Money
data={firstVariant.price}
className="product-price"
/>

<div
className="product-description"
dangerouslySetInnerHTML={{
__html: product.descriptionHtml,
}}
/>

<ShopPayButton
variantIds={[firstVariant.id]}
storeDomain={context.env.PUBLIC_STORE_DOMAIN}
/>
</div>
</div>
</div>
);
}

キャッシュ戦略

Hydrogen はパフォーマンスに不可欠な組み込みキャッシュユーティリティを提供します:

// Storefront クライアントで利用可能なキャッシュ戦略
storefront.query(query, {
cache: storefront.CacheNone(), // キャッシュなし(リアルタイムデータ)
cache: storefront.CacheShort(), // 1秒 stale、60秒最大
cache: storefront.CacheLong(), // 1時間 stale、1日最大
cache: storefront.CacheCustom({
mode: 'public',
maxAge: 60, // 秒
staleWhileRevalidate: 300,
}),
});
キャッシュ戦略のガイドライン
  • 商品ページ: CacheLong() -- 商品データはあまり変更されない
  • コレクションページ: CacheLong() -- 商品と同様
  • カート: CacheNone() -- 常にリアルタイムである必要がある
  • 検索結果: CacheShort() -- 新鮮だが短い遅延は許容
  • ホームページ: CacheLong() + コンテンツ変更時の手動無効化

サーバーサイドレンダリングとストリーミング

Hydrogen は Remix のストリーミング SSR を活用して高速な初期ページロードを実現します。すべてのデータが解決されるまで HTML の送信を待つ代わりに、サーバーは HTML シェルを即座にストリーミングし、データが到着するにつれて動的コンテンツを埋めていきます。

// app/routes/($locale).collections.$handle.tsx
import {defer, type LoaderFunctionArgs} from '@shopify/remix-oxygen';
import {Await, useLoaderData} from '@remix-run/react';
import {Suspense} from 'react';

export async function loader({params, context}: LoaderFunctionArgs) {
const {handle} = params;
const {storefront} = context;

// クリティカルデータ:即座に await
const collection = await storefront.query(COLLECTION_QUERY, {
variables: {handle, first: 12},
});

// ノンクリティカルデータ:ストリーミング用に defer
const recommendations = storefront.query(RECOMMENDATIONS_QUERY, {
variables: {handle},
});

return defer({
collection: collection.collection,
recommendations, // これは Promise で、await されていない
});
}

export default function CollectionPage() {
const {collection, recommendations} = useLoaderData<typeof loader>();

return (
<div>
<h1>{collection.title}</h1>

{/* クリティカルコンテンツは即座にレンダリング */}
<ProductGrid products={collection.products.nodes} />

{/* 遅延コンテンツは準備ができたらストリーミング */}
<Suspense fallback={<RecommendationsSkeleton />}>
<Await resolve={recommendations}>
{(data) => (
<RecommendedProducts products={data.products.nodes} />
)}
</Await>
</Suspense>
</div>
);
}

このパターンにより、一部のデータの読み込みに時間がかかっても、顧客はミリ秒以内に意味のあるコンテンツを見ることができます。

Oxygen ホスティング

Oxygen は Hydrogen ストアフロント専用に構築された Shopify のエッジホスティングプラットフォームです。

デプロイメント

Oxygen は自動デプロイのために GitHub と統合されています:

  1. Shopify 管理画面の 販売チャネル > Hydrogen で GitHub リポジトリを接続
  2. メインブランチにプッシュ -- Oxygen が自動デプロイ
  3. 他のブランチにプッシュ -- Oxygen がプレビューデプロイを作成
# Shopify CLI による手動デプロイ
shopify hydrogen deploy

環境変数

Shopify 管理画面または CLI を通じて環境変数を管理:

# 本番環境の環境変数を設定
shopify hydrogen env push

# ローカルの .env に環境変数をプル
shopify hydrogen env pull

Oxygen を選ぶ理由

  • 設定不要: サーバーセットアップ、CDN 設定、スケーリング判断が不要
  • グローバルエッジネットワーク: ワーカーが世界中の顧客の近くで実行
  • Shopify 最適化: Shopify の Storefront API への最低レイテンシーパス
  • プレビューデプロイ: すべてのブランチがレビュー用の固有 URL を取得
  • 組み込みアナリティクス: Shopify 管理画面でのパフォーマンスモニタリング
Oxygen は必須ではない

Hydrogen は任意の Node.js ホスティングプロバイダー(Vercel、Netlify、Cloudflare Workers、Fly.io、または自前のサーバー)にデプロイできます。Oxygen は便利で Shopify に最適化されていますが、ロックインではありません。

スターターテンプレート

Shopify はいくつかの Hydrogen スターターテンプレートを提供しています:

テンプレート説明
demo-storeすべてのページを含むフル機能ストアフロント
hello-world最小限のスタートポイント
skeletonルーティング付き基本構造、スタイリングなし
# 特定のテンプレートから作成
npm create @shopify/hydrogen@latest -- --template demo-store

# またはクローンしてカスタマイズ
npm create @shopify/hydrogen@latest -- --template skeleton

demo-store テンプレートには、商品ページ、コレクションページ、カート機能、カスタマーアカウント、検索、ブログ、SEO が含まれています -- カスタマイズ可能な完全なストアフロントです。

重要なポイント

  • Hydrogen はヘッドレス Shopify ストアフロントを構築するための React + Remix フレームワークです
  • 完全なデザインコントロール、React の専門知識、またはマルチソースデータ統合が必要な場合に使用します
  • Storefront API がデータレイヤーです -- ルートローダー内の型付き GraphQL クエリを通じてアクセスします
  • deferAwait によるストリーミング SSR で高速な初期ページロードを実現します
  • Oxygen は GitHub 統合とプレビューデプロイメントを備えたゼロコンフィグのエッジホスティングを提供します
  • ほとんどのストアは Liquid テーマを使用すべきです -- Hydrogen は特定のハイエンドユースケース向けです

次は、Shopify Functions を探ります -- Shopify のインフラストラクチャ内でコマースロジックを直接カスタマイズできる WebAssembly ランタイムです。