Commerce-Backend: Shopify (Admin/Storefront APIs), Daten via GraphQL API.
Theme-Layer: Shopify Themes mit Liquid Templating für Inhalte/Pages, die (noch) nicht headless migriert sind oder bewusst im Theme bleiben.
Best Practice: Lege Integrationsgrenzen fest (welche Routen laufen in Hydrogen vs. Theme), um Doppelpflege und SEO-Risiken zu vermeiden (Canonical, Redirects, Sitemap-Ownership).
Feature
Details
Rendering-Strategie
Hydrogen: SSR/Streaming an der Edge (Oxygen). Theme: Liquid server-rendered im Shopify-Stack.
type GraphQLErrorItem = {
message: string;
extensions?: Record<string, unknown>;
};
type GraphQLResponse<T> = {
data?: T;
errors?: GraphQLErrorItem[];
};
type MoneyV2 = {
amount: string;
currencyCode: string;
};
type Image = {
url: string;
altText?: string | null;
width?: number | null;
height?: number | null;
};
type Product = {
id: string;
handle: string;
title: string;
description: string;
featuredImage?: Image | null;
priceRange: {
minVariantPrice: MoneyV2;
};
};
type ProductByHandleData = {
productByHandle: Product | null;
};
const PRODUCT_BY_HANDLE_QUERY = `#graphql
query ProductByHandle($handle: String!) {
productByHandle(handle: $handle) {
id
handle
title
description
featuredImage {
url
altText
width
height
}
priceRange {
minVariantPrice {
amount
currencyCode
}
}
}
}
`;
type StorefrontClientOptions = {
storeDomain: string;
storefrontAccessToken: string;
apiVersion: string;
};
export class StorefrontGraphQLClient {
private endpoint: string;
private token: string;
constructor(private opts: StorefrontClientOptions) {
this.endpoint = `https://${opts.storeDomain}/api/${opts.apiVersion}/graphql.json`;
this.token = opts.storefrontAccessToken;
}
async request<T>(query: string, variables?: Record<string, unknown>): Promise<T> {
const res = await fetch(this.endpoint, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Shopify-Storefront-Access-Token': this.token,
},
body: JSON.stringify({ query, variables }),
});
if (!res.ok) {
const text = await res.text();
throw new Error(`Storefront API HTTP ${res.status}: ${text}`);
}
const payload = (await res.json()) as GraphQLResponse<T>;
if (payload.errors?.length) {
// GraphQL kann data + errors liefern; je nach Use Case entscheiden
const messages = payload.errors.map((e) => e.message).join('; ');
throw new Error(`Storefront GraphQL errors: ${messages}`);
}
if (!payload.data) {
throw new Error('Storefront GraphQL response missing data');
}
return payload.data;
}
}
export async function getProductByHandle(handle: string) {
const client = new StorefrontGraphQLClient({
storeDomain: process.env.SHOPIFY_STORE_DOMAIN as string,
storefrontAccessToken: process.env.SHOPIFY_STOREFRONT_TOKEN as string,
apiVersion: '2025-01',
});
const data = await client.request<ProductByHandleData>(PRODUCT_BY_HANDLE_QUERY, { handle });
if (!data.productByHandle) {
return { status: 404 as const, product: null };
}
return { status: 200 as const, product: data.productByHandle };
}
Oxygen-spezifisch: In Hydrogen/Oxygen arbeitest du typischerweise mit Edge-Caching (z. B. kurze TTL + SWR). Plane das Query-Design so, dass du Cache-Hit-Rates erhöhst (stabile Query-Keys, konsistente Variablen, getrennte Queries für personalisierte Inhalte).
3) Liquid Templating: Wann Themes sinnvoll sind (und wie du sauber integrierst)
Liquid Templating ist die Template-Sprache von Shopify Themes. Sie rendert serverseitig im Shopify-Theme-Stack und hat direkten Zugriff auf Theme-Objekte (z. B. product, collection, cart) abhängig vom Template-Kontext.
3.1 Best Practices für Liquid in hybriden Architekturen
Klare Ownership pro URL: Eine Route gehört entweder dem Theme oder Hydrogen (nicht beides). Für Migrationen setze 301-Redirects.
Composable Sections: Nutze Sections/Blocks für Marketing-Seiten, die schnell iterieren müssen.
App Proxy / Headless Widgets: Wenn Hydrogen Daten/HTML liefern soll, kapsle es über stabile Endpunkte und integriere im Theme gezielt (nicht als „Spaghetti“).
Zu viel Logik im Template: Liquid ist bewusst eingeschränkt; komplexe Logik gehört in Apps/Services.
Performance: Viele include/snippet-Aufrufe und große Loops können Theme-Rendering verlangsamen.
Unklare Datenquelle: Wenn Produktdaten sowohl via GraphQL in Hydrogen als auch via Liquid gerendert werden, entstehen Inkonsistenzen (Preis, Verfügbarkeit, Metafields).
Oxygen Deployment sollte wie ein modernes Web-Produkt betrieben werden: reproduzierbar, getestet, mit klaren Umgebungen. Best Practices:
Preview Deployments pro PR: Stakeholder können Features prüfen, ohne Produktion zu riskieren.
Environment Variables: Tokens/Keys ausschließlich als Secrets; nie ins Repo.
Rollback-Strategie: Versionierte Releases; im Fehlerfall auf vorheriges Deployment zurück.
Observability: Error-Tracking + Performance-Metriken (TTFB, Cache Hit Rate, GraphQL Latency).
Screenshot der Oxygen Deployments Übersicht in Shopify Admin bzw. Hydrogen Deployment UI mit Preview/Production Status
5) YAML Deployment Script: CI für Hydrogen auf Oxygen
Ein CI-Workflow sollte: Dependencies installieren, TypeScript builden, Tests ausführen und anschließend deployen. Das folgende Beispiel zeigt eine typische Pipeline-Struktur, die du an deine Oxygen/Shopify-Hydrogen-Deploy-Mechanik anpasst (z. B. via Shopify CLI und passende Tokens).
YAML: CI Pipeline für Build & Oxygen Deployment
name: hydrogen-oxygen-deploy
on:
push:
branches:
- main
pull_request:
branches:
- main
jobs:
build-and-deploy:
runs-on: ubuntu-latest
permissions:
contents: read
env:
SHOPIFY_STORE_DOMAIN: ${{ secrets.SHOPIFY_STORE_DOMAIN }}
SHOPIFY_STOREFRONT_TOKEN: ${{ secrets.SHOPIFY_STOREFRONT_TOKEN }}
OXYGEN_DEPLOY_TOKEN: ${{ secrets.OXYGEN_DEPLOY_TOKEN }}
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Typecheck
run: npm run typecheck
- name: Unit tests
run: npm test
- name: Build
run: npm run build
- name: Deploy to Oxygen (main only)
if: github.ref == 'refs/heads/main'
run: |
npm run deploy:oxygen
env:
OXYGEN_DEPLOY_TOKEN: ${{ secrets.OXYGEN_DEPLOY_TOKEN }}
Theme Governance: Liquid nur für das, was bewusst im Theme bleibt; keine „halb-headless“ Doppelquellen.
8) Wann du eine externe Umsetzung brauchst
Wenn du die Trennung von Shopify Hydrogen, Shopify Themes und Oxygen Deployment sauber aufsetzen willst (inkl. Query-Design, Caching und CI), lohnt sich ein Setup-Workshop mit klaren Deliverables (Routenplan, Datenmodell, Deployment-Blueprint). Mehr dazu auf der Seite Shopify Agentur.
Häufig gestellte Fragen
Was ist der größte Vorteil von Shopify Oxygen gegenüber klassischem Hosting?
<p>Oxygen bringt Hydrogen nah an den Nutzer (Edge Runtime), wodurch SSR/Streaming schneller wird und du Caching sowie Deployments speziell für Headless-Storefronts standardisieren kannst. Das reduziert Latenzen und vereinfacht Release-Prozesse.</p>
Warum sollte ich in Hydrogen primär die GraphQL API nutzen?
<p>Mit der GraphQL API fragst du exakt die Felder ab, die du im UI brauchst. Das verbessert Performance, reduziert Payloads und macht Frontend-Entwicklung planbarer (z. B. via TypeScript-Typisierung/Codegen).</p>
Wann ist Liquid Templating weiterhin die bessere Wahl?
<p>Für stark content-getriebene Seiten, schnelle Marketing-Iterationen und Bereiche, die bewusst im Shopify-Theme-Ökosystem bleiben sollen (Sections/Theme Editor), ist Liquid Templating oft effizienter als eine Headless-Neuentwicklung.</p>
Kann ich Shopify Themes und Hydrogen parallel betreiben?
<p>Ja, als hybride Architektur. Wichtig ist, dass jede Route eine klare Zuständigkeit hat (Theme oder Hydrogen) und SEO-relevante Signale (Canonical, Redirects, Structured Data) nicht doppelt oder widersprüchlich ausgeliefert werden.</p>
Wie vermeide ich Performance-Probleme durch zu viele GraphQL Calls?
<p>Nutze Fragments, begrenze Felder, implementiere Pagination und setze konsequentes Caching (Edge TTL/SWR). Zusätzlich helfen konsistente Query-Keys und das Vermeiden von personalisierten Queries auf Cache-kritischen Seiten.</p>
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "FAQPage",
"mainEntity": [
{
"@type": "Question",
"name": "Was ist der größte Vorteil von Shopify Oxygen gegenüber klassischem Hosting?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Oxygen bringt Hydrogen nah an den Nutzer (Edge Runtime), wodurch SSR/Streaming schneller wird und du Caching sowie Deployments speziell für Headless-Storefronts standardisieren kannst. Das reduziert Latenzen und vereinfacht Release-Prozesse."
}
},
{
"@type": "Question",
"name": "Warum sollte ich in Hydrogen primär die GraphQL API nutzen?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Mit der GraphQL API fragst du exakt die Felder ab, die du im UI brauchst. Das verbessert Performance, reduziert Payloads und macht Frontend-Entwicklung planbarer (z. B. via TypeScript-Typisierung/Codegen)."
}
},
{
"@type": "Question",
"name": "Wann ist Liquid Templating weiterhin die bessere Wahl?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Für stark content-getriebene Seiten, schnelle Marketing-Iterationen und Bereiche, die bewusst im Shopify-Theme-Ökosystem bleiben sollen (Sections/Theme Editor), ist Liquid Templating oft effizienter als eine Headless-Neuentwicklung."
}
},
{
"@type": "Question",
"name": "Kann ich Shopify Themes und Hydrogen parallel betreiben?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Ja, als hybride Architektur. Wichtig ist, dass jede Route eine klare Zuständigkeit hat (Theme oder Hydrogen) und SEO-relevante Signale (Canonical, Redirects, Structured Data) nicht doppelt oder widersprüchlich ausgeliefert werden."
}
},
{
"@type": "Question",
"name": "Wie vermeide ich Performance-Probleme durch zu viele GraphQL Calls?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Nutze Fragments, begrenze Felder, implementiere Pagination und setze konsequentes Caching (Edge TTL/SWR). Zusätzlich helfen konsistente Query-Keys und das Vermeiden von personalisierten Queries auf Cache-kritischen Seiten."
}
}
]
}
</script>"
}
Konkrete Schritte, um Shopify-Kosten beim Store-Aufbau zu senken: Shopify Pricing Tiers (Shopify Basic Plan bis Shopify Plus), Third-party App Costs, Third-party integrations, Theme-Setup mit JSON und App-Integration mit TypeScript. Inkl. Tabelle, Mermaid-Diagramm, FAQs + FAQPage Schema.