https://github.com/haydenk/lynko
Hugo module that adds a polished, zero-JS linktree-style /links page to any Hugo site — auto light/dark mode, 25+ SVG icons, and a single CSS variable to theme it.
https://github.com/haydenk/lynko
css dark-mode hugo hugo-module hugo-theme link-page linktree no-javascript static-site svg-icons
Last synced: about 1 month ago
JSON representation
Hugo module that adds a polished, zero-JS linktree-style /links page to any Hugo site — auto light/dark mode, 25+ SVG icons, and a single CSS variable to theme it.
- Host: GitHub
- URL: https://github.com/haydenk/lynko
- Owner: haydenk
- License: gpl-3.0
- Created: 2026-03-01T05:24:06.000Z (about 1 month ago)
- Default Branch: develop
- Last Pushed: 2026-03-01T19:11:03.000Z (about 1 month ago)
- Last Synced: 2026-03-01T19:35:02.140Z (about 1 month ago)
- Topics: css, dark-mode, hugo, hugo-module, hugo-theme, link-page, linktree, no-javascript, static-site, svg-icons
- Language: HTML
- Homepage: https://haydenk.github.io/lynko/
- Size: 50.8 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Funding: .github/FUNDING.yml
- License: LICENSE
Awesome Lists containing this project
README
# Lynko
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
---
## Usage
Lynko works in two modes. Choose one, or use both in the same site.
---
### Option A — Add a `/links` page to an existing 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.
#### 1 · Import the module
```bash
hugo mod get github.com/haydenk/lynko
```
Then add to your `hugo.toml`:
```toml
[module]
[[module.imports]]
path = "github.com/haydenk/lynko"
```
#### 2 · Create the section page
```bash
mkdir -p content/links
cat > content/links/_index.md << 'EOF'
+++
title = "Links"
layout = "lynko"
+++
EOF
```
The `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/`.
#### 3 · Configure your links
Add a `[params.lynko]` block to your `hugo.toml`:
```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"
```
---
### Option B — Standalone site (homepage is the linktree)
Use this when the linktree *is* the entire site — no other pages, no theme.
#### 1 · Create a new Hugo site
```bash
hugo new site mylinks
cd mylinks
hugo mod init github.com/yourname/mylinks
```
#### 2 · Import the module
```bash
hugo mod get github.com/haydenk/lynko
```
Add to `hugo.toml`:
```toml
[module]
[[module.imports]]
path = "github.com/haydenk/lynko"
```
#### 3 · Set the homepage layout
```bash
cat > content/_index.md << 'EOF'
+++
title = "Links"
layout = "lynko"
+++
EOF
```
#### 4 · Configure your links
Same `[params.lynko]` block as Option A above.
Your linktree is now live at the root — `yoursite.com/`.
---
### Option C — Both (standalone homepage + `/links` section)
Set `layout = "lynko"` on both `content/_index.md` and
`content/links/_index.md`. Each renders independently from the same
`[params.lynko]` config.
---
## Configuration reference
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"` | `` override |
| `metaDesc` | string | bio | `` override |
### `[[params.lynko.links]]`
| 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` |
### `[[params.lynko.social]]`
| Key | Required | Description |
|---|---|---|
| `name` | ✓ | Icon name (see list below) |
| `url` | ✓ | Profile URL |
---
## Supported icons
| Name | Platform |
|---|---|
| `github` | GitHub |
| `twitter` | Twitter / X |
| `linkedin` | LinkedIn |
| `instagram` | Instagram |
| `youtube` | YouTube |
| `tiktok` | TikTok |
| `facebook` | Facebook |
| `discord` | Discord |
| `twitch` | Twitch |
| `mastodon` | Mastodon |
| `bluesky` | Bluesky |
| `reddit` | Reddit |
| `medium` | Medium |
| `substack` | Substack |
| `patreon` | Patreon |
| `spotify` | Spotify |
| `soundcloud` | SoundCloud |
| `pinterest` | Pinterest |
| `snapchat` | Snapchat |
| `email` / `mail` | Email |
| `rss` | RSS feed |
| `globe` / `website` | Generic website |
| `link` | Generic link (fallback) |
---
## Theming & CSS customisation
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:
```css
/* assets/css/custom.css */
:root {
--lynko-radius-md: 1.5rem; /* rounder buttons */
--lynko-blur: 24px; /* stronger glass */
}
```
---
## Design decisions
- **No JavaScript** — 100% CSS light/dark mode, animations, and hover effects
- **Self-contained page** — the `lynko` layout renders its own `` 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-primary` via `color-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
---
## Requirements
- Hugo **v0.121.0+** (standard edition is sufficient — no Sass/PostCSS used)
- Go 1.22+
---
## License
GPL-3.0-only. See [LICENSE](LICENSE).