#1113·templ

proposal: add dynamic html element helper function

Author: anuragkumar19Created Mar 28, 2025Updated Apr 27, 2026
LabelsNeedsDecisionruntimeproposal

Sometime when building components we don't have prior knowledge of which html element the user of component might want to use. For example a UI library provide a component Button, it may be a html <button> element or a <a>.

For example Vue.js provide API look like <component :is="a"> to support this.

It would be good to have this utility built into templ.

Suggested API:

go
func Element(e string, attrs Attributes) Component

Usage:

templ
templ Button(is string) {
	@templ.Element(is, templ.Attributes{
		"class": "btn btn-primary",
		"href":  "/hello",
	}) {
		Hello
	}
} 

My Current Local Implementation

go
func Element(e string, attrs templ.Attributes) templ.Component {
	return templ.ComponentFunc(func(ctx context.Context, w io.Writer) error {
		if _, err := w.Write([]byte("<")); err != nil {
			return err
		}
		if _, err := w.Write([]byte(e)); err != nil {
			return err
		}
		if err := templ.RenderAttributes(ctx, w, attrs); err != nil {
			return err
		}
		if _, err := w.Write([]byte(">")); err != nil {
			return err
		}

		if c := templ.GetChildren(ctx); c != nil {
                        ctx = templ.ClearChildren(ctx)
			if err := c.Render(ctx, w); err != nil {
				return err
			}
		}

		if _, err := w.Write([]byte("</")); err != nil {
			return err
		}
		if _, err := w.Write([]byte(e)); err != nil {
			return err
		}
		if _, err := w.Write([]byte(">")); err != nil {
			return err
		}

		return nil
	})
}