HugoBlog

stark — Hugo Blog Template

By jimyag

Stark is a minimal Hugo blog theme based on hugo-bearblog that adds a table of contents, full-text search, Mermaid diagrams, image lightbox, and SEO structured data to a clean layout.

Explore the design

Compare the page layouts and mobile experience. Open any screenshot for a closer look.

3 previews
Desktop homepage1 / 3
Desktop captureTop of page

Actual screenshot captured by the server browser.

All pages & views 3

Screenshots show visual appearance; interactive behavior may differ.

Recorded 2026-09-30View source

What stands out

A quick read of the recorded project description.

01

The table of contents is fixed in the sidebar on wide screens and becomes a floating button with a slide-out panel on narrow screens

02

Client-side full-text search opened via Ctrl/Cmd+K or a navigation button, with no external service required

03

Mermaid diagrams and image lightbox support zoom, drag, and keyboard shortcuts

04

Outputs canonical, Open Graph, Twitter Card, and schema.org structured data

05

Resizes local images to a maximum width of 1200 px and converts them to WebP at build time

06

Built-in English and Chinese interfaces, with dark mode following system preference

Template Details

Stark is a minimal Hugo blog theme for text-focused personal blogs, built as an extension of hugo-bearblog. While keeping a clean layout, it adds reading-experience features such as a table of contents, client-side full-text search, Mermaid diagrams, image lightbox, code copy buttons, a reading progress bar, a back-to-top button, and math rendering, and outputs canonical, Open Graph, Twitter Card, and schema.org structured data.

The theme includes English and Chinese interfaces, automatically switches dark mode based on system preference, and supports a post list grouped by year with pinned posts, pagination, previous/next navigation, and related posts matched by tags. At build time, local images can be resized to a maximum width of 1200 px and converted to WebP. Search, RSS summaries, word count, and reading time do not depend on browser JavaScript; Mermaid and MathJax load only on pages that contain the corresponding content.

The theme also offers an optional MDX workflow that allows React components in posts, but it requires Node.js and a recent version of Hugo, and MDX pages do not go through Hugo shortcodes, Chroma highlighting, Mermaid code hooks, or automatic image processing. Chinese fonts rely on the reader's system having LXGW WenKai installed; the theme does not bundle complete font files.

HugoBlog

Is it right for your project?

Use Cases

  • Writing a text-focused personal technical blog that needs a table of contents and full-text search
  • Embedding Mermaid flowcharts or math formulas in posts and wanting scripts to load on demand
  • Needing a post list grouped by year, pinned posts, and tag-based related recommendations
  • Wanting post pages to provide a link to the original Markdown

Suitable For

  • Developers building personal blogs with Hugo
  • Writers who prefer a minimal layout but need reading features such as search and a table of contents
  • Sites that need bilingual English/Chinese interfaces or dark mode support
  • Users who want to mix React components into Markdown posts (requires enabling the optional MDX workflow)

Getting started & customization

Use these recorded setup notes alongside the repository instructions for your chosen version.

  1. 1

    Add the theme to themes/stark via git submodule and set theme = "stark" in hugo.toml

  2. 2

    Search requires adding JSON output for home in [outputs]

  3. 3

    Original Markdown links require adding MARKDOWN output for page and configuring the corresponding mediaTypes and outputFormats

  4. 4

    MDX is an optional workflow that requires Node.js and a recent version of Hugo, and the compile script must be run before each Hugo build

  5. 5

    The theme bundles the 0xProto font (SIL OFL); Chinese fonts rely on the reader's system having LXGW WenKai installed, and complete font files are not bundled

Read repository instructions

License & source material

Usage conditions & limitations

Free to use · keep license notice

This entry covers the free version in the public repository under the MIT license; the free scope is the code of that version and does not mean external services or third-party assets are free.

Must comply with when using

  • You may use, modify, commercialize, and distribute the code of this version for free.
  • When distributing copies or substantial portions of the code, retain the original author's copyright notice and the complete MIT license notice.
  • The code is provided as is; warranties and limitations of liability are governed by the original license and applicable law.

Additional costs & items to verify

  • The optional MDX workflow requires Node.js 22+ and Hugo 0.162+; a plain Markdown site can be built with Hugo alone.
  • The theme does not bundle complete LXGW WenKai Chinese font files; Chinese rendering depends on the reader's system having the font installed, otherwise you must add a site-level subset font yourself.
  • The github-file shortcode requests raw.githubusercontent.com in the browser to fetch public GitHub files, so it depends on that external service being available.
  • MDX pages use a separate renderer; Hugo shortcodes, Chroma highlighting, Mermaid code hooks, and automatic image processing do not apply in MDX.
  • The MDX compiler does not watch for file changes; after each modification to MDX or its imports, you must manually rerun the compile script.
  • When using additional React components in MDX, you must install the corresponding dependencies in your site's package.json yourself.
  • Demo images, fonts, icons, and other third-party assets must be checked against their respective licenses; the code's MIT license alone cannot be used to judge them.
  • External services such as domains, hosting, databases, payments, or AI may incur separate charges.
View Original Text Basis

Permission is hereby granted, free of charge

Original License Text

Node.js 22+ and Hugo 0.162+ are required for this optional workflow.

Original README

The full LXGW WenKai font is not bundled because the regular TTF is about 25 MB

Original README

The browser requests the corresponding `raw.githubusercontent.com` URL.

Original README

MDX uses its own renderer: Hugo shortcodes, Chroma highlighting, Mermaid code hooks, and automatic Hugo image processing do not run inside MDX.

Original README

Rerun the compiler after editing MDX or its imports; the compiler does not watch files.

Original README

Install extra component dependencies in your site's `package.json`.

Original README
https://github.com/jimyag/stark/blob/main/LICENSEhttps://github.com/jimyag/stark/blob/main/README.md

Compiled by DeepSeek based on repository license and README ·2026-10-01. Results only cover the materials read; dependencies, images, fonts, and subsequent term changes are subject to their respective original texts.

Project checks & description sources

Template Information

Source platforms
GitHub
Documentation and maintenance reference score
More documented · 80 / 100
Technologies
Hugo
Website type
Blog
How this score is calculated

Our heuristic uses license records (up to 30), a demo link (12), a preview (10), stars (15), recorded maintenance (15), description completeness (8), feature records (5) and classification data (5). It is not a code, security or performance test, or a Google score. A link does not establish tested functionality.

What to verify for this project

Repository update recorded
2026-09-27
Screenshot last checked
2026-10-01

A demo link is listed. Check it with your own content and viewport sizes; its presence does not confirm that forms, authentication or payments work.

The catalog identifies Hugo as the primary stack. Check the actual dependency manifest and lockfile for versions and hosting requirements. These notes use recorded metadata, not a code audit or a deployment test.

Use a selection guide →

How this description was prepared

AI-assisted description based on catalog records and repository material. Repository authors are not automatically the reviewers of this description.

Automatically checked against source and license rules; no manual editorial review.

Inspect the recorded source material

SHA-256: c2c36fa8340cafd55d81f41d7146ad16325e8e78bd999a1b8d088a2d2cbf48c1

2026-10-01T13:59:34.720Z

Source file / repository
# Stark

A minimal Hugo blog theme with practical enhancements. Based on [hugo-bearblog](https://github.com/janraasch/hugo-bearblog).

[![Check](https://github.com/jimyag/stark/actions/workflows/check.yaml/badge.svg)](https://github.com/jimyag/stark/actions/workflows/check.yaml)

Live demo: [jimyag.com](https://jimyag.com)

## Features

- Table of Contents — fixed sidebar on wide screens (>1400 px), floating button + slide-up modal on narrow screens
- Full-text search — client-side, no external service, `Ctrl/Cmd+K` or the Search button in the nav
- Mermaid diagrams — fenced code block with `mermaid` language tag; click to open zoomable lightbox (scroll wheel, drag, keyboard shortcuts)
- Image lightbox — click any image in a post to preview with zoom controls
- Code copy button — appears on hover over any highlighted code block
- Raw Markdown link — direct link from each post to its source Markdown
- Code block language label — language name shown in top-left corner of each code block
- Reading progress bar — 3 px bar at the top of the viewport
- Back to top button — appears after scrolling 300 px
- Math rendering — MathJax loaded automatically only on pages that contain `$...$` or `\(...\)` expressions
- Enhanced SEO — canonical URL, Open Graph, Twitter Card, schema.org structured data (WebSite, Person, BlogPosting, BreadcrumbList)
- Auto image optimization — local images resized to max 1200 px width and converted to WebP at build time
- Year-grouped post list with pinned posts at the top, pagination support
- Prev/Next post navigation at the bottom of each post
- Related posts section at the bottom of each post (matched by tags)
- Word count, estimated reading time, and last modified date in the post header
- Callout and details shortcodes
- Analytics — Plausible and Google Analytics 4 (opt-in, no script injected unless configured)
- i18n — English and Chinese built-in, extensible to any language
- Dark mode — automatic, follows system preference

## Typography

Stark bundles the 0xProto webfont for Latin text, code, and UI details. The font
files live in `static/fonts/` and are licensed under the SIL Open Font License;
see `static/fonts/0xProto-LICENSE.txt`.

Chinese text prefers the local `LXGW WenKai` / `霞鹜文楷` font when it is
installed on the reader's system. The full LXGW WenKai font is not bundled
because the regular TTF is about 25 MB; sites that need identical Chinese
rendering on every device should add a site-level subset font instead.

## Installation

```bash
git submodule add https://github.com/jimyag/stark.git themes/stark
```

Set the theme in `hugo.toml`:

```toml
theme = "stark"
```

## Configuration

A full working example is in [`exampleSite/hugo.toml`](exampleSite/hugo.toml). The annotated reference below covers every supported option.

```toml
baseURL = "https://example.com"

theme      = "stark"
title      = "ᕕ( ᐛ )ᕗ My Blog"
copyright  = "Copyright © 2024, Your Name."
locale       = "zh-CN"

enableRobotsTXT = true

# Suppress unused taxonomy pages; required for clean tag URLs
disableKinds = ["taxonomy"]
ignoreErrors = ["error-disable-taxonomy", "warning-goldmark-raw-html"]

[permalinks]
blog = "/posts/:slug/"
tags = "/blog/:slug"

# Search requires a JSON output on the home page
# Raw Markdown links require the MARKDOWN output on pages
[outputs]
  home = ["HTML", "RSS", "JSON"]
  page = ["HTML", "MARKDOWN"]

[mediaTypes]
  [mediaTypes."text/markdown"]
    suffixes = ["md"]

[outputFormats]
  [outputFormats.MARKDOWN]
    mediaType = "text/markdown"
    isPlainText = true
    notAlternative = true
    permalinkable = true
    ugly = true

[[menu.main]]
  name   = "RSS"
  url    = "/index.xml"
  weight = 2

[params]
description      = "A minimal blog about software engineering"
favicon          = "images/favicon.png"   # path under /static
images           = ["images/share.png"]   # default OG share image
dateFormat       = "2006-01-02"           # Go time format
hideMadeWithLine = false                  # set true to hide footer credit
# ogLocale       = "zh_CN"               # defaults to "en_US"

[params.author]
  name  = "Your Name"
  email = "[email protected]"   # used in RSS <managingEditor>

# Social links for schema.org Person structured data
[params.social]
  github        = "your-github-username"
  # stackoverflow = "https://stackoverflow.com/users/..."
  # twitter       = "your-twitter-handle"

[markup]
  [markup.goldmark]
    [markup.goldmark.renderer]
      unsafe = true   # allow raw HTML in Markdown
  [markup.highlight]
    style              = "monokai"
    lineNos            = true
    lineNumbersInTable = true
    codeFences         = true
    guessSyntax        = true
    noClasses          = false
  [markup.tableOfContents]
    startLevel = 2
    endLevel   = 4
```

## Content Structure

```
content/
├── _index.md          # home page body (Hugo renders .Content here)
├── blog/
│   ├── _index.md      # blog section (title = "Blog")
│   └── my-post/
│       ├── index.md   # post content (page bundle)
│       └── image.png  # local image — auto-optimized to WebP
└── friends.md         # any extra page; add to menu via front matter
```

### Home Page

`content/_index.md` or `content/_index.mdx` is rendered as the body of the home page. Use it for a bio, project table, or any Markdown content. The MDX variant can also import React components:

```markdown
+++
title = ""
+++

# Hi, I'm Your Name

Software engineer. Write about Go, Kubernetes, and systems engineering.
```

### Extra Menu Pages

Add any standalone page to the nav by setting `menu = "main"` and `weight` in the front matter:

```markdown
+++
title   = "Friends"
menu    = "main"
weight  = 2
+++
```

## Post Front Matter

```yaml
---
title: "Post Title"
description: "One-sentence summary used in meta tags and the search index."
date: 2024-06-01T12:00:00+08:00
slug: "post-slug"          # controls the URL: /posts/post-slug/
tags: ["go", "linux"]
pinned: false              # set true to pin to the top of the list
weight: 1                  # lower weight appears first among pinned posts
---
```

All fields except `title` and `date` are optional.

## Features In Detail

### MDX (optional)

Stark supports `.mdx` pages, including the home page and section pages, with imported React components, JSX,
expressions, and GitHub-flavored Markdown. Node.js 22+ and Hugo 0.162+ are
required for this optional workflow. Ordinary Markdown sites still build with
Hugo alone.

The compiler renders content to HTML at build time, then bundles React hydration
for each MDX page. The initial HTML contains the article and component output;
search, RSS summaries, word counts, and reading time remain available without
browser JavaScript. Only MDX pages load React.

From your **site root**, install the theme's locked dependencies and copy the
mount configuration once:

```bash
npm ci --prefix themes/stark
cp themes/stark/exampleSite/mdx.toml mdx.toml
```

Add `.stark-mdx/` and `.stark-mdx-build-*/` to your site's `.gitignore`. If you
already customize Hugo module mounts or content security, merge the settings in
`mdx.toml` with your existing configuration. The mounts combine generated HTML
pages with original content and local images; HTML content must be enabled.

Create `content/blog/my-post/index.mdx` alongside its React components:

```mdx
---
title: "My interactive post"
date: 2026-09-12T10:00:00+08:00
lastmod: 2026-09-12T10:00:00+08:00
description: "A small interactive example."
slug: "my-interactive-post"
tags: ["mdx"]
images: []
draft: false
---

import Counter from './Counter.jsx'

## Try it

This text is rendered at build time.

<Counter />
```

Use [Counter.jsx](exampleSite/content/blog/mdx-demo/Counter.jsx) as a starting
point. YAML and TOML (`+++`) front matter are supported. Compile before every
Hugo build, including in your deployment build command:

```bash
node themes/stark/scripts/mdx.mjs --site .
hugo --config hugo.toml,mdx.toml
```

For local preview, use `hugo server --config hugo.toml,mdx.toml` after compiling.
Rerun the compiler after editing MDX or its imports; the compiler does not watch
files. Drafts and future posts are excluded, including their generated assets.
To preview them, compile with `--drafts --future` and run Hugo with `-D -F`.
Expired pages are always excluded. Use explicit page dates and draft fields;
the compiler does not evaluate Hugo cascades or custom publication-date rules.

Try the included example from the **theme root**:

```bash
npm ci
npm run mdx -- --site exampleSite
hugo server --source exampleSite --themesDir ../.. --config hugo.toml,mdx.toml
```

MDX headings appear in Stark's TOC, with levels 2–4 by default. Override
`params.mdx.tocStartLevel` and `params.mdx.tocEndLevel` for MDX pages. The article's
source link downloads the original MDX; it does not include imported component
files. MDX pages emit HTML instead of the ordinary raw Markdown output.

Boundaries:

- Each `.mdx` file under `content/` is a page. Use `.jsx` or `.tsx` for imported
  components. Home and section `_index.mdx` files are supported and hydrate
  through their corresponding list or home layout.
- Do not keep both `index.md` and `index.mdx` for the same page. Generated files
  stay under `.stark-mdx/`; source content is never overwritten.
- React components must render on the server. Access browser globals such as
  `window` inside effects or event handlers. Install extra component dependencies
  in your site's `package.json`.
- MDX uses its own renderer: Hugo shortcodes, Chroma highlighting, Mermaid code
  hooks, and automatic Hugo image processing do not run inside MDX. Relative
  image URLs in page bundles work; Markdown pages retain their existing features.
- MDX is executable source code. Compile articles and imports you trust.

Integration references: [MDX compiler](https://mdxjs.com/packages/mdx/),
[React hydration](https://react.dev/reference/react-dom/client/hydrateRoot), and
[Hugo content formats](https://gohugo.io/content-management/formats/).

### Search

Search is built client-side from a JSON index generated at build time. It requires no external service. Open with the Search button in the nav or `Ctrl/Cmd+K`. Results are scored by title (10×), tags (5×), and content (1×), top 10 shown.

Requires the JSON output on the home page:

```toml
[outputs]
  home = ["HTML", "RSS", "JSON"]
```

### Raw Markdown Link

Post pages can show a "Markdown" link to the generated Markdown output for the current page. With the configuration below, `/posts/hello-world/` links to its raw Markdown at `/posts/hello-world.md`.

```toml
[outputs]
  home = ["HTML", "RSS", "JSON"]
  page = ["HTML", "MARKDOWN"]

[mediaTypes]
  [mediaTypes."text/markdown"]
    suffixes = ["md"]

[outputFormats]
  [outputFormats.MARKDOWN]
    mediaType = "text/markdown"
    isPlainText = true
    notAlternative = true
    permalinkable = true
    ugly = true
```

### Pinned Posts

Set `pinned: true` in a post's front matter. Pinned posts appear above the year-grouped list. Use `weight` to control ordering among pinned posts (lower = higher in the list).

### Mermaid Diagrams

Use a fenced code block with the `mermaid` identifier. The Mermaid JS library is loaded only on pages that contain at least one diagram.

````markdown
```mermaid
graph TD
    A[Client] --> B[Server]
    B --> C[(Database)]
```
````

Click a rendered diagram to open the lightbox. Keyboard shortcuts inside the lightbox: `+`/`-` to zoom, `0` or Space to reset, `Escape` to close.

### Math

Inline: `$E = mc^2$`

Block:

```markdown
$$
\int_{-\infty}^{\infty} e^{-x^2} dx = \sqrt{\pi}
$$
```

MathJax is injected into the `<head>` only on pages that contain math expressions (detected by scanning `.RawContent` for `$`, `\(`, or `\[`).

### Table of Contents

The TOC is generated automatically from headings within the range set in `[markup.tableOfContents]` (default h2–h4). It is only shown when the rendered TOC is longer than 100 characters.

- Screen width > 1400 px: fixed sidebar to the left of the content
- Screen width ≤ 1400 px: floating "目录" button (bottom-right) opens a slide-up modal

### Image Lightbox

All images inside the main content area get a click handler. Clicking opens a fullscreen overlay with zoom-in/zoom-out buttons. Keyboard: `+`/`-` to zoom, `Escape` to close.

Local images in page bundles are automatically processed: resized to a max width of 1200 px and converted to WebP with `loading="lazy" decoding="async"`.

### Related Posts

At the bottom of each post, up to 6 posts that share at least one tag are shown as "相关文章". This section is hidden if there are no tag matches.

### Dark Mode

The theme follows the OS/browser `prefers-color-scheme` preference. No toggle is provided; switching is handled automatically.

### Prev/Next Post Navigation

Each post page shows navigation links to the previous and next post within the same section (ordered by date). The links appear below the related posts section.

### Last Modified Date

If a post's `lastmod` date (set via git or explicitly in front matter) differs from its `date`, a "Last modified" line is shown below the reading time.

To enable automatic `lastmod` from git commit history, add to `hugo.toml`:

```toml
[frontmatter]
  lastmod = ["lastmod", ":git", "date"]
```

### Reading Progress Bar

A 3 px bar at the top of the viewport shows reading progress on every page. It fills as the user scrolls and updates in real time.

### Code Block Language Label

A small language label (e.g. `go`, `bash`) is shown in the top-left corner of every syntax-highlighted code block. It reads the `data-lang` attribute set by Hugo's Chroma highlighter.

### Callout Shortcode

```markdown
{{</* callout type="note" */>}}
Informational note. Markdown is supported.
{{</* /callout */>}}

{{</* callout type="tip" title="Custom title" */>}}
A helpful tip.
{{</* /callout */>}}

{{</* callout type="warning" */>}}
Something to be cautious about.
{{</* /callout */>}}

{{</* callout type="danger" */>}}
Critical warning.
{{</* /callout */>}}
```

Available types: `note` (default), `tip`, `warning`, `danger`.

### GitHub File Shortcode

Public GitHub files can be requested in the browser and displayed with line
numbers. Use a commit, tag, or branch without a slash in the `blob` URL:

```markdown
{{</* github-file url="https://github.com/kubernetes/kubernetes/blob/52ba90138eb40cab0987dac73e05c838149bdd1c/staging/src/k8s.io/api/core/v1/types.go#L8287-L8326" */>}}
```

Without a line anchor, the whole file is displayed. The code area scrolls both
vertically and horizontally, and can be collapsed. `start` and `end` can also
be passed when the line range is easier to read separately:

```markdown
{{</* github-file
  url="https://github.com/example/project/blob/main/example.go"
  start="10"
  end="30"
*/>}}
```

Syntax highlighting is loaded asynchronously after the file is shown. If the
highlighter is unavailable, the component keeps the readable plain-text view.

For MDX pages, import the shared component from `content/GitHubFile.jsx`:

```mdx
import GitHubFile from '../../GitHubFile.jsx'

<GitHubFile url="https://github.com/example/project/blob/main/example.go" />
```

The URL must point to a public `github.com/<owner>/<repo>/blob/<ref>/<path>`
file. The browser requests the corresponding `raw.githubusercontent.com` URL.
Invalid URLs, missing files, request failures, and files larger than 5 MiB are
shown as errors in the article.

### Details Shortcode

```markdown
{{</* details summary="Click to expand" */>}}
Hidden content revealed on click.
{{</* /details */>}}
```

### Pagination

Set `pagerSize` in `hugo.toml` to control the number of posts per page (Hugo v0.128+ syntax):

```toml
[pagination]
  pagerSize = 20
```

Pinned posts are always shown in full on every page and are not included in the paginator.

### Analytics

Plausible:

```toml
[params.analytics]
  plausible = "yourdomain.com"
```

Google Analytics 4:

```toml
[params.analytics]
  googleAnalyticsId = "G-XXXXXXXXXX"
```

Both can be set at the same time. Neither script is injected unless the corresponding key is present.

### i18n

The theme ships with English (`en`) and Chinese (`zh-CN`) translations. To use English:

```toml
locale = "en-US"
defaultContentLanguage = "en"
```

To add another language, create `i18n/<code>.toml` in your site (not the theme) and translate the keys from `i18n/zh.toml`.

## Development

With Node.js 22 and Hugo 0.165 installed, run the MDX and Hugo smoke tests:

```bash
npm ci
node --test tests/*.test.mjs
```

## Credits

- [hugo-bearblog](https://github.com/janraasch/hugo-bearblog) by Jan Raasch (MIT)
- [Bear Blog](https://bearblog.dev) by Herman Martinus

## License

MIT
Report a correction

Explore similar templates

Compare previews and descriptions within the same stack and category.