Skip to content

About

A newspaper-style Hugo theme for news sites and blogs

Resources

Stars

2 stars

Watchers

0 watching

Forks

Repository files navigation

Broadsheet

A newspaper-style Hugo theme designed for news sites, magazines, and blogs that want the aesthetic of a traditional broadsheet newspaper with modern performance.

Live Demo: ap7i.com

Note: This theme is in active development (v0.x). The configuration options, templates, and CSS classes may change before v1.0 stable release.

Features

  • Newspaper-style masthead with date, navigation, and site title
  • Multi-column grid layouts for homepage stories
  • Featured article support for lead stories
  • Responsive design optimized for mobile reading
  • Dark mode follows system preference automatically, respecting individual user settings
  • Share buttons for LinkedIn, Facebook, X, and Reddit (optional, zero JavaScript)
  • Fast performance - minimal JavaScript, optimized CSS
  • Clean typography using Libre Baskerville (headlines) and Source Sans (body)
  • Section labels for categorizing articles
  • Reading time estimates
  • SEO optimized with proper meta tags and semantic HTML

Requirements

  • Hugo Extended v0.158.0 or later (Extended for SCSS/CSS processing; that release introduced the locale setting the templates read)
  • Git (for submodule installation)

Installation

Option 1: Git Submodule (Recommended)

This method allows you to easily update the theme and track which version you're using.

# Navigate to your Hugo site
cd your-hugo-site

# Add the theme as a submodule
git submodule add https://github.com/parkscloud/hugo-broadsheet.git themes/broadsheet

# Initialize and update (if cloning a site that already has the submodule)
git submodule update --init --recursive

To update the theme later:

git submodule update --remote themes/broadsheet

Option 2: Git Clone

If you want to modify the theme directly or don't want to use submodules:

cd your-hugo-site
git clone https://github.com/parkscloud/hugo-broadsheet.git themes/broadsheet

# Remove .git to avoid nested repo issues
rm -rf themes/broadsheet/.git

Option 3: Download ZIP

  1. Download the latest release or main branch ZIP
  2. Extract to your-hugo-site/themes/broadsheet/

After Installation

Add to your hugo.toml:

theme = 'broadsheet'

Configuration

Full configuration example for hugo.toml:

theme = 'broadsheet'

# Generate robots.txt from the theme's template (see SEO below)
enableRobotsTXT = true

[params]
  # Site tagline (appears below masthead title)
  tagline = "All the news that's fit to print"

  # robots.txt always allows every crawler and lists the sitemap. Set this to
  # also name the major AI crawlers and say yes to AI training and AI answers.
  # Off by default.
  robotsAllowAI = false

  # <title> and meta description limits, in characters. The defaults match
  # Bing Webmaster Tools; 0 turns a limit off. See SEO below.
  titleMaxLength = 70
  descriptionMaxLength = 160

  # How a tag page names itself in <title>; %s is the tag. Use "%s" for
  # the bare name.
  tagTitleFormat = "Posts tagged %s"

  # Structured data (JSON-LD). Off unless enable = true; see SEO below.
  [params.schema]
    enable = true
    logo = "images/logo.png"        # publisher logo, relative to the site root
    logoWidth = 600
    logoHeight = 300
    license = "https://creativecommons.org/licenses/by/4.0/"   # optional
    [params.schema.person]          # optional: the site's main author
      name = "Jane Smith"
      url = "about/"
      jobTitle = "Editor"
      bylines = ["Jane Smith"]      # front matter author values that mean this person
      sameAs = ["https://www.linkedin.com/in/example/"]
    [params.schema.aiMakers]        # optional: add AI model families
      Mistral = "Mistral AI"

  # Show reading time on articles
  showReadingTime = true

  # Enable search functionality
  enableSearch = true

  # Enable share buttons (LinkedIn, Facebook, X)
  enableShareButtons = true

  # Footer links
  [[params.footerLinks]]
    name = "About"
    url = "/about/"
  [[params.footerLinks]]
    name = "Contact"
    url = "/contact/"

[menu]
  [[menu.main]]
    name = "News"
    url = "/posts/"
    weight = 1
  [[menu.main]]
    name = "Opinion"
    url = "/opinion/"
    weight = 2
  [[menu.main]]
    name = "Technology"
    url = "/tech/"
    weight = 3

Content Front Matter

Posts support the following front matter:

---
title: "Article Headline"
date: 2026-01-01
draft: false
author: "Jane Reporter"
section: "Technology"
summary: "A brief summary that appears in article lists and the lead story."
image: "/images/article-image.jpg"
imageCaption: "Photo credit or description"
featured: true  # Makes this the lead story on homepage
tags: ["breaking", "tech"]
---

Front Matter Fields

Field Description
title Article headline
date Publication date
author Byline (e.g., "By Jane Reporter")
section Section label (e.g., "Technology", "Opinion")
summary Brief description for lists and featured display
pageTitle Optional text for <title> in place of the headline; the heading on the page, Open Graph, Twitter and JSON-LD keep title
image Featured image path
imageCaption Image caption/credit
featured Set true to make this the lead story
tags Array of tags for categorization

Images

All images in Broadsheet use a 16:9 aspect ratio with object-fit: cover. This applies to:

  • Article hero images
  • Lead story images on homepage
  • Story card thumbnails

Recommended specifications:

Spec Value
Aspect ratio 16:9
Dimensions 1200×675 px
Format WebP (with JPG or PNG fallback)
Max file size 150 KB

Usage in front matter:

image: "/images/posts/my-article.webp"
imageCaption: "Photo credit or description"

Automatic fallback detection: When using WebP images, Broadsheet automatically provides a fallback for browsers that don't support WebP. The theme uses the HTML <picture> element to serve WebP to modern browsers while falling back to JPG or PNG for older ones.

At build time, Hugo checks which fallback file exists:

  1. If a .jpg file exists with the same base name, it uses JPG as the fallback
  2. Otherwise, if a .png file exists, it uses PNG as the fallback
  3. If neither exists, the WebP is used directly (older browsers will show a broken image)

This auto-detection means you can use JPG fallbacks for photographs (smaller file size) and PNG fallbacks for graphics with transparency or sharp edges, without any configuration.

To use this feature:

  1. Save both formats with the same base name (e.g., my-article.webp and my-article.jpg)
  2. Reference only the .webp file in front matter
  3. The theme automatically detects and uses the appropriate fallback

Preparation tips:

  • Crop to 16:9 before uploading to avoid unexpected cropping
  • Provide a JPG fallback for photographs (better compression)
  • Provide a PNG fallback for graphics, screenshots, or images needing transparency
  • Compress images to under 150KB for fast mobile loading
  • Store in static/images/ and reference with absolute paths
  • Use Squoosh for easy browser-based conversion with visual comparison

Homepage Layout

The homepage displays articles in a newspaper-style layout:

  1. Lead Story - The most recent featured: true article (or most recent if none featured)
  2. Secondary Stories - Next 4 articles in a grid
  3. Earlier - Remaining articles in a list format (appears when you have more than 5 posts)

Lead story layout: When the featured post has an image, the layout is two-column (content + image). Without an image, content spans full width.

Dark Mode

Broadsheet automatically adapts to the user's system preference using CSS media queries (prefers-color-scheme). There is no manual toggle—the theme respects whatever the user has configured on their device:

  • iOS/Android users with auto-switching see the theme change with sunrise/sunset
  • Users who prefer dark mode always see the dark theme
  • Default system users see the light theme

This approach:

  • Respects individual user preferences without requiring interaction
  • Eliminates JavaScript for theme switching
  • Works immediately on first page load (no flash of wrong theme)

Share Buttons

Optional social sharing buttons appear at the end of articles when enabled:

[params]
  enableShareButtons = true

Supported platforms: LinkedIn, Facebook, X (Twitter), Reddit

Implementation details:

  • Zero JavaScript—uses simple share URLs that open each platform's share dialog
  • No tracking scripts or external requests
  • Icons use inline SVG (Feather Icons style, MIT licensed)
  • Styled as subtle circular buttons that match the theme

When disabled (default), no share UI appears on article pages.

Customization

Footer

The footer includes a .cc-icon class for Creative Commons icons. To add CC license icons to your footer, use inline SVGs in your layouts/partials/footer.html:

<svg class="cc-icon" viewBox="0 0 24 24"><!-- CC icon path --></svg>
<svg class="cc-icon" viewBox="0 0 24 24"><!-- BY icon path --></svg>
CC BY 4.0

The icons automatically scale with text size and inherit the link color.

Links in params.footerLinks whose URL starts with http:// or https:// open in a new tab with rel="noopener noreferrer"; relative links such as /about/ open in place.

Colors

Override CSS custom properties in your own stylesheet:

:root {
  --color-accent: #1a5f7a;  /* Change accent color */
  --font-headline: 'Playfair Display', serif;  /* Different headline font */
}

Typography

Fonts are self-hosted for performance and privacy (no external requests):

  • Headlines: Libre Baskerville (serif)
  • Body: Source Sans 3 (sans-serif)

To use different fonts, replace the files in static/fonts/ and update the @font-face declarations in assets/css/broadsheet.css.

Callout Boxes

Use the .callout class to highlight example content, notes, or other material that should stand out from the main text. Callouts display with a shaded background and subtle left border.

Usage in markdown:

<div class="callout">

Your content here. Markdown formatting works inside the div,
but you need a blank line after the opening tag.

- Lists work
- **Bold** and *italic* work
- Headers work

</div>

Note: Hugo requires unsafe = true in your markup configuration for raw HTML in markdown:

[markup.goldmark.renderer]
  unsafe = true

Performance

Broadsheet is built for speed:

  • Zero JavaScript for core functionality (dark mode via CSS media queries)
  • Self-hosted fonts - no external requests to Google or other CDNs
  • CSS-only layouts (no CSS frameworks)
  • System font fallbacks for fast initial render
  • Responsive images with lazy loading
  • Minified output when built with hugo --minify

SEO

Broadsheet follows SEO best practices:

  • Proper H1 structure — The site title renders as <h1> on the homepage only; inner pages use <h1> for the article title
  • Content-first page titles — Inner pages use Article Title | Site so the <title> opens with the same words as the <h1>; the homepage uses Site | tagline. Titles stay within params.titleMaxLength (default 70, Bing Webmaster Tools' limit): the site name is dropped when there's no room for it, and a headline that is still too long is cut at a word break with "…". A page's pageTitle front matter replaces the headline in <title>, which suits a one-word headline (Bing reports "Title too short" under 15 characters), and tag pages read Posts tagged Name (params.tagTitleFormat).
  • Meta descriptions — Taken from the page's description field, else its summary, else the site's description param, and kept within params.descriptionMaxLength (default 160). A longer text keeps its opening sentences, or is cut at a word break with "…" when they would be too short. Open Graph, Twitter and JSON-LD keep the full text.
  • Open Graph tags — Article images and descriptions are included for social sharing
  • Twitter Cards — Large image cards for better visibility when shared
  • Semantic HTML — Proper use of <article>, <header>, <nav>, <footer>, and <time> elements
  • Canonical URLs — Prevents duplicate content issues
  • Structured data (JSON-LD) — With params.schema.enable = true, every page carries one JSON-LD @graph describing the publisher (Organization), the site's main author (Person, when configured), and the WebSite. Articles add a BlogPosting (headline, dates, images, author, publisher, section, tags, license, isAccessibleForFree) and a BreadcrumbList; the author's profile page becomes an AboutPage. Bylines that start with a known AI model family (Claude, GPT, Gemini, Grok, Kimi, Muse, Qwen, plus any in params.schema.aiMakers) are described as the model, typed Organization, with its maker as parentOrganization and the configured person as editor; other bylines become a Person. The block is a data block, so it works under a strict script-src Content Security Policy with no 'unsafe-inline'.
  • robots.txt — With enableRobotsTXT = true, the theme writes a robots.txt that allows every crawler and lists the sitemap by absolute URL, replacing Hugo's built-in one-line default. Setting params.robotsAllowAI = true also names the major search and AI crawlers (GPTBot, OAI-SearchBot, ClaudeBot, Claude-SearchBot, PerplexityBot, Google-Extended, Applebot-Extended, and others) and adds yes signals for search, AI answers, and AI training in two formats: the IETF AI preferences draft's Content-Usage and Cloudflare's Content-Signal. The same group includes the proposed __usage_ai-training policy token with Allow: /, expressing an affirmative preference under that convention; a wildcard alone does not count. These signals communicate intent and do not guarantee inclusion or citations. If the site has static/llms.txt, the file points to it. A site can override the whole file with its own layouts/robots.txt.

Browser Support

  • Chrome, Firefox, Safari, Edge (latest versions)
  • Mobile browsers (iOS Safari, Chrome for Android)
  • Graceful degradation for older browsers

Versioning

This project uses Semantic Versioning:

  • 0.x.y - Development releases (current)
    • 0.1.0 - Initial release
    • 0.x.0 - New features, may include breaking changes
    • 0.x.y - Bug fixes and minor improvements
  • 1.0.0 - First stable release (when feature-complete and battle-tested)
  • 1.x.y - Stable releases with backward compatibility

Current status: Pre-release development. Expect changes to templates, CSS classes, and configuration options before v1.0.

Development

Running the Example Site

The exampleSite/ directory contains a complete demo site. To run it locally:

cd hugo-broadsheet/exampleSite
hugo server --themesDir /path/to/parent/of/hugo-broadsheet

For example, if your theme is at /home/user/repos/hugo-broadsheet:

cd /home/user/repos/hugo-broadsheet/exampleSite
hugo server --themesDir /home/user/repos

Theme Development

When making changes to the theme, the example site will live-reload automatically.

Contributing

Contributions are welcome! Please open an issue to discuss changes before submitting a PR.

License

MIT License - see LICENSE for details.

Third-Party Licenses

This theme includes the following third-party assets, which are distributed under their respective open-source licenses:

Fonts (SIL Open Font License 1.1)

The fonts included in static/fonts/ are licensed under the SIL Open Font License 1.1, which permits:

  • Free use in personal and commercial projects
  • Modification and redistribution
  • Bundling with other software
Font Copyright License File
Libre Baskerville 2012 Pablo Impallari, Rodrigo Fuenzalida static/fonts/LICENSE-LibreBaskerville.txt
Source Sans 3 2010-2020 Adobe static/fonts/LICENSE-SourceSans.md

Icons (MIT License)

Icon Set Copyright License File
Feather Icons 2013-2023 Cole Bemis static/fonts/LICENSE-FeatherIcons.txt

Icons are embedded as inline SVG in templates (no external requests).

Changelog

v0.7.5 - 2026-05-10

  • .callout pre now wraps text instead of horizontal-scrolling: white-space: pre-wrap; overflow-wrap: anywhere; overflow-x: visible; overrides the default .article-content pre { overflow-x: auto; } rule when a <pre> is nested inside a <div class="callout">. Use this pattern for long preformatted content that benefits from monospace structure but needs to wrap to the column width — e.g., an API call with a long string parameter, a long shell command, or a structured config file. Indentation is preserved; long lines wrap.

v0.7.2 - 2026-03-31

  • Dark mode image support: <picture> elements now auto-detect -dark variants via fileExists() and serve them with media="(prefers-color-scheme: dark)"

v0.7.0 - 2026-02-09

  • Widened list page layout from 720px to 1200px to match homepage width

v0.3.9 - 2026-01-30

  • Auto-detect JPG or PNG fallback for WebP images at build time (JPG preferred for photos, PNG for graphics)

v0.3.8 - 2026-01-12

  • Added PNG fallback support on homepage for WebP images using <picture> element

v0.3.7 - 2026-01-09

  • Standardized footer link styling: all links now show color change on hover without underlines

v0.3.6 - 2026-01-07

  • Added markdown render hook for external links opening in new tabs

v0.3.0 - 2026-01-01

  • Title format updated to show site name before page name
  • Various layout and typography refinements

Credits

About

A newspaper-style Hugo theme for news sites and blogs

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages