跳到主要内容
知仓学习社ZHICANG

alpinejs-django

Use when adding, changing, or debugging Alpine.js behavior in Django-rendered templates, especially when Alpine.js coexists with HTMX partial updates.

联网无严重或高危命中hashgraph-online/awesome-codex-plugins

它会碰到什么

扫了多少1 个文本文件,7 KB
它会碰到什么联网
命中总数1 处
命中统计严重 0 · 高 0 · 中 0 · 低 1

这一栏是扫描器报的事实,不是结论。命中多不等于有毒(安全工具、规则库、示例脚本本来就会包含危险写法),命中少也不等于干净。它和你手上的凭据、文件、网络有什么关系,需要你自己看。

技能内容

Alpine.js with Django

Use this skill for local browser state in Django-rendered templates: dropdowns,

modals, tabs, disclosures, inline filters, disabled/loading states, small

preview interactions, and client-only toggles. Use Django views/forms/models as

the source of truth for durable state. Use HTMX when the server needs to return

fresh HTML.

Setup checks

  • Identify how the project loads Alpine. Prefer the existing static asset or

bundling pipeline as the source of truth.

  • Find the base template, layout, or bundled entrypoint that loads HTMX,

Alpine, and app JavaScript. Preserve the current ordering unless changing

initialization deliberately.

  • Determine whether the loaded Alpine file is self-starting or module-based. Do

not call Alpine.start() when the project already loads a self-starting

Alpine build. If using a module build, register components and start Alpine

from the owning entrypoint.

  • Simple Alpine behavior should usually live inline in the Django template with

x-data.

  • If a reusable component or store is worth extracting, register it before

Alpine starts. Check the existing script order before relying on

document.addEventListener("alpine:init", ...) from an app-wide script.

  • When reusable Alpine registration is needed, add or reuse a script or

entrypoint that runs before Alpine starts. Register components and stores

inside document.addEventListener("alpine:init", ...), include the file

through the project's normal asset path, and avoid double-starting Alpine.

Ownership rules

  • Django owns persistence, authorization, validation, redirects, and rendered

HTML.

  • HTMX owns server round trips and DOM swaps.
  • Alpine owns ephemeral state already present in the browser.
  • Plain JavaScript modules or bundled entrypoints own shared DOM behavior that

is not naturally scoped to one Alpine component.

  • Do not duplicate the same behavior in Alpine and a plain JS module.

Template patterns

Use a small x-data object near the markup it controls:

<div
  x-data="{ open: false }"
  @keydown.escape.window="open = false"
  @click.outside="open = false"
>
  <button
    type="button"
    :aria-expanded="open.toString()"
    @click.stop="open = !open"
  >
    Menu
  </button>

  <div x-cloak x-show="open" x-transition>
    ...
  </div>
</div>

Prefer Alpine directives over manual DOM manipulation:

  • x-show for toggling visibility while keeping the element in the DOM.
  • x-if on a <template> when the element should be created and destroyed.
  • x-model for client-only input state; Django form submission and validation

still happen on the server.

  • :class, :disabled, :aria-expanded, and :hidden for state-derived

attributes.

  • $watch for one named state transition; x-effect only when the dependency

set is simple and intentional.

  • $dispatch for browser events between Alpine components or from Alpine to

HTMX triggers.

Use x-cloak for anything hidden by default. Ensure the base CSS includes the

required [x-cloak] { display: none !important; } rule.

Django data

Keep Django interpolation out of complex JavaScript expressions when possible.

For simple values, prefer HTML attributes:

<div
  data-initial-label="{{ object.name }}"
  x-data="{ label: '' }"
  x-init="label = $el.dataset.initialLabel"
>
  <span x-text="label"></span>
</div>

For structured values, prefer Django's json_script and parse it in x-init:

{{ rows|json_script:"rows-data" }}

<div
  x-data="{ rows: [] }"
  x-init="rows = JSON.parse(document.getElementById('rows-data').textContent)"
>
  <template x-for="row in rows" :key="row.id">
    <span x-text="row.name"></span>
  </template>
</div>

Avoid |safe inside Alpine expressions. If the browser must display text, use

x-text. Use x-html only for trusted, already-sanitized HTML; most HTML should

be rendered by Django or returned through HTMX.

Alpine and HTMX

When HTMX swaps a fragment containing x-data, Alpine should initialize the new

component automatically. Do not restart Alpine after HTMX swaps.

Keep persistent Alpine state outside HTMX targets that will be replaced:

<section x-data="{ panelOpen: false }">
  <button type="button" @click="panelOpen = !panelOpen">Filters</button>

  <div id="results" hx-get="{% url 'search_results' %}" hx-trigger="change from:#filters">
    ...
  </div>
</section>

Use events as the boundary between HTMX responses and Alpine state. From Django,

set an HX-Trigger or HX-Trigger-After-Swap response header, then listen from

Alpine:

<div x-data="{ open: true }" @profile-saved.window="open = false">
  <form hx-post="{% url 'profile_update' %}" hx-target="#profile-panel" hx-swap="outerHTML">
    ...
  </form>
</div>

Listen for HTMX lifecycle events in kebab case from Alpine, such as

@htmx:after-swap.window, because HTML attributes are case-insensitive.

If Alpine dispatches an event that HTMX should react to, make the trigger

explicit:

<button type="button" x-data @click="$dispatch('refresh-results')">
  Refresh
</button>

<div hx-get="{% url 'results' %}" hx-trigger="refresh-results from:body">
  ...
</div>

Accessibility

  • Keep real buttons as <button type="button"> unless submitting a form.
  • Bind ARIA state from Alpine state, especially aria-expanded,

aria-controls, aria-selected, and aria-hidden.

  • Support @keydown.escape.window for dismissible overlays.
  • Use @click.outside for popovers and menus, paired with a visible trigger.
  • Preserve focus behavior for modals, menus, and swapped HTMX content. If focus

trapping is needed, add a focused plain JS module or Alpine plugin deliberately

instead of hand-rolling a brittle trap in attributes.

Security and CSP

  • Treat all Alpine expressions as JavaScript running in the user's browser.
  • Do not put secrets, signed tokens, or privileged data into x-data,

data-*, json_script, or hidden inputs unless the user is allowed to see

them.

  • If strict Content Security Policy without unsafe-eval is required, switch

deliberately to Alpine's CSP build and retest Alpine expressions. The default

alpinejs/dist/cdn.min.js build is not the CSP build.

  • If Alpine code makes fetch() requests, include Django CSRF headers or use

existing HTMX/Django forms instead.

Validation

  • For template-only Alpine changes, run the Django template or view tests that

cover the page, plus npm run lint if JavaScript modules changed.

  • For HTMX interactions, test the full page and the partial response path.
  • If the project has a frontend build step, run it before relying on static

output.

  • Manually verify stateful controls in light and dark mode when changing visible

UI behavior.

想直接用这个技能?

本站把开放许可(MIT / Apache 等)的技能按仓库打包整理到网盘,点一下转存到你自己的网盘,不用一个个从 GitHub 拉。许可未声明的技能只给原始仓库链接,不打包。