Packages
mdex
0.13.3
0.13.3
0.13.2
0.13.1
0.13.0
0.12.5
retired
0.12.4
0.12.3
0.12.2
0.12.1
0.12.0
0.11.7
0.11.6
0.11.5
0.11.4
0.11.3
0.11.2
0.11.1
0.11.0
0.10.0
0.9.4
0.9.3
0.9.2
0.9.1
0.9.0
0.8.6
0.8.5
0.8.4
0.8.3
0.8.2
0.8.1
0.8.0
0.7.5
0.7.4
0.7.3
0.7.2
0.7.1
0.7.0
0.6.2
0.6.1
0.6.0
0.5.0
0.4.3
0.4.2
0.4.1
0.4.0
0.3.3
0.3.2
0.3.1
0.3.0
0.2.0
0.1.18
0.1.17
0.1.16
0.1.15
0.1.14
0.1.13
0.1.12
0.1.11
0.1.10
0.1.9
0.1.8
0.1.7
0.1.6
0.1.5
0.1.4
0.1.3
0.1.2
0.1.1
0.1.0
Fast and extensible Markdown for Elixir
Current section
Files
Jump to
Current section
Files
guides/heex.md
# HEEx Integration
MDEx integrates with Phoenix LiveView's HEEx templates, allowing you to use Markdown alongside Phoenix components, `phx-*` bindings, and Elixir expressions.
## When to Use HEEx Integration
Use HEEx integration when you need:
- Phoenix components (like `<.link>`, `<.button>`, or custom components) inside Markdown
- LiveView bindings (`phx-click`, `phx-submit`, etc.)
- Elixir expressions that evaluate at runtime (`{@var}`)
For static Markdown without Phoenix components, use the regular `~MD[...]HTML` modifier or `MDEx.to_html/2` instead.
## Setup
Add `use MDEx` to your module to enable both `require MDEx` (for `to_heex/2`) and `import MDEx.Sigil` (for the `~MD` sigil):
```elixir
defmodule MyAppWeb.PageLive do
use Phoenix.LiveView
use MDEx
# Now you can use ~MD[...]HEEX and MDEx.to_heex/2
end
```
## Two Approaches
### `~MD[...]HEEX` Sigil (Compile-time)
The preferred approach for LiveView templates. The Markdown is parsed at compile-time for optimal performance:
```elixir
def render(assigns) do
~MD"""
# Welcome, {@username}!
<.link href={@profile_url}>View Profile</.link>
"""HEEX
end
```
### `MDEx.to_heex/2` Macro (Runtime)
For dynamic content or when the sigil isn't available. The template is evaluated at runtime:
```elixir
def render(assigns) do
markdown = fetch_markdown_from_database()
MDEx.to_heex!(markdown, assigns: assigns)
end
```
Note: Calling `to_heex/2` repeatedly at runtime may impact performance. Prefer the sigil when possible.
## Using Assigns
Pass variables to your Markdown templates using the `{@var}` syntax:
```elixir
def render(assigns) do
~MD"""
Welcome back, **{@user.name}**!
You have {@notification_count} unread notifications.
"""HEEX
end
```
The old `<%= @var %>` EEx syntax also works for compatibility.
## Phoenix Components
Use any Phoenix component directly in your Markdown:
```elixir
~MD"""
# Navigation
- <.link navigate={~p"/home"}>Home</.link>
- <.link navigate={~p"/about"}>About</.link>
<.button phx-click="save">Save Changes</.button>
<MyAppWeb.Components.card title={@card_title}>
Card content here
</MyAppWeb.Components.card>
"""HEEX
```
> #### Component imports are not automatic {: .info}
>
> MDEx does not automatically import components. To use function components with the dot notation:
>
> - Import `Phoenix.Component` for core components like `<.link>`
> - Import your app's components module (e.g., `import MyAppWeb.CoreComponents`)
> - Or use fully qualified names: `<Phoenix.Component.link href="/">Home</Phoenix.Component.link>`
>
> In Phoenix applications, `use MyAppWeb, :live_view` typically handles these imports for you.
## Elixir Expressions
Embed Elixir expressions using curly braces:
```elixir
~MD"""
Today is _{Calendar.strftime(DateTime.utc_now(), "%B %d, %Y")}_
<%= for item <- @items do %>
- {item.name}: **{item.status}**
<% end %>
"""HEEX
```
## Converting HEEx to HTML String
When you need the final HTML as a string (e.g., for emails or static pages):
```elixir
MDEx.to_heex!(markdown, assigns: assigns)
|> MDEx.to_html!()
```
## Full Example
```elixir
defmodule MyAppWeb.BlogLive do
use Phoenix.LiveView
use MDEx
def mount(_params, _session, socket) do
{:ok, assign(socket, title: "My Post", likes: 42)}
end
def render(assigns) do
~MD"""
# {@title}
This post has **{@likes}** likes.
<.button phx-click="like">Like this post</.button>
---
Built with <.link href="https://hex.pm/packages/mdex">MDEx</.link>
"""HEEX
end
def handle_event("like", _, socket) do
{:noreply, update(socket, :likes, &(&1 + 1))}
end
end
```