Skip to main content
go-swarm-icons
On this page

Goldmark Integration

Embed icons directly in Markdown content using the Goldmark extension's inline icon syntax.

If the application renders Markdown (a blog, a wiki, a documentation site), the Goldmark extension lets content authors embed icons inline with :icon[prefix:name] syntax, with no Go code in the templates and no manual SVG markup.

Install

The Goldmark extension is in a separate submodule:

Terminal window
go get github.com/frostybee/go-swarm-icons/goldmark@latest

This module depends on the core module and github.com/yuin/goldmark.

Register the extension

Create an IconManager, then pass it to the extension when configuring Goldmark:

Go
import (
"bytes"
"fmt"
swarmicons "github.com/frostybee/go-swarm-icons"
swarmgoldmark "github.com/frostybee/go-swarm-icons/goldmark"
"github.com/frostybee/go-swarm-icons/lucide"
"github.com/yuin/goldmark"
)
func main() {
manager := swarmicons.Default("lucide", lucide.Provider())
ext := &swarmgoldmark.Extension{
Manager: manager,
SilentOnMissing: true,
}
md := goldmark.New(goldmark.WithExtensions(ext))
input := []byte("Click the :icon[lucide:home] icon to go home.")
var buf bytes.Buffer
if err := md.Convert(input, &buf); err != nil {
panic(err)
}
fmt.Println(buf.String())
}

Inline syntax

The parser recognizes the pattern :icon[...] in Markdown source text. Everything between the brackets is parsed as an icon name followed by optional attributes.

Basic usage

Markdown
:icon[lucide:home]

Bare name (default prefix)

If the manager has a default prefix set, the prefix can be omitted:

Markdown
:icon[home]

This resolves as manager.Get("home"), which uses the default prefix.

With attributes

Attributes follow the icon name, separated by spaces. Values can be double-quoted, single-quoted, or unquoted:

Markdown
:icon[lucide:star size="24" class="gold"]
:icon[lucide:star size='24' class='gold']
:icon[lucide:star size=24]

Multiple icons on one line

Markdown
:icon[lucide:home] and :icon[lucide:star]

Both icons render independently.

Transform vs. pass-through attributes

Attributes split into two groups based on the key name:

Transform attributes

These are applied via fluent Icon methods after the icon is resolved:

Attribute Fluent method Example
size icon.Size(int) size="24"
rotate icon.Rotate(float64) rotate="45"
flip icon.Flip(string) flip="h"
opacity icon.Opacity(float64) opacity="0.5"
title icon.Title(string) title="Home"

Transforms are applied in this order: size, rotate, flip, opacity, title.

Pass-through attributes

All other attributes (class, id, width, data-*, etc.) are passed to manager.Get() as caller-level attributes (layer 5 in the attribute merge). They follow the same merge rules as any other caller attributes.

Markdown
:icon[lucide:home class="icon-blue" id="nav-home"]

Missing icons

SilentOnMissing: true

When an icon is not found, the extension renders an HTML comment instead of returning an error:

HTML
<!-- SwarmIcons: Icon "lucide:missing" not found -->

The rest of the Markdown document continues to render normally.

SilentOnMissing: false (default)

Full example

Go
import (
"bytes"
"fmt"
swarmicons "github.com/frostybee/go-swarm-icons"
swarmgoldmark "github.com/frostybee/go-swarm-icons/goldmark"
"github.com/frostybee/go-swarm-icons/lucide"
"github.com/yuin/goldmark"
)
func main() {
manager, _ := swarmicons.NewConfig().
AddProvider("lucide", lucide.Provider()).
DefaultPrefix("lucide").
DefaultAttributes(map[string]string{
"stroke": "currentColor",
"stroke-width": "2",
"fill": "none",
}).
Build()
ext := &swarmgoldmark.Extension{
Manager: manager,
SilentOnMissing: true,
}
md := goldmark.New(goldmark.WithExtensions(ext))
input := []byte(`# Welcome
Click :icon[home] to return.
Rate this: :icon[star size="16" class="gold" rotate="45"]
`)
var buf bytes.Buffer
if err := md.Convert(input, &buf); err != nil {
panic(err)
}
fmt.Println(buf.String())
}

The output contains the <h1> heading, paragraph text with the inline <svg> for "home", and a second paragraph with a rotated, gold-classed star icon.

See also

Edit this page

Last updated: