maragudk

gomponents

29
6
# Install this skill:
npx skills add maragudk/skills --skill "gomponents"

Install specific skill from multi-skill repository

# Description

Guide for working with gomponents, a pure Go HTML component library. Use this skill when reading or writing gomponents code, or when building HTML views in Go applications.

# SKILL.md


name: gomponents
description: Guide for working with gomponents, a pure Go HTML component library. Use this skill when reading or writing gomponents code, or when building HTML views in Go applications.
license: MIT


gomponents

Overview

gomponents is a pure Go HTML component library that treats HTML elements as composable Go values. Everything is built on the Node interface, making HTML construction type-safe and composable.

When to Use This Skill

Use this skill when:
- Reading or writing gomponents code
- Building server-side HTML views in Go applications
- Creating reusable HTML components in Go

Core Interface

Everything in gomponents implements the Node interface:

type Node interface {
    Render(w io.Writer) error
}

Essential Functions

Element and Attribute Creation

  • El(name string, children ...Node) - Create custom HTML elements
  • Attr(name string, value ...string) - Create custom attributes

Most standard HTML5 elements and attributes are available as functions in the html package:
- Elements: Div(), Span(), P(), A(), etc.
- Attributes: Class(), ID(), Href(), Src(), etc.

Note: nil Nodes are ignored during rendering, so it's safe to pass nil nodes to elements.

Text Content

  • Text(string) - HTML-escaped text content
  • Textf(format string, args...) - Formatted, escaped text
  • Raw(string) - Unescaped HTML
  • Rawf(format string, args...) - Formatted, unescaped content

Composition

  • Group([]Node) - Combine multiple nodes
  • Map[T]([]T, func(T) Node) - Transform slices into node sequences
  • If(condition bool, node Node) - Conditional rendering
  • Iff(condition bool, func() Node) - Lazy conditional rendering (deferred evaluation)

Import Convention

Contrary to common Go idioms, dot imports are recommended for gomponents to achieve DSL-like syntax:

import (
    . "maragu.dev/gomponents"
    . "maragu.dev/gomponents/html"
    . "maragu.dev/gomponents/components"
)

This allows writing clean, HTML-like code:

Div(Class("container"),
    H1(Text("Hello World")),
    P(Text("Welcome to gomponents")),
)

Package Organization

  • maragu.dev/gomponents - Core interface and helper functions
  • maragu.dev/gomponents/html - All HTML5 elements and attributes
  • maragu.dev/gomponents/http - HTTP helpers for rendering components as responses
  • maragu.dev/gomponents/components - Higher-level utilities (HTML5 document structure, dynamic classes)

Common Patterns

Basic Component

func UserCard(name, email string) Node {
    return Div(Class("user-card"),
        H2(Text(name)),
        P(Text(email)),
    )
}

Conditional Rendering

func Alert(message string, isError bool) Node {
    return Div(
        If(isError, Class("error")),
        If(!isError, Class("info")),
        P(Text(message)),
    )
}

Use If when the node is always safe to evaluate. Use Iff when the node might be nil and shouldn't be evaluated unless the condition is true.

func UserProfile(user *User) Node {
    return Div(
        H1(Text(user.Name)),
        // Use Iff to avoid nil pointer dereference when user.Avatar is nil
        Iff(user.Avatar != nil, func() Node {
            return Img(Src(user.Avatar.URL))
        }),
    )
}

Grouping Without a Parent Element

Use Group to group multiple nodes without wrapping them in a parent element:

func FormFields(required bool) Node {
    return Group{
        Label(For("email"), Text("Email")),
        Input(Type("email"), ID("email")),
        If(required, Span(Class("required"), Text("*"))),
    }
}

List Rendering

func TodoList(todos []Todo) Node {
    return Ul(Class("todo-list"),
        Map(todos, func(t Todo) Node {
            return Li(Text(t.Title))
        }),
    )
}

HTML Document

func Page(title string, body Node) Node {
    return HTML5(HTML5Props{
        Title:    title,
        Language: "en",
        Head: []Node{
            Link(Rel("stylesheet"), Href("/styles.css")),
        },
        Body: []Node{body},
    })
}

HTTP Handler

import ghttp "maragu.dev/gomponents/http"

func HomeHandler(w http.ResponseWriter, r *http.Request) (Node, error) {
    return Page("My App",
        Div(Class("container"),
            H1(Text("Hello, World!")),
        ),
    ), nil
}

// In main:
http.HandleFunc("/", ghttp.Adapt(HomeHandler))

The http package provides:
- Handler type - function signature that returns (Node, error)
- Adapt(Handler) - converts Handler to http.HandlerFunc
- Error handling with custom status codes via StatusCode() int interface

# Supported AI Coding Agents

This skill is compatible with the SKILL.md standard and works with all major AI coding agents:

Learn more about the SKILL.md standard and how to use these skills with your preferred AI coding agent.