Examples

Explore interactive examples showcasing the power and flexibility of ZX framework. Each example includes live code and preview.

If/Else Statements

Use if/else expressions to conditionally render content based on state. ZX supports inline conditional expressions that return components or text.

pub fn Page(allocator: zx.Allocator) zx.Component {
    const is_logged_in = true;
    const is_premium = false;

    return (
        <main @allocator={allocator}>
            {if (is_logged_in) (
                <div>
                    <h2>Welcome back!</h2>
                    {if (is_premium) (
                        <p>Enjoy your premium features.</p>
                    ) else (
                        <p>Upgrade to premium for more features.</p>
                    )}
                </div>
            ) else (
                <div>
                    <h2>Hello, Guest</h2>
                    <p>Please log in to continue.</p>
                </div>
            )}
        </main>
    );
}

const zx = @import("zx");

<main><div><h2>Welcome back!</h2><p>Upgrade to premium for more features.</p></div></main>
Tip: You can nest if/else expressions for more complex conditional logic.

Switch Expressions

Switch expressions provide pattern matching for enums and other types. Each branch can return a component or text.

pub fn Page(allocator: zx.Allocator) zx.Component {
    const status: Status = .active;

    return (
        <main @allocator={allocator}>
            <h2>Account Status</h2>
            <div class="status">
                {switch (status) {
                    .active => (<span style="color: green">● Active</span>),
                    .pending => (<span style="color: orange">● Pending</span>),
                    .inactive => (<span style="color: red">● Inactive</span>),
                }}
            </div>
            <p>
                {switch (status) {
                    .active => ("Your account is in good standing."),
                    .pending => ("Your account is awaiting approval."),
                    .inactive => ("Your account has been deactivated."),
                }}
            </p>
        </main>
    );
}

const zx = @import("zx");

const Status = enum { active, pending, inactive };

<main><h2>Account Status</h2><div class="status"><span style="color: green">● Active</span></div><p>Your account is in good standing.</p></main>

For Loop

Iterate over arrays and slices to render lists of components. Each iteration receives the current item which you can use in your template.

pub fn Page(allocator: zx.Allocator) zx.Component {
    const users = [_]struct { name: []const u8, role: []const u8 }{
        .{ .name = "Alice", .role = "Admin" },
        .{ .name = "Bob", .role = "Member" },
        .{ .name = "Charlie", .role = "Guest" },
    };

    return (
        <main @allocator={allocator}>
            <h2>Team Members</h2>
            <ul>
                {for (users) |user| (
                    <li>
                        <strong>{user.name}</strong>
                        <span> - {user.role}</span>
                    </li>
                )}
            </ul>
        </main>
    );
}

const zx = @import("zx");

<main><h2>Team Members</h2><ul><li><strong>Alice</strong><span> - Admin</span></li><li><strong>Bob</strong><span> - Member</span></li><li><strong>Charlie</strong><span> - Guest</span></li></ul></main>

Component Props

Create reusable components by defining props structs. Components can accept any Zig type as props, including booleans, strings, and custom structs.

pub fn Page(allocator: zx.Allocator) zx.Component {
    return (
        <main @allocator={allocator}>
            <h2>Product Cards</h2>
            <div style="display: flex; gap: 1rem; flex-wrap: wrap;">
                <ProductCard name="Laptop" price="$999" in_stock={true} />
                <ProductCard name="Phone" price="$699" in_stock={true} />
                <ProductCard name="Tablet" price="$499" in_stock={false} />
            </div>
        </main>
    );
}

const ProductCardProps = struct {
    name: []const u8,
    price: []const u8,
    in_stock: bool,
};

fn ProductCard(allocator: zx.Allocator, props: ProductCardProps) zx.Component {
    return (
        <div style="border: 1px solid #ccc; padding: 1rem; border-radius: 8px; min-width: 150px;" @allocator={allocator}>
            <h3>{props.name}</h3>
            <p style="font-size: 1.25rem; font-weight: bold;">{props.price}</p>
            {if (props.in_stock) (
                <span style="color: green;">In Stock</span>
            ) else (
                <span style="color: red;">Out of Stock</span>
            )}
        </div>
    );
}

const zx = @import("zx");

<main><h2>Product Cards</h2><div style="display: flex; gap: 1rem; flex-wrap: wrap;"><div style="border: 1px solid #ccc; padding: 1rem; border-radius: 8px; min-width: 150px;"><h3>Laptop</h3><p style="font-size: 1.25rem; font-weight: bold;">$999</p><span style="color: green;">In Stock</span></div><div style="border: 1px solid #ccc; padding: 1rem; border-radius: 8px; min-width: 150px;"><h3>Phone</h3><p style="font-size: 1.25rem; font-weight: bold;">$699</p><span style="color: green;">In Stock</span></div><div style="border: 1px solid #ccc; padding: 1rem; border-radius: 8px; min-width: 150px;"><h3>Tablet</h3><p style="font-size: 1.25rem; font-weight: bold;">$499</p><span style="color: red;">Out of Stock</span></div></div></main>

Dynamic Attributes

Set HTML attributes dynamically using Zig expressions. Boolean attributes like disabled and readonly are handled automatically.

pub fn Page(allocator: zx.Allocator) zx.Component {
    const is_dark = true;
    const size = 42;
    const user_name = "Alice";

    return (
        <main @allocator={allocator}>
            <h2>Dynamic Attributes</h2>
            <button class={if (is_dark) "btn-dark" else "btn-light"}>
                Click Me
            </button>
            <div 
                style={std.fmt.allocPrint(allocator, "width: {d}px; height: {d}px; background: #3b82f6; border-radius: 4px;", .{size, size}) catch ""}
            >
            </div>
            <p>Hello, <span id={user_name}>{user_name}</span>!</p>
        </main>
    );
}

const std = @import("std");
const zx = @import("zx");
<main><h2>Dynamic Attributes</h2><button class="btn-dark"> Click Me</button><div style="width: 42px; height: 42px; background: #3b82f6; border-radius: 4px;"></div><p>Hello, <span id="Alice">Alice</span>!</p></main>

Form Handling

Build forms with standard HTML form elements. ZX handles form submission through standard HTTP methods.

pub fn Page(allocator: zx.Allocator) zx.Component {
    return (
        <main @allocator={allocator}>
            <h2>Contact Form</h2>
            <form method="post" action="/api/contact">
                <div>
                    <label for="name">Name</label>
                    <input type="text" id="name" name="name" placeholder="Your name" />
                </div>
                <div>
                    <label for="email">Email</label>
                    <input type="email" id="email" name="email" placeholder="your@email.com" />
                </div>
                <div>
                    <label for="message">Message</label>
                    <textarea id="message" name="message" placeholder="Your message..."></textarea>
                </div>
                <button type="submit">Send Message</button>
            </form>
        </main>
    );
}

const zx = @import("zx");

<main><h2>Contact Form</h2><form method="post" action="/api/contact"><div><label for="name">Name</label><input type="text" id="name" name="name" placeholder="Your name"></div><div><label for="email">Email</label><input type="email" id="email" name="email" placeholder="your@email.com"></div><div><label for="message">Message</label><textarea id="message" name="message" placeholder="Your message..."></textarea></div><button type="submit">Send Message</button></form></main>