Light Mode

Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

weavejester/hiccup

Repository files navigation

Hiccup

Hiccup is a library for representing HTML in Clojure. It uses vectors to represent elements, and maps to represent an element's attributes.

Install

Add the following dependency to your deps.edn file:

hiccup/hiccup {:mvn/version "2.0.0"}

Or to your Leiningen project.clj file:

[hiccup "2.0.0"]

Documentation

Syntax

Here is a basic example of Hiccup syntax:

(str (h/html [:span {:class "foo"} "bar"])) "bar"">user=> (require '[hiccup2.core :as h])
nil
user=> (str (h/html [:span {:class "foo"} "bar"]))
"\"foo\">bar"

The first element of the vector is used as the element name. The second attribute can optionally be a map, in which case it is used to supply the element's attributes. Every other element is considered part of the tag's body.

Hiccup is intelligent enough to render different HTML elements in different ways, in order to accommodate browser quirks:

user=> (str (h/html [:script]))
""
user=> (str (h/html [:p]))
"

"

And provides a CSS-like shortcut for denoting id and class attributes:

user=> (str (h/html [:div#foo.bar.baz "bang"]))
"
\"foo\" class=\"bar baz\">bang
"

If the body of the element is a seq, its contents will be expanded out into the element body. This makes working with forms like map and for more convenient:

user=> (str (h/html [:ul
(for [x (range 1 4)]
[:li x])]))
"
  • 1
  • 2
  • 3
"

Strings are automatically escaped:

user=> (str (h/html [:p "Tags in HTML are written with <>"]))
"

Tags in HTML are written with <>

"

To bypass this, use the hiccup2.core/raw function:

user=> (str (h/html [:p (h/raw "Hello World")]))
"

Hello World

"

This can also be used for doctype declarations:

user=> (str (h/html (h/raw "") [:html {:lang "en"}]))
"\"en\">"

Differences between Hiccup 1 and 2

In brief: Hiccup 1 doesn't escape strings by default, while Hiccup 2 does. They occupy different namespaces to ensure backward compatibility.

In Hiccup 1, you use the h function to escape a string - that is, ensure that unsafe characters like <, > and & are converted into their equivalent entity codes:

(h1/html [:div "Username: " (h1/h username)])

In Hiccup 2 strings are escaped automatically, but the return value from the html macro is a RawString, rather than a String. This ensures that the html macro can still be nested.

(str (h2/html [:div "Username: " username]))

It's recommended to use Hiccup 2 where possible, particularly if your app handles user data. Use of the non-core namespaces, such as hiccup.page, should be avoided with Hiccup 2.

License

Copyright (c) 2025 James Reeves

Distributed under the Eclipse Public License either version 1.0 or (at your option) any later version.

About

Fast library for rendering HTML in Clojure

Topics

Resources

Readme

License

EPL-1.0 license

Contributing

Contributing

Stars

Watchers

Forks

Packages