Shopware 6.7 introduces a refined approach to store customization that sits between configuration and full plugin development: App Scripts and Script Hooks. Designed for developers who need precise, event-driven behavior without the boilerplate of traditional plugins, scripts offer a sandboxed, API-managed execution model. Whether you’re modifying checkout logic, injecting dynamic storefront elements, or synchronizing external systems, understanding this architecture is essential for modern Shopware development.
Why Scripts Over Traditional Plugins?
Historically, extending Shopware meant creating full plugins: registering service providers, defining routes, wiring templates, and managing dependency injection manually. While powerful, this approach often introduces upgrade friction and unnecessary complexity for lightweight logic. App Scripts solve this by decoupling execution from the plugin lifecycle. Scripts run as isolated PHP closures triggered by internal system events. They don’t require composer packages, routing configurations, or template overrides. Instead, they subscribe to Script Hooks—specific moments in Shopware’s request cycle—and execute within a restricted dependency scope.
This shift enables rapid iteration, safer upgrades, and cleaner separation of concerns. Scripts also integrate seamlessly with the modern App ecosystem, allowing you to manage secrets, permissions, and deployments via the Storefront App API rather than touching the core codebase.
The Script Hook Architecture
Script Hooks in Shopware 6.7 are classified into distinct lifecycle domains: storefront rendering, checkout flow, cart manipulation, order processing, and system-level events. Each hook exposes a predictable context object that grants controlled access to repositories, request data, and security tokens. Unlike kernel listeners, scripts execute synchronously by default within a sandboxed runtime. The platform validates trigger filters before execution, ensuring scripts only run when their registered conditions match.
Hooks support filter expressions, allowing you to scope execution to specific customer groups, sales channels, or entity attributes. For example, you can attach a script exclusively to the checkout.step.payment hook and restrict it to orders containing gift wrapping items. The filtering happens at the registry level, preventing unnecessary PHP compilation and memory overhead.
Registration & Configuration
Before writing logic, your script must be registered as an App. This is typically done via the Storefront CLI or REST API using a payload that defines:
- Unique script identifier
- Executable file path (relative to app root)
- Event subscription map (
hook→filter_expression) - Required secrets and scope permissions
Once synced to a running Shopware instance, the platform compiles the sandbox manifest, resolves allowed dependencies, and caches hook mappings. Scripts are hot-reloadable in development mode and automatically cleared on version updates. Always test registrations in staging first; misconfigured filters can cause silent skips or permission exceptions.
Code Example: A Checkout-Ready Script
Below is a Shopware 6.7+ compatible script that monitors cart modifications and logs promotion applications:
<?php declare(strict_types=1);
use Shopware\Script\Api\ScriptContext;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
return static function (ScriptContext $context): void {
$cart = $context->get('cart');
if (!$cart instanceof \Shopware\Core\Checkout\Cart\SalesChannel\Cart) {
return;
}
$lineItems = $cart->getLineItems();
$promotionCode = $lineItems->filterByProperty('promotion_code');
if ($promotionCode->isEmpty()) {
return; // Skip unmanaged carts
}
$context->logger()->info(
'Promotion applied to cart',
['cartId' => $cart->getId(), 'code' => $promotionCode->first()?->getValue()]
);
};
Notice the closure signature and strict typing. Shopware 6.7 wraps every script in an invokable function, passing a typed ScriptContext that guarantees safe service resolution. The get() method respects sandbox boundaries, while logger() routes to Shopware’s unified audit trail. No direct container access is permitted—this enforces upgrade safety and prevents circular dependencies.
Context Object & Available Capabilities
The ScriptContext object is your primary interface. It provides:
get(string $alias): Resolves sandbox-safe services (cart, session, request)getRepository(string $entityName): Returns typed repositories with query limitslogger(): Writes to Shopware’s log system with automatic correlation IDsgetToken(): Validates security context for authenticated operations
You cannot directly instantiate classes, use globals, or access superglobals. The sandbox intercepts unsupported calls and throws controlled exceptions. For complex operations, delegate to message queues via $context->getAppContext()->dispatch() or cache results using Shopware’s Redis backend through allowed aliases.
Performance, Security & Debugging
Scripts execute synchronously during request cycles, so performance matters. Avoid N+1 queries, block I/O, or unbounded loops. Use early returns for mismatched conditions and batch repository reads. Enable script.debug_mode in your app configuration to log compilation warnings and execution timing. Monitor memory via Xdebug’s memory_get_peak_usage() wrapped in try/catch blocks.
Security is enforced at three layers: sandbox isolation, permission scoping, and secret rotation. Never hardcode tokens; fetch them via $context->getSecret('external_api_key'). Scripts also respect GDPR data retention policies—avoid storing customer identifiers beyond the request lifetime.
Deployment & Best Practices
Package your script alongside an app.yaml manifest for version control compatibility. Use semantic filtering to reduce trigger collisions, and always implement idempotency for order-related hooks. Test in a fresh 6.7+ installation; sandbox behavior differs slightly between PHP 8.2 and 8.3 environments due to JIT compilation changes. For production, enable script rate-limiting via the App Dashboard and review execution logs weekly for timeout patterns.
Conclusion
App Scripts and Script Hooks redefine how we interact with Shopware’s core. They remove plugin boilerplate, enforce security boundaries by design, and align with headless, event-driven architectures. Master them to ship store modifications faster while maintaining upgrade compatibility. Start with simple cart hooks, validate context permissions, and scale responsibly. The future of Shopware customization is lightweight, auditable, and built for precision.