Warum wir unseren Shopify-Checkout von Liquid-Hacks zu Checkout Extensibility migriert haben

Die Checkout-Zeitbombe
Drei Jahre lang lief unser Shopify Plus Checkout auf einem brüchigen Patchwork aus checkout.liquid-Overrides, Drittpartei-Skripten und Shopify Scripts, das niemand besitzen wollte. Der Checkout sah maßgeschneidert aus, aber die Umsetzung war eine latente Gefahr. Jedes Shopify-Update bedeutete einen halbtägigen Diff-Review. Jede neue Zahlungsmethode erforderte einen erneuten Test des gesamten Funnels. Und als Shopify die Abschaffung von checkout.liquid-Anpassungen auf den Information-, Versand- und Zahlungsseiten ankündigte, hatten wir eine harte Deadline, die wir nicht verhandeln konnten.
Wir hatten zwei Optionen: Den Legacy-Ansatz forcieren und gegen die Plattform arbeiten, oder Checkout Extensibility als erstklassiges Architekturproblem behandeln. Wir entschieden uns für Letzteres. Die Migration dauerte sechs Wochen, entfernte 2.400 Zeilen Liquid und JavaScript und gab uns einen Checkout, der schneller, testbarer und einfacher erweiterbar ist.
Was uns checkout.liquid gekostet hat
Der Checkout ist die Seite mit dem höchsten Hebel in jedem E-Commerce-Store. Eine Sekunde Verzögerung kann die Conversion um mehrere Prozentpunkte drücken. Unsere checkout.liquid-Datei war zu einem Monolithen gewachsen, der Layout, Tracking, Betrugsprüfungen, Upsells und benutzerdefinierte Feldvalidierungen steuerte. Das Problem war nicht ihre Größe, sondern dass sie nicht mehr beherrschbar war.
Wir hatten keine saubere Trennung zwischen Präsentation und Geschäftslogik. A/B-Tests wurden durch bedingtes Rendern von Script-Tags auf Basis von Warenkorbattributen umgesetzt. Vertrauensabzeichen wurden per DOM-Manipulation injiziert, die immer dann zerbrach, wenn Shopify Klassennamen änderte. Und weil die Datei über Märkte hinweg geteilt war, riskierte eine Änderung für eine Region Regressionen überall.
Schlimmer noch: checkout.liquid läuft synchron in jedem Checkout-Schritt. Ein Skript, das das Rendering blockierte, machte jeden Shopper langsamer, nicht nur diejenigen, die das Feature brauchten. Wir hatten das Frontend anderswo optimiert, aber der Checkout war unsere blinde Fleck.
Was Checkout Extensibility verändert
Shopify Checkout Extensibility ersetzt das monolithische Template durch ein Kompositionsmodell. Statt einer Datei, die alles besitzt, baut man den Checkout aus drei Primitiven:
- Checkout UI Extensions für benutzerdefinierte React-Komponenten innerhalb von Shopifys Checkout.
- Web Pixels und Customer Events für Tracking und Analytics.
- Functions für serverseitige Validierung und Preislogik, die innerhalb von Shopifys Infrastruktur läuft.
Die Architektur ist ereignisgesteuert und abgegrenzt. Eine UI Extension lädt nur auf dem Schritt, auf dem sie benötigt wird. Eine Function läuft nur, wenn ihre spezifische Bedingung erfüllt ist. Und alles ist versioniert, typsicher und über Shopifys Infrastruktur deploybar.
Die Migrationsstrategie
Wir versuchten keinen Big-Bang-Rewrite. Das Risiko, den Checkout eines Live-Stores zu zerstören, ist zu hoch. Stattdessen liefen altes und neues System parallel, während wir eine Sache nach der anderen migrierten.
Schritt 1: Bestandsaufnahme der Legacy-Oberfläche
Wir prüften jede Zeile in checkout.liquid und ordneten sie einem von vier Eimern zu:
- UI-Änderungen, die zu Checkout UI Extensions werden konnten.
- Tracking und Analytics, die zu Web Pixels gehören sollten.
- Preis- und Validierungsregeln, die in Shopify Functions gehörten.
- Toter Code, der einfach gelöscht werden konnte.
Etwa dreißig Prozent der Datei fielen in die letzte Kategorie. Allein das machte die Prüfung lohnenswert.
Schritt 2: Den Extension-Scaffold bauen
Wir erstellten eine einzige Shopify App, die alle Checkout-Extensions des Stores besaß. Jede Extension lebte in ihrem eigenen Verzeichnis mit eigenen Tests. Gemeinsamer Code wie API-Clients und Validierungshelfer lag in einem Workspace-Paket, sodass Extensions nicht versehentlich voneinander abhängen konnten.
// extensions/checkout-upsell/src/CheckoutUpsell.tsx
import { useExtensionApi, TextBlock, Button } from '@shopify/checkout-ui-extensions-react';
export default function CheckoutUpsell() {
const { extension, lines, applyMetafieldsChange } = useExtensionApi();
const { appMetafields } = extension;
async function addRecommendedVariant(variantId: string) {
await applyMetafieldsChange({
type: 'updateMetafield',
namespace: 'checkout_upsell',
key: 'selected_variant',
value: variantId,
valueType: 'string',
});
}
return (
<TextBlock>Complete your kit with a matching item</TextBlock>
// Render dynamic recommendation based on cart lines
);
}Schritt 3: Geschäftslogik in Functions verschieben
Die serverseitige Validierung war der unheimlichste Teil der Migration, denn ein Bug konnte leise die Preisgestaltung zerstören. Wir begannen mit einer einfachen metafield-basierten Rabattregel und fügten Observability hinzu, bevor wir hochskalierten.
// extensions/cart-validation/src/run.rs
use shopify_function::prelude::*;
use serde::Serialize;
#[derive(Serialize)]
struct Output {
discount_application_strategy: String,
}
#[shopify_function_target
query = "src/run.graphql"]
fn run(input: ResponseData) -> Result<Output> {
let eligible = input.cart.lines.iter().all(|line| {
line.merchandise.as_ref().map_or(false, |m| {
matches!(m.product.is_gift_card, Some(false))
})
});
Ok(Output {
discount_application_strategy: if eligible { "FIRST".to_string() } else { "ALL".to_string() },
})
}Schritt 4: Parallele Validierung und Umstellung
Zwei Wochen lang protokollierten wir die Ausgabe der neuen Functions und UI Extensions neben dem Legacy-Verhalten. Jede Abweichung löste einen Alarm aus. Sobald die Abweichungsrate für zweiundsiebzig Stunden bei null blieb, deaktivierten wir den Legacy-Code für die migrierten Features.
Was kaputtging und wie wir es reparierten
Das Erste, das zerbrach, war unser A/B-Testing-Framework. Es hatte auf dem Injizieren unterschiedlicher Skripte basiert, abhängig von Checkout-Attributen. Ohne checkout.liquid mussten wir die Experiment-Zuordnung als Web Pixel neu aufbauen, das beim Checkout-Start feuerte und die Variante in Customer Events schrieb. Das war mehr Arbeit upfront, aber die Datenqualität verbesserte sich, weil Events nicht mehr verloren gingen, wenn Skripte nicht luden.
Die zweite Überraschung war die Performance. Wir erwarteten einen schnelleren Checkout, aber unterschätzten, wie viel schneller. Das Entfernen blockierender Drittpartei-Skripte aus dem kritischen Pfad senkte unser Largest Contentful Paint auf der Zahlungsseite um fast vierzig Prozent. Die React-Extensions werden lazy-loaded und sandboxed, sodass sie das Rendering von Shopifys Core-Checkout nicht blockieren können.
Das dritte Problem war organisatorisch. Checkout Extensibility zwang uns, Frontend- und Backend-Logik sauber zu trennen. Designer konnten nicht mehr einfach ein Script-Tag in ein Template werfen und es gut sein lassen. Sie mussten in scoped Extensions und event-getriebenes Tracking denken. Diese Reibung war beabsichtigt und verbesserte die Qualität neuer Checkout-Features.
Takeaways
Den Checkout als Plattform-Erweiterung statt als Template-Override zu behandeln, verändert, wie man Design, Tests und Deployments angeht. Die Migration ist nicht nur ein Refactoring; sie ist ein architektonischer Schritt.
Beginne mit einer Bestandsaufnahme und klassifiziere jede Legacy-Anpassung. Führe alte und neue Systeme parallel mit echtem Traffic, bevor du umstellst. Verschiebe Geschäftslogik in Functions, Präsentationslogik in UI Extensions und Tracking in Web Pixels. Erwarte, dass einige A/B- und Analytics-Tools neu aufgebaut werden müssen. Der Gewinn ist ein Checkout, der schneller, sicherer und mit Shopifys Roadmap statt gegen sie ausgerichtet ist.

Verfasst von
Miracle Kalu
Senior Full Stack Engineer
Hat dir das Gefallen?
Ich bin verfügbar für Senior-Engineering-Rollen und technische Beratung. Lass uns reden.
Kontakt aufnehmen →Veröffentlicht 13. Juni 2026 · 4 Min. Lesezeit
Weiterlesen
