hyva-alpine-component — Claude Code skill
Guides the agent through building Alpine.js components for Hyvä themes in Magento 2 that keep working when Content Security Policy is strict.
npx skills add hyva-themes/hyva-ai-tools --skill hyva-alpine-component -a claude-codeWhat hyva-alpine-component does
The skill covers interactive Hyvä templates that must run in the Alpine CSP build, which avoids the unsafe-eval directive. Payment pages need that setup for PCI-DSS 4.0, mandatory from April 1, 2025. Treat CSP style as the default for any Alpine code you write.
The guidance is concrete. To toggle state, call a method such as toggle instead of assigning inline; to pass an argument, put it in a data-* attribute and read this.$el.dataset. x-model has no equivalent in Alpine CSP, so inputs use :value plus @input. Range loops are out too. Each component follows a template: a named global constructor function, registered with Alpine.data() inside an alpine:init listener that passes {once: true}, and $hyvaCsp->registerInlineScript() after every <script> block.
PHP values reach JavaScript through $escaper->escapeJs(); data attributes take escapeHtmlAttr() instead. Numeric input goes through hyva.safeParseNumber(), and combining objects uses spread with .call(this). Skip the registerInlineScript() call and the inline script stays unregistered, so the policy blocks it.
What it helps with
- Build an Alpine component in a Hyvä template that passes CSP rules
- Port an existing
x-datablock to Alpine CSP withoutunsafe-eval - Replace
x-modelwith:valueand@inputhandlers - Register a component constructor once via
Alpine.data() - Pass a method argument through a data attribute with proper escaping
Example prompts for the agent
- Build an Alpine component for the Hyvä cart: toggle the panel and update a quantity, no
unsafe-eval - Rewrite
checkout.phtmlso it works in the Alpine CSP build - Add two-way binding for the coupon field using
:valueand@input
How to install hyva-alpine-component
1Skills CLI (Vercel)
npx skills add hyva-themes/hyva-ai-tools --skill hyva-alpine-component -a claude-code2Manually: put the files in place
~/.claude/skills/hyva-alpine-component/SKILL.mdCopy the whole skill folder; for one project use .claude/skills/hyva-alpine-component/
1Skills CLI (Vercel)
npx skills add hyva-themes/hyva-ai-tools --skill hyva-alpine-component -a codex2Manually: put the files in place
.agents/skills/hyva-alpine-component/SKILL.mdFor all projects use ~/.agents/skills/
1Skills CLI (Vercel)
npx skills add hyva-themes/hyva-ai-tools --skill hyva-alpine-component -a cursor2Manually: put the files in place
.cursor/skills/hyva-alpine-component/SKILL.mdCursor also reads .agents/skills/ and .claude/skills/
1GitHub CLI
gh skill install hyva-themes/hyva-ai-tools hyva-alpine-component2Manually: put the files in place
.github/skills/hyva-alpine-component/SKILL.md1Skills CLI (Vercel)
npx skills add hyva-themes/hyva-ai-tools --skill hyva-alpine-component -a gemini-cli2Platform CLI
gemini skills install https://github.com/hyva-themes/hyva-ai-tools --path skills/hyva-alpine-componentManually: put the files in place
.devin/skills/hyva-alpine-component/SKILL.mdThe legacy .windsurf/skills/ path still works
Skills CLI (Vercel)
npx skills add hyva-themes/hyva-ai-tools --skill hyva-alpine-component -a opencodeClaude.ai
Zip the folder and upload it in Settings → Capabilities → Skills
Step by step, with commands for each platform: How to install skills in Claude Code: five ways
Questions about hyva-alpine-component
How to install hyva-alpine-component in Claude Code?
Run npx skills add hyva-themes/hyva-ai-tools --skill hyva-alpine-component -a claude-code. The skill file lands at ~/.claude/skills/hyva-alpine-component/SKILL.md.
What does hyva-alpine-component do?
It gives the agent rules for Alpine.js components in Hyvä that run under the CSP build without unsafe-eval, covering methods, state changes, argument passing and constructor registration.
Why does it avoid x-model?
Alpine CSP has no x-model. The skill shows manual binding with :value and @input, and hyva.safeParseNumber() for numeric fields.