Install
$ agentstack add skill-ddtcorex-dev-skills-hub-magento2-frontend-dev ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
Magento 2 Frontend Developer
This skill covers Luma/Blank theme development, Knockout.js, RequireJS, LESS CSS, and UI Components.
Related Skills
REQUIRED BACKGROUND: Load magento2-dev-core first — it defines the escaping (escapeHtml/escapeHtmlAttr/escapeJs) and backend patterns this skill's templates and view models rely on.
This skill targets Luma/Blank-derived themes. If the project's theme.xml parent is Hyva/default or Hyva/reset (or composer.json requires hyva-themes/*), use magento2-hyva-dev instead — the two frontend stacks are mutually exclusive and share almost no code patterns.
Theme Structure
app/design/frontend/Vendor/Theme/
├── registration.php
├── theme.xml
├── composer.json
├── media/
│ └── preview.jpg
├── web/
│ ├── css/
│ │ └── source/
│ │ ├── _extend.less
│ │ ├── _theme.less
│ │ └── _variables.less
│ ├── js/
│ │ └── namespace/
│ │ └── module.js
│ └── images/
└── Magento_Theme/
├── layout/
│ ├── default.xml
│ └── default_head_blocks.xml
└── templates/
└── header.phtml
RequireJS Modules
Creating a Module
// web/js/namespace/module.js
define([
'jquery',
'ko',
'uiComponent',
'Magento_Customer/js/customer-data'
], function ($, ko, Component, customerData) {
'use strict';
return Component.extend({
defaults: {
template: 'Namespace_Module/template-name',
exports: {
value: '${ $.provider }:data.value'
},
tracks: {
value: true
}
},
/** @inheritdoc */
initialize: function () {
this._super();
// Initialization logic
},
/** @inheritdoc */
initObservable: function () {
this._super()
.observe('value');
return this;
},
/**
* Example method
* @returns {string}
*/
getFormattedValue: function () {
return this.value() + ' formatted';
}
});
});
Using a Module in Template
{
"*": {
"Namespace_Module/js/module": {
"config": "value"
}
}
}
Click
{
"*": {
"Magento_Ui/js/core/app": {
"components": {
"module": {
"component": "Namespace_Module/js/module"
}
}
}
}
}
Knockout.js Patterns
ViewModel Structure
define(['ko'], function () {
'use strict';
return function (config, element) {
var self = this;
// Observable properties
self.products = ko.observableArray(config.products || []);
self.isLoading = ko.observable(false);
self.selectedId = ko.observable(null);
// Computed properties
self.hasProducts = ko.computed(function () {
return self.products().length > 0;
});
self.selectedProduct = ko.computed(function () {
return self.products().find(function (p) {
return p.id === self.selectedId();
});
});
// Methods
self.selectProduct = function (product) {
self.selectedId(product.id);
};
self.loadMore = function () {
self.isLoading(true);
// AJAX call
$.get('/api/products', function (data) {
self.products(self.products().concat(data));
self.isLoading(false);
});
};
// Initialize
self.init = function () {
if (config.enableAutoLoad) {
self.loadMore();
}
}();
};
});
Knockout Template
No products available
Loading...
Load More
Layout XML
Reference
custom-price
Adding JS with Layout
LESS CSS
Structure
// web/css/source/_extend.less
// Main entry point for theme customizations
// Import lib (Magento UI library)
@import 'lib/_lib.less';
// Import vendor styles
@import '_components.less';
// Your theme variables
@color-primary: #1979c3;
@color-secondary: #f0f0f0;
// Extend parent theme
@import '_theme.less';
// Custom styles
.block-product {
margin-bottom: @indent__l;
&__title {
font-size: 20px;
color: @color-primary;
}
&__image {
width: 100%;
}
}
UI Library Mixins
// Using Magento UI library mixins
.product-grid {
.lib-css(display, flex);
.lib-css(flex-wrap, wrap);
.lib-css(gap, 20px);
.lib-list-reset();
}
// Buttons
.action.primary {
.lib-button-replace();
.lib-button-primary();
}
// Forms
.field {
.lib-form-field();
}
// Links
a {
.lib-link($_linkColor: @color-primary);
}
Responsive Breakpoints
// Mobile first approach
@mobile: 640px;
@tablet: 768px;
@desktop: 1024px;
.product-card {
width: 100%;
@media (min-width: @tablet) {
width: 50%;
}
@media (min-width: @desktop) {
width: 33.333%;
}
}
UI Components (Magento 2.3+)
Basic UI Component
// web/js/view/checkout/summary/shipping-method.js
define([
'uiComponent',
'Magento_Checkout/js/model/quote',
'Magento_Checkout/js/action/select-shipping-method'
], function (Component, quote, selectShippingMethodAction) {
'use strict';
return Component.extend({
defaults: {
template: 'Magento_Checkout/shipping-method/shipping-method-list'
},
isVisible: function () {
return quote.shippingMethod() !== null;
},
/** Get shipping method code */
getMethodCode: function () {
var method = quote.shippingMethod();
return method ? method.carrier_code + '_' + method.method_code : '';
},
/** Select this shipping method */
selectMethod: function (method) {
selectShippingMethodAction(method);
}
});
});
XML UI Component Definition
sales_rule_form.sales_rule_form_data_source
Cart Price Rules
templates/form/collapsible
left
tabs
sales_rule_form.sales_rule_form_data_source
Magento_Ui/js/form/provider
Cache Configuration
null
Verification
# Deploy static content
bin/magento setup:static-content:deploy -f --theme=Vendor/Theme
# Clean caches
bin/magento cache:clean layout block_html
# Enable template hints (dev only)
bin/magento dev:template-hints:enable
bin/magento dev:template-hints:enable --store=admin
# Check RequireJS config
bin/magento config:set dev/js/merge_files 0
Pitfalls recap
- Don't mix Knockout/UI Component patterns into a Hyvä theme (or vice versa) — check
theme.xmlfirst if unsure which stack the project uses. - A
referenceBlockmarkedcacheable="false"blocks full-page caching for the whole containing page, not just that block — useesi:inlineor a shortercache_lifetimeinstead where possible. - Clear the right cache after a change:
layout/block_htmlfor layout XML,full_pagefor FPC-visible content, and always redeploy static content (setup:static-content:deploy) after CSS/JS changes in production mode. - RequireJS module paths are case-sensitive and must match the
require-config.jsmap exactly, or the module silently fails to resolve.
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: ddtcorex
- Source: ddtcorex/dev-skills-hub
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.