HTML helpers
Vix UI provides small HTML helpers for building safe HTML fragments from C++.
Use them when you need to generate a piece of HTML without writing a full template.
They are useful for:
small components
server-rendered fragments
HTML attributes
safe text escaping
dynamic tags
layout helpers
forms and UI primitivesFor full pages, prefer templates and vix::ui::View.
Basic example
#include <vix/ui/html/Html.hpp>
#include <vix/ui/html/HtmlAttrs.hpp>
vix::ui::HtmlAttrs attrs;
attrs.set("class", "card");
attrs.set("id", "welcome");
const std::string html =
vix::ui::Html::tag(
"section",
vix::ui::Html::tag("h1", vix::ui::Html::text("Vix UI")) +
vix::ui::Html::tag(
"p",
vix::ui::Html::text("Small HTML fragments from C++.")),
attrs);Output:
<section class="card" id="welcome">
<h1>Vix UI</h1>
<p>Small HTML fragments from C++.</p>
</section>Escaped text
Use Html::text() when the value comes from a user, a request, a database, or any untrusted source.
const std::string username = "<script>alert(1)</script>";
const std::string html =
vix::ui::Html::tag(
"p",
vix::ui::Html::text(username));Output:
<p><script>alert(1)</script></p>This prevents unsafe HTML from being rendered directly.
Raw HTML
Use Html::raw() only when the HTML is trusted and already generated by your application.
const std::string html =
vix::ui::Html::tag(
"div",
vix::ui::Html::raw("<strong>Ready</strong>"));Output:
<div><strong>Ready</strong></div>Do not pass user input to Html::raw().
Attributes
HtmlAttrs stores and renders HTML attributes.
vix::ui::HtmlAttrs attrs;
attrs.set("class", "button");
attrs.set("id", "save-button");
attrs.set("data-action", "save");
const std::string html =
vix::ui::Html::tag(
"button",
vix::ui::Html::text("Save"),
attrs);Output:
<button class="button" data-action="save" id="save-button">Save</button>Attribute values are escaped automatically.
vix::ui::HtmlAttrs attrs;
attrs.set("title", R"(Save "draft" & continue)");Output:
title="Save "draft" & continue"Boolean attributes
Use boolean attributes for HTML attributes that do not need a value.
vix::ui::HtmlAttrs attrs;
attrs.boolean("disabled", true);
attrs.boolean("hidden", false);Only enabled boolean attributes are rendered.
disabledYou can also remove a boolean attribute by setting it to false.
attrs.boolean("disabled", false);Conditional attributes
Use set_if() when an attribute should only appear in some cases.
const bool active = true;
vix::ui::HtmlAttrs attrs;
attrs.set("class", "nav-link");
attrs.set_if(active, "aria-current", "page");Output:
class="nav-link" aria-current="page"Open and close tags
Use open_tag() and close_tag() when you need to build HTML in multiple steps.
vix::ui::HtmlAttrs attrs;
attrs.set("class", "container");
std::string html;
html += vix::ui::Html::open_tag("main", attrs);
html += vix::ui::Html::tag("h1", vix::ui::Html::text("Dashboard"));
html += vix::ui::Html::close_tag("main");Output:
<main class="container"><h1>Dashboard</h1></main>Normal tags
Use Html::tag() for tags with opening and closing elements.
const std::string title =
vix::ui::Html::tag(
"h1",
vix::ui::Html::text("Hello Vix"));Output:
<h1>Hello Vix</h1>With attributes:
vix::ui::HtmlAttrs attrs;
attrs.set("class", "title");
const std::string title =
vix::ui::Html::tag(
"h1",
vix::ui::Html::text("Hello Vix"),
attrs);Output:
<h1 class="title">Hello Vix</h1>Void tags
Use Html::void_tag() for tags that do not have closing tags.
vix::ui::HtmlAttrs attrs;
attrs.set("charset", "utf-8");
const std::string meta =
vix::ui::Html::void_tag("meta", attrs);Output:
<meta charset="utf-8" />Common void tags include:
meta
link
img
input
br
hrDoctype
Use Html::doctype() when generating a full HTML document.
const std::string html =
vix::ui::Html::doctype() +
"<html lang=\"en\">"
"<head>"
"<meta charset=\"utf-8\">"
"<title>Vix UI</title>"
"</head>"
"<body>"
"<h1>Hello</h1>"
"</body>"
"</html>";Output starts with:
<!doctype html>Practical card example
#include <vix/core.hpp>
#include <vix/ui.hpp>
int main()
{
vix::App app;
app.get("/", [](vix::Request &req, vix::Response &res) {
(void)req;
vix::ui::HtmlAttrs card_attrs;
card_attrs.set("class", "card");
vix::ui::HtmlAttrs title_attrs;
title_attrs.set("class", "title");
const std::string card =
vix::ui::Html::tag(
"section",
vix::ui::Html::tag(
"h1",
vix::ui::Html::text("Vix UI HTML"),
title_attrs) +
vix::ui::Html::tag(
"p",
vix::ui::Html::text(
"Small HTML fragments generated safely from C++.")),
card_attrs);
const std::string html =
vix::ui::Html::doctype() +
"<html lang=\"en\">"
"<head>"
"<meta charset=\"utf-8\">"
"<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">"
"<title>Vix UI HTML</title>"
"</head>"
"<body><main>" +
card +
"</main></body></html>";
res.ui(vix::ui::HtmlResponse::html(html));
});
app.run(8080);
return 0;
}Valid names
Tag names and attribute names are validated.
Valid examples:
div
section
custom-element
svg:path
class
data-id
aria-label
_privateInvalid examples:
1div
bad name
bad/nameInvalid names throw a HtmlError.
try
{
const std::string html =
vix::ui::Html::tag("1bad", "content");
}
catch (const vix::ui::HtmlError &)
{
// invalid tag name
}Common mistakes
Passing user input as raw HTML
Wrong:
std::string html = vix::ui::Html::raw(user_input);Correct:
std::string html = vix::ui::Html::text(user_input);Building full pages only with C++ strings
HTML helpers are good for small fragments.
For full pages, prefer:
vix::ui::View("dashboard.html")Templates are easier to read and maintain.
Forgetting attributes are escaped
You do not need to escape attribute values manually.
attrs.set("title", R"(Hello "Vix" & C++)");Vix UI handles the escaping when rendering.
Using HTML helpers as a frontend framework
HTML helpers are not a virtual DOM.
They are small server-side helpers for generating safe HTML.
For pages, use templates.
For small components, use Html, HtmlAttrs, and HtmlEscape.
Next step
Continue with HTML responses.