A Hugo module (not a standalone theme) that adds a polished, linktree-style
/links page to any existing Hugo site — or works standalone as the whole site.
- Pure CSS3: custom properties, native nesting,
color-scheme,light-dark(),color-mix(),@layer, backdrop-filter, animations - Auto light / dark mode — no JavaScript required
- 25+ inline SVG brand icons (fill-based, colour-controlled via CSS)
- Explicit icon selection via config; falls back to a generic link icon
- Staggered entrance animations
- Primary colour fully configurable via a single CSS variable
- Accessible: keyboard navigation,
focus-visible,prefers-reduced-motion - Works alongside any existing Hugo theme (PaperMod, Congo, Blowfish, etc.)
- Can also run standalone as the entire site
Lynko works in two modes. Choose one, or use both in the same site.
Use this when you already have a Hugo site with a theme and want to add a
linktree at yoursite.com/links/ without touching anything else.
hugo mod get github.com/haydenk/lynkoThen add to your hugo.toml:
[module]
[[module.imports]]
path = "github.com/haydenk/lynko"mkdir -p content/links
cat > content/links/_index.md << 'EOF'
+++
title = "Links"
layout = "lynko"
+++
EOFThe layout = "lynko" key is required — it tells Hugo to use Lynko's
self-contained page template. Without it, the section falls through to your
existing theme's list layout.
Your linktree is now live at yoursite.com/links/.
Add a [params.lynko] block to your hugo.toml:
[params.lynko]
title = "Hayden King"
handle = "@haydenk"
bio = "Designer · Developer · Coffee enthusiast"
avatar = "/images/me.jpg" # relative to /static
# Optional: override the accent colour
# primaryColor = "#0ea5e9"
[[params.lynko.links]]
title = "My Blog"
url = "https://myblog.example"
icon = "globe"
[[params.lynko.links]]
title = "GitHub Projects"
url = "https://github.com/haydenk"
icon = "github"
[[params.lynko.links]]
title = "Say hello"
url = "mailto:hi@example.com"
icon = "email"
target = "_self"
[[params.lynko.social]]
name = "github"
url = "https://github.com/haydenk"
[[params.lynko.social]]
name = "twitter"
url = "https://x.com/haydenk"Use this when the linktree is the entire site — no other pages, no theme.
hugo new site mylinks
cd mylinks
hugo mod init github.com/yourname/mylinkshugo mod get github.com/haydenk/lynkoAdd to hugo.toml:
[module]
[[module.imports]]
path = "github.com/haydenk/lynko"cat > content/_index.md << 'EOF'
+++
title = "Links"
layout = "lynko"
+++
EOFSame [params.lynko] block as Option A above.
Your linktree is now live at the root — yoursite.com/.
Set layout = "lynko" on both content/_index.md and
content/links/_index.md. Each renders independently from the same
[params.lynko] config.
All options live under [params.lynko].
| Key | Type | Default | Description |
|---|---|---|---|
title |
string | site title | Display name |
handle |
string | — | Subtitle / handle (@you) |
bio |
string | site description | Short bio text |
avatar |
string | — | Path to profile image (relative to /static or absolute URL) |
primaryColor |
string | #0ea5e9 |
Any valid CSS colour — overrides --lynko-primary |
showPoweredBy |
bool | true |
Show "Powered by Hugo" footer |
metaTitle |
string | "Name — Links" |
<title> override |
metaDesc |
string | bio | <meta description> override |
| Key | Required | Description |
|---|---|---|
url |
✓ | Destination URL or mailto: |
title |
✓ | Button label |
icon |
Icon name (see list below); omit to use the generic link icon |
|
target |
Link target; defaults to _blank |
|
rel |
Link rel; defaults to noopener noreferrer |
| Key | Required | Description |
|---|---|---|
name |
✓ | Icon name (see list below) |
url |
✓ | Profile URL |
| Name | Platform |
|---|---|
github |
GitHub |
twitter |
Twitter / X |
linkedin |
|
instagram |
|
youtube |
YouTube |
tiktok |
TikTok |
facebook |
|
discord |
Discord |
twitch |
Twitch |
mastodon |
Mastodon |
bluesky |
Bluesky |
reddit |
|
medium |
Medium |
substack |
Substack |
patreon |
Patreon |
spotify |
Spotify |
soundcloud |
SoundCloud |
pinterest |
|
snapchat |
Snapchat |
email / mail |
|
rss |
RSS feed |
globe / website |
Generic website |
link |
Generic link (fallback) |
The only variable you normally need is primaryColor in hugo.toml.
For deeper customisation, override any --lynko-* custom property in your
site's CSS, outside the lynko layer so it takes precedence:
/* assets/css/custom.css */
:root {
--lynko-radius-md: 1.5rem; /* rounder buttons */
--lynko-blur: 24px; /* stronger glass */
}- No JavaScript — 100% CSS light/dark mode, animations, and hover effects
- Self-contained page — the
lynkolayout renders its own<html>so it never inherits the parent theme's navigation, sidebar, or fonts. This is intentional: a linktree page should look distinct and load fast - Color-mix for tints — button backgrounds, borders, and glows are all
derived from
--lynko-primaryviacolor-mix(in srgb, …)so changing one variable updates the entire colour scheme - Staggered animations — entrance delays are set as inline CSS custom
properties (
--lynko-stagger) computed in the Hugo template, keeping the CSS clean
- Hugo v0.121.0+ (standard edition is sufficient — no Sass/PostCSS used)
- Go 1.22+
GPL-3.0-only. See LICENSE.