Component-Based Development
Nex supports a powerful component-based development model, helping you build maintainable and reusable UI interfaces.
1. UI Components
UI Components are the most basic unit of reuse in Nex. They are typically stored in the src/components/ directory, but you can define them in any module.
Defining a Component
A component is just a normal function that receives assigns and returns a ~H template.
defmodule MyApp.Components.Buttons do
use Nex
def primary_button(assigns) do
~H"""
<button class="px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700 transition">
{render_slot(@inner_block)}
</button>
"""
end
end
Using a Component
In a page, you can use the <.component_name /> syntax to call it.
def render(assigns) do
~H"""
<div class="p-4">
<MyApp.Components.Buttons.primary_button>
Submit Application
</MyApp.Components.Buttons.primary_button>
</div>
"""
end
2. Slots
Slots allow you to pass complex HTML content to components.
-
Default Slot: Accessed via
{@inner_block}and rendered usingrender_slot/1. -
Named Slots: Passed using the
<:slot_name>syntax and accessed via{@slot_name}.
def card(assigns) do
~H"""
<div class="border rounded shadow">
<div class="p-4 border-b font-bold bg-gray-50">
{render_slot(@header)}
</div>
<div class="p-4">
{render_slot(@inner_block)}
</div>
</div>
"""
end
# Usage
~H"""
<.card>
<:header>Card Title</:header>
This is the main content of the card.
</.card>
"""
3. Layout Contract
src/layouts.ex is the top-level container for your application. It must follow a set of “contracts” to ensure framework functionality works correctly.
Core Variables
-
@inner_content: Must be rendered, representing the core HTML of the page. Use{raw(@inner_content)}to render it. -
@title: The page title, returned by the page module’smount/1(defaults to “Nex App”).
Layout Example
defmodule MyApp.Layouts do
use Nex
def render(assigns) do
~H"""
<!DOCTYPE html>
<html>
<head>
<title>{@title}</title>
<script src="https://cdn.tailwindcss.com"></script>
</head>
<body>
<nav>...</nav>
<main>
{raw(@inner_content)}
</main>
</body>
</html>
"""
end
end
4. Component Reuse Patterns
-
Single-File Components: For UI fragments used only on the current page, you can define private functions (e.g.,
defp my_widget(assigns)) directly at the bottom of the page module. -
Global Libraries: Centralize common base components (buttons, inputs, cards) in
src/components/. -
Zero-Config Import: Since
use Nexautomatically imports necessary macros for you, you don’t need to manuallyimport Phoenix.Component.