Skip to content
Docs

Configuration reference

Every knob the theme exposes. Hugo reads hugo.toml [params]; Astro reads src/config.ts, same keys, same meaning.

Site identity

title, tagline, description, brandName + brandSub (the two-line wordmark in the header), logo, ogImage, and landAcknowledgement (footer slot, leave empty to hide).

[params]
  tagline = "A friendly coding meetup"
  brandName = "Rocky Cove"
  brandSub = "Aquarium Club"
  logo = "images/logo.png"
  landAcknowledgement = "…"
export const SITE = {
  title: 'Rocky Cove Aquarium Club',
  tagline: 'A friendly coding meetup',
  brandName: 'Rocky Cove',
  brandSub: 'Aquarium Club',
  logo: '/images/logo.png',
  landAcknowledgement: '…',
};

Brand tokens

The whole visual identity, one block. Only primary is required to re-brand; the rest have sensible defaults. See Theming for how derived tints work.

KeyWhat it controls
primary / primaryHover / primaryActivebuttons, links, accents
link / linkHoverprose link color, when the default (derived from primaryActive) lacks contrast against body text
secondarysecondary buttons, persona accents
accentoccasional highlights
accentHoveraccent-button hover (defaults to a darkened accent)
inkheadings & dark text
surfaceWash / surfaceWashSofthero wash & soft bands
surfaceInkfooter / dark strips
fontSans / fontDisplaybody & display faces
radiusCard, containerMaxcard corners, page width
surfacePage / surfaceCard / surfaceTertiary / textBody / textMuted / textOnBrand / borderSubtledark-palette keys: page & card backgrounds, body/muted text, filled-button text, borders. Set these (plus the surfaces above) to run the theme on a dark background

Top menu = standard Hugo menu ([[menu.main]]). Header button = [params.cta] (label, url, icon).

Top menu = NAV array. Header button = CTA (label, url, icon).

  • footer.tagline + footer.columns: link columns (they lay out side by side and wrap on small screens)
  • social: icon links in the footer. Any Font Awesome class works, so adding a channel is one entry:
[[params.social]]
  label = "YouTube"
  icon  = "fa-brands fa-youtube"
  url   = "https://youtube.com/@yourcommunity"
[[params.social]]
  label = "TikTok"
  icon  = "fa-brands fa-tiktok"
  url   = "https://tiktok.com/@yourcommunity"
[[params.social]]
  label = "Mastodon"
  icon  = "fa-brands fa-mastodon"
  url   = "https://fosstodon.org/@yourcommunity"
[[params.social]]
  label = "RSS"
  icon  = "fa-solid fa-rss"
  url   = "/blog/index.xml"
export const SOCIAL = [
  { label: 'YouTube', icon: 'fa-brands fa-youtube', url: 'https://youtube.com/@yourcommunity' },
  { label: 'TikTok', icon: 'fa-brands fa-tiktok', url: 'https://tiktok.com/@yourcommunity' },
  { label: 'Mastodon', icon: 'fa-brands fa-mastodon', url: 'https://fosstodon.org/@yourcommunity' },
  { label: 'RSS', icon: 'fa-solid fa-rss', url: '/rss.xml' },
];
  • support: optional box at the end of every blog post (badge, text, CTAs). Omit / set null to hide.

Feeds & sharing defaults

These work out of the box, nothing to configure:

  • Open Graph / Twitter-card meta tags on every page (title, description, URL, and ogImage or the page’s own image), so links unfurl nicely on social platforms and chat apps.
  • RSS feed for the blog, advertised via a <link rel="alternate"> tag (feed readers auto-discover it) and a “Subscribe via RSS” link on the blog page. Tell your members they can follow new posts in any feed reader, no account needed.

Hugo generates the feed at /blog/index.xml.

The feed is served at /rss.xml.

Section headers & home page

The home page composition (hero, stats, features, team heading, testimonials, closing CTA) lives in:

content/_index.md front matter: [hero], [[stats]], [featuresHead] + [[features]], [team], [testimonialsHead] + [[testimonials]], [getInvolved].

HOME in src/config.ts (same shape), plus SECTIONS for the blog/events/organizers list-page headers.

Each [[testimonials]] entry takes a quote, name, optional role, and optional photo; delete the block to hide the section.

Beyond those, the home page auto-populates the next upcoming event, the latest three posts, and your organizers from content, no config.

Calendar feed (iCal)

Add Calendar to your events section’s outputs and the theme publishes an iCalendar feed at /events/calendar.ics that people subscribe to once and see every future meetup in Google, Apple or Outlook Calendar:

# content/events/_index.md
outputs = ["HTML", "RSS", "Calendar"]

The events list gains a “Subscribe to calendar” link automatically. Timed events (a parseable time) get a start and a 2-hour default end ([params.events] defaultDurationMinutes); date-only events are all-day. Cancelled events carry STATUS:CANCELLED. To subscribe, most apps take the feed URL under “add calendar from URL”. On Astro the feed is always at /events/calendar.ics, no opt-in needed.

Search-engine basics

The theme emits a robots.txt pointing at your sitemap, plus og:locale and (when a page has an image) og:image:alt. Optional knobs:

  • imageAlt on any page’s front matter sets the og:image:alt text (defaults to the page title).
  • [params.seo] noindexTaxonomies = true adds noindex,follow to tag pages (Astro: SITE.seo.noindexTaxonomies).

A fuller SEO reference (structured data, event rich results) lives on the SEO docs page.

Live counts in the home page stats

The stats strip is the theme’s social-proof pattern: a running “events hosted” or “years running” count is the quiet evidence that a group is real and regular. A stat’s value is shown verbatim unless it is one of these computed tokens, which stay true on their own as your history grows:

  • @pastEventCount: the number of past events, rounded down to a “70+” style once there are ten or more.
  • @count:<section>: the live number of entries in a section, for example @count:blog or @count:events.
  • @count:<section>:rounded: the same count, rounded down to “70+” at ten or more (podcast-style exact counts stay exact without :rounded).
[[stats]]
  value = "@count:blog"
  label = "posts"

On Hugo the resolver is partials/stat-value.html, reusable from any template; on Astro it is formatStat in src/lib/stats.ts.

Renaming content sections

If your community’s people are not “organizers” and your blog is not written by “authors”, rename the sections the theme reads, without overriding any template. In hugo.toml:

[params.sections]
  authors = "hosts"   # resolve post-author bylines against content/hosts/
  team    = "hosts"   # show the content/hosts/ people in the homepage team grid

Both default to the theme’s own names (authors, organizers). authors drives the byline links and author bio cards on posts; team drives the homepage team grid and its “All organizers” button. Rename the matching content directory to suit (content/authors/ becomes content/hosts/).

On the Astro side the equivalent lives in config.ts as SECTIONS_MAP ({ authors: 'hosts', team: 'hosts' }); the value names a collection that must exist in your content.config.ts.

Extra head markup (analytics and friends)

The theme core ships no analytics. To add a tracking snippet, verification tag, or any other head-level markup, create layouts/partials/head-extra.html in your site: the theme includes it at the end of <head> and ships it empty, so your version wins without overriding the whole head partial.

Translating the UI

All template strings (section headings, buttons, badges, empty states, dates) are translatable; content is whatever language you write it in.

Set defaultContentLanguage in hugo.toml, at the top level above any [section]: it drives both <html lang> and date formatting. Then create i18n/<lang>.toml in your site root and override any key from the theme’s i18n/en.toml; you only need the keys you want to change.

Set SITE.locale in src/config.ts (drives <html lang> and date formatting), then edit the values in the STRINGS block. Keys match the Hugo theme’s i18n/en.toml one to one.

One site, one language: multilingual sites (several languages with a language switcher) are not supported yet.

Demo bar

demoBar (Hugo) / DEMO_BAR (Astro) renders the floating demo switcher on the theme’s own demo builds. Never set it on a real site and it never appears.