phoenix-html

Critical Phoenix HTML and HEEx template guidelines that prevent common bugs and syntax errors. Use when writing Phoenix templates, HEEx files, LiveView templates, or any code using `~H` sigils. Prevents common mistakes with form handling, conditional syntax, class attributes, interpolation, and template comments that cause compilation errors or runtime bugs.

$ 安裝

git clone https://github.com/forest/dotfiles /tmp/dotfiles && cp -r /tmp/dotfiles/claude/skills/phoenix-html ~/.claude/skills/dotfiles

// tip: Run this command in your terminal to install the skill


name: phoenix-html description: Critical Phoenix HTML and HEEx template guidelines that prevent common bugs and syntax errors. Use when writing Phoenix templates, HEEx files, LiveView templates, or any code using ~H sigils. Prevents common mistakes with form handling, conditional syntax, class attributes, interpolation, and template comments that cause compilation errors or runtime bugs.

Phoenix HTML/HEEx Guidelines

Template Syntax

  • Always use ~H sigils or .html.heex files. Never use ~E
  • HEEx comments use <%!-- comment --%> syntax

Forms

  • Always use Phoenix.Component.form/1 and Phoenix.Component.inputs_for/1
  • Never use deprecated Phoenix.HTML.form_for or Phoenix.HTML.inputs_for
  • Always use to_form/2 for form handling:
# In mount/handle_event:
assign(socket, form: to_form(changeset))

# In template:
<.form for={@form} id="product-form">
  <.input field={@form[:name]} />
</.form>
  • Always add unique DOM IDs to forms for testability

Conditionals

Elixir has if/else but does NOT support if/else if or if/elsif.

Never do this (invalid):

<%= if condition do %>
  ...
<% else if other_condition %>
  ...
<% end %>

Always use cond for multiple conditions:

<%= cond do %>
  <% condition1 -> %>
    ...
  <% condition2 -> %>
    ...
  <% true -> %>
    ...
<% end %>

Class Attributes

Always use list [...] syntax for class attributes:

<a class={[
  "px-2 text-white",
  @some_flag && "py-5",
  if(@other_condition, do: "border-red-500", else: "border-blue-100")
]}>Text</a>

Always wrap if expressions in parentheses inside {...}.

Never do this (invalid syntax):

<a class={
  "px-2 text-white",
  @some_flag && "py-5"
}>

Interpolation

  • Use {...} for interpolation within tag attributes and simple values in tag bodies
  • Use <%= ... %> for block constructs (if, cond, case, for) in tag bodies

Correct:

<div id={@id}>
  {@my_assign}
  <%= if @condition do %>
    {@value}
  <% end %>
</div>

Invalid (never do this):

<div id="<%= @invalid %>">
  {if @condition do}
  {end}
</div>

Iterating Collections

Always use for comprehensions:

<%= for item <- @collection do %>
  <div>{item.name}</div>
<% end %>

Never use <% Enum.each %> for template content.

Literal Curly Braces

Use phx-no-curly-interpolation for literal { or } in code snippets:

<code phx-no-curly-interpolation>
  let obj = {key: "val"}
</code>

Within annotated tags, use <%= ... %> for dynamic expressions.

App-Wide Imports

Add shared imports to my_app_web.ex's html_helpers block for availability in all LiveViews and components.