Skip to content
Grav 2.0 is officially stable. Read the announcement →
Premium / Forum Pro
Premium Plugin · v1.0.1

Forum Pro

A real community forum, running inside your Grav site

Forum Pro is a complete, self-hosted discussion platform that lives inside your Grav site. Not an iframe, not a hosted widget, not a monthly per-seat bill. Your members get everything they expect from a modern forum (topics, reactions, private messages, notifications, live updates, real moderation and search) as first-class Grav pages that inherit your theme, share one login with the rest of your site, and store every post in a database you own. Built for Grav 2.0 and Admin Next, it runs the identical schema on SQLite, MySQL/MariaDB or PostgreSQL, so a hobby board and a community of tens of thousands are a config change apart, not a rewrite. And when you outgrow a hosted forum, the one-command Discourse importer brings your members, content and files across intact. We are not asking you to take that on faith: the Grav Community Forum runs Forum Pro, with over 41,000 posts across 9,300 topics from 3,800 members, and it runs great.

Grav 2.0+

Forum Pro is built for Grav 2.0 and requires the free API plugin. It is not compatible with Grav 1.7.

We run our own community on it

The Grav Community Forum is not a demo instance we spun up for this page. It is Forum Pro, it is where the Grav team works, and anyone is welcome to sign up and take part.

41,742 posts
9,332 topics
3,841 members

Nine years of community history, imported out of Discourse in a single command, with every member's password still working. Full-text search, live updates, private messages, badges, ranks and the full spam pipeline are all switched on. And it runs great.

Everything you need. Nothing you don’t.

Over 84 distinct features and integrations, out of the box.

Discussions & Content

The reading and writing experience your members spend all of their time in. Everything is server-rendered first, so the forum works with JavaScript off and search engines index it like the rest of your site.

01
Sections, categories and topics with per-category permissions, custom icons and ordering. The index shows each forum's latest topic and its author.
02
Rich posts through a hardened Markdown pipeline: @mentions with autocomplete, formatted quotes with reply-below-post, and fenced code blocks with server-side syntax highlighting, including automatic language detection when a block doesn't name one.
03
A WYSIWYG editor enhances the posting forms, while plain HTML forms keep working with JavaScript disabled.
04
Image and file attachments by drag-and-drop, by pasting a screenshot (it previews inline as it uploads), or with a plain file picker. Content-addressed dedupe, per-file, per-post and per-member limits, and automatic cleanup of abandoned uploads.
05
Reactions in a hover tray, with configurable types, emoji, and a reputation weight per type for the post author.
06
Polls on new topics, single or multiple choice, with vote changing and live result bars.
07
Tags with chips on listings, a tag browser, per-tag pages, and a tags field when starting a topic. You control who may mint new ones.
08
Accepted answers: the topic author or staff marks the reply that solved it, listings show a checkmark, and the answer's author gets notified.
09
Full revision history on every edit, with a configurable edit window. Authors and staff can browse every prior version of a post and restore one.
10
Bookmarks on topics and posts, reviewable on a private bookmarks page.
11
Unread tracking with a per-member read baseline, a new-post counter on unread topics, and links that jump straight to the first unread reply.
12
Suggested topics under each topic (your unread first, then related) plus a scrollspy timeline rail for scrubbing long threads.

Members & Community

Everything that makes contributors feel recognized and gives your community a sense of identity. Forum Pro runs its own account system, so members never need a Grav account, but your existing Grav admin and staff accounts link in automatically and keep working.

01
Native forum accounts with registration, email verification and password reset. Passwords use PHP's native bcrypt, sessions ride an HttpOnly cookie with a sliding window, and reset links are single-use, hashed at rest and pinned to a trusted host.
02
Public profiles with avatars, recent activity, ranks, badges, reputation and group affiliations, plus a send-message button.
03
Avatars that members upload, change or remove, with a per-member colored letter avatar derived from the username when none is set.
04
Automatic ranks that members climb as they post, plus custom ranks so staff can grant a handpicked honor like Founder with its own icon.
05
Badges awarded automatically for milestones and grantable or revocable by staff, shown as compact hover-labeled icons beside member names.
06
Member groups such as Core Team or Moderators, each with a color and icon, shown as badge bars under names in posts and topic lists.
07
Member titles shown under the name and editable from the admin.
08
A member directory at /forum/members, filterable and searchable, with an always-online window and who's-online counts.
09
An always-visible member toolbar with search and quick links to recent, unread, unanswered and participated topics. The avatar menu reaches profile, notifications, messages, bookmarks, your topics and settings.
10
Announcements: staff post dismissible banners above every forum page, with an optional expiry, color variant, icon and Markdown body.

Moderation & Safety

Tools that scale from a hobby board to a large community without turning moderation into a second job. Most of it happens on the forum itself, so your moderators never need admin access.

01
Scoped moderators: grant a moderator role globally, or limit it to specific sections and categories.
02
A review queue on the forum at /forum/queue with one-click publish, delete, or delete-and-ban, a jump to the post in its topic, and a step-through review mode that clears the whole queue in place.
03
A full moderation queue in the admin with pending, spam and flagged views, bulk actions on up to 100 items at a time, and one-click bans.
04
Per-category premoderation, applied to new members only or to everyone.
05
Member reports, where heavily reported posts auto-hide until a moderator reviews them.
06
Bans that can be global or scoped, temporary or permanent, with appeals and a content disposition: keep, reversibly hide everything, anonymize, or delete it all. Banned members are recognized if they try to re-register.
07
Undo for deletions and bans: a Deleted tab lists everything recently removed with who removed it, when and why, and a one-click Restore. A Bans area lists every active ban with a Lift that also brings back the content the ban had hidden.
08
In-topic moderation to pin, lock, hide, move and delete topics, and to hide, mark spam, restore or delete individual posts, all from a tidy wrench menu.
09
A complete audit log of every staff action, and legal holds that exempt a member, topic or post from all automated cleanup.
10
A daily moderator digest email with queue counts and activity, scheduled to a specific local time and timezone, and silent on quiet days.

Spam Defense

Three independent stages plus account-level gates, so unproven newcomers can't turn your board into a link farm. Everything any stage catches lands in the review queue, never deleted automatically before the retention window.

01
Heuristics (instant, always on): honeypot, submit speed, link counts, blocklists, flood limits and new-member weighting score every post. Configurable thresholds route content into the pending queue or straight into spam.
02
An ML classifier (instant, optional, self-hosted): posts by low-trust members are checked against a quantized DistilRoBERTa model served by a tiny Python and ONNX sidecar. Roughly 200ms, no GPU, and an install script sets it up on any Linux host. The client fails open, so a slow or dead sidecar can never block posting.
03
AI review (hourly, optional, via AI Pro): an LLM reviews new members' recent posts with full topic context and queues confident spam for moderators, logging its reasoning on every decision.
04
Provisional-member restrictions keep brand-new accounts on a lighter footing until they have both posted a configurable number of times and been registered a while. While provisional you can strip links to plain text, hide website, social, signature and title, mark the profile noindex, show a New badge, and block uploads and private messages. Every restriction is its own switch.
05
Invisible captcha: an optional transparent proof-of-work check on register and login that needs no user interaction at all.
06
Maintenance and read-only mode lets members browse but not post, react or sign up during a window, with an optional banner. Staff can keep full access or be locked out too.

Notifications, Email & Private Messages

Keep members in the loop without flooding their inbox, and let them talk to each other privately when a thread isn't the right place.

01
An in-app notification bell with live unread counts for replies, quotes, @mentions, watched activity, moderation decisions and badges.
02
Live toast notifications that slide in the moment a reply, mention or private message arrives, naming the sender, previewing PMs, and linking straight to the post.
03
Burst coalescing, so twelve replies in a watched topic become one bell entry rather than twelve.
04
Watch levels (Watching, Normal, Muted) per topic and per whole forum, with members auto-watching topics they start or reply to.
05
Email that mirrors the bell per member preference: immediate (throttled to one email per topic per window), daily or weekly digests, or never, with per-type toggles and one-click unsubscribe signed into every message.
06
Queued, individually-addressed delivery, never BCC blasts, drained by the background worker with retry and backoff. Sent payloads purge on schedule.
07
Private messages at /forum/messages, one-to-one or in groups, with a toolbar envelope carrying a live unread count and new replies appearing without a refresh.
08
Archiving, blocking and bulk cleanup on messages, including select-all-on-page and select-all-N so you can clear an entire tab and keep just the few you want. Conversations are reportable to moderators, who see only the reported message, with the access audited.

Search & Live Updates

Finding things, and seeing them happen. Search is always constrained by the visitor's category permissions, and live updates are a progressive enhancement that degrades to a perfectly good server-rendered forum.

01
Full-text search at /forum/search over published posts, with filters for keywords, author, a single forum and topics-only.
02
Post-style result cards with author avatar, name and group badges, date, a solution flag on accepted answers, and the matching text highlighted.
03
Two search engines: builtin uses SQLite FTS5, MySQL FULLTEXT or PostgreSQL tsvector with zero setup, or hand indexing to YetiSearch Pro for fuzzy matching and tuned relevance. The index maintains itself and rebuilds with a single CLI command.
04
New replies appear in place, reaction counts tick up, and category listings raise a refresh bar.
05
Presence and typing indicators on topic pages, showing who's viewing and who's typing.
06
Permission-aware channels, so private categories never broadcast to outsiders.
07
Transports, best first: Mercure push over server-sent events with a bundled hub binary, automatic polling fallback, or the plain server-rendered experience with zero live markup.
08
In-page navigation swaps forum pages without a full reload, handling the back button, page titles and focus correctly, and standing down automatically when your theme ships its own htmx.

Comments for Your Whole Site

Turn any page, blog posts especially, into a commentable article whose discussion lives in the forum. This is the classic comments backed by a real board model with none of the iframe or JS-embed friction, because the forum runs in the same Grav install.

01
One account covers comments and the forum alike.
02
The first comment opens the forum thread automatically, seeded with the article excerpt and a link back to the page.
03
Comments are ordinary forum posts, so spam scoring, premoderation, the review queue, search, notifications and reputation all apply, and the thread can be read and continued in the forum.
04
Enabled per template or per page, with a forum_comments(page) Twig call and a forum_comments_count(page) helper for 12 comments links on your listings.

Theming, Accessibility & SEO

The forum is theme-agnostic by design. Every color, radius, font and shadow resolves through a token chain, so a theme that publishes design tokens gets a forum that looks native to the site with no work at all.

01
Design token chain: --forum-* site overrides fall back to --grav-* theme tokens, then to --theme-accent, then to accessible neutral defaults.
02
*Themes that publish `--grav-` tokens** get matching typography, cards, buttons, chips and labels automatically. Themes that don't get contrast-checked neutral styles in both light and dark schemes.
03
One-property branding: a theme that only wants the forum to match its brand color publishes --theme-accent and is done. Labels sitting on a filled accent pick black or white automatically from how light that accent resolves.
04
Dark mode without a token set, recognizing data-theme, data-bs-theme and a dark class on html or body, and falling back to the Canvas system color for popovers and dialogs.
05
Inline Lucide SVG icons that recolor with the surrounding text.
06
Canonical URLs: topic addresses canonicalize by id, and slug or category mismatches 301 to the correct address, so links never rot and search engines see one URL per topic.
07
Per-page browser titles that follow in-page navigation, breadcrumb trails on every page, and noindex on provisional or hidden profiles.
08
Assistive technology support: focus moves to new content so screen readers announce where you landed, and icon-only buttons, the editor, its toolbar and the live-update bar are all labeled and announced.
09
Fully translatable visitor-facing text.

Privacy, Storage & Operations

The engineering that makes all of the above dependable at scale, plus the compliance controls you need when you are the one holding the data.

01
A portable database layer running the identical schema and migrations on SQLite, MySQL/MariaDB and PostgreSQL, selected by config. CI runs the full test suite against all three.
02
Safe migrations behind a database run-lock, auto-applied on SQLite and reviewable or manual elsewhere.
03
A scheduled worker on the Grav scheduler handles email delivery, badge awards, retention purges, session cleanup, view-count folding and scheduled scans, with a job queue that large ban dispositions defer to.
04
Content-addressed blob storage for attachments and avatars, local by default or on any S3-compatible store (Cloudflare R2 recommended) with a local read-through cache and render-time CDN switching. No AWS SDK, signing is built in.
05
Member self-deletion (GDPR erasure) confirmed by an email double opt-in, with a configurable cooling-off window that logging back in cancels.
06
Retention windows that hard-delete soft-deleted and spam content, scrub stored IP addresses, drop closed-report snapshots, read notifications and sent-email payloads. Each is configurable and each is enforced by the worker.
07
Legal holds that override retention for anything under investigation.
08
Efficient view counting and denormalized counters kept honest by a recount command and a read-only integrity checker.
09
A public, permission-filtered read-only API for forum data, and a metrics ledger tracking DAU, MAU, engaged-user trends, posting activity, top posters and queue health.
10
A full CLI: status, migrate, work, recount, reindex, rerender, integrity, files-sync, avatars-sync, ai-scan and import-discourse.

Migrating from Discourse

A genuine replacement, not a fresh start. Point the importer at a standard Discourse admin backup (the .sql.gz kind) and it stream-parses the dump in PHP. No PostgreSQL install required.

01
Members arrive with working passwords. Discourse's pbkdf2 hashes verify natively and upgrade to bcrypt on each member's first login, so nobody has to reset anything.
02
Content converts faithfully: categories (parents with children become sections, restricted ones go staff-only), topics, posts with uploads, quotes, emoji and [details] blocks converted, post revision history, likes as reactions, tags, accepted answers, bookmarks, polls with votes, watched and muted topics, and private messages.
03
People and identity come too: admins and moderators as moderator grants, custom groups with their flair colors, custom award badges and member titles.
04
Files rehost into your own storage. A --download-files pass pulls every referenced image, attachment and avatar off the old CDN into content-addressed storage and rewrites the posts that use them. Resumable and rate-limited.
05
Internal links are rewritten, and every imported row carries its Discourse id, so re-running an interrupted import never duplicates anything.
06
Legacy redirects 301 old Discourse URLs (/t, /p, /c, /u) to their Forum Pro equivalents, which makes the DNS cutover a non-event for search engines and old bookmarks.
07
On a different platform? Talk to us at [email protected] about building an importer for it. The Discourse importer sits on a general import layer, so a new source is mostly a matter of reading a different export format.
A real forum, not an embed

A real forum, not an embed

Topic lists that do the work: pinned and locked states, group badges under author names, solved checkmarks, unread dots with a jump-to-first-unread counter, overlapping avatars of everyone in the conversation, tags, replies, views and activity. It's a Grav page, at whatever route you choose (including your home page), rendered by your theme, indexed by search engines, and served from your own database.

Posts worth reading

Markdown with @mentions, quotes, and server-side syntax highlighting with automatic language detection. Accepted answers get called out at the top of the topic with a jump to the solution. A timeline rail tracks where you are in a long thread and lets you scrub through it. Every edit is kept, so authors and staff can browse the full history of a post and restore any prior version.

Posts worth reading
Spam stops before your members see it

Spam stops before your members see it

Moderators work the review queue right on the forum, no admin login needed. Spam, awaiting approval, reported and deleted each get their own tab with a live count, every card shows its spam score, and one click publishes, deletes, or deletes and bans the author. A step-through mode clears the entire queue in place. Nothing is ever hard-deleted before your retention window, so an accidental removal is always recoverable.

Recognition that keeps people around

Profiles pull together ranks, reputation, group badges and award badges alongside recent activity and a send-message button. Ranks climb automatically as people post, or staff can grant a custom honor like Founder with its own icon. Groups get a color and an icon and show up as badge bars everywhere the member appears.

Recognition that keeps people around
Comments for your whole site

Comments for your whole site

Drop one Twig call into your article template and your blog posts get a comment section backed by a real forum topic. The first comment opens the thread automatically, seeded with the article excerpt and a link back. From there it's an ordinary forum post: moderated, scored for spam, searchable, notified on, and continuable in the forum itself. One account covers both.

Run it from Grav Admin

Admin Next gets a full Forum section: Structure for sections and categories with icons, ordering and permissions, plus Queue, Members, Groups, Tags, Moderators, Bans and a Status panel that reports on your database, schema, background jobs, scheduler and real-time health. Settings live in seven tabs covering everything from posting limits to retention windows.

Run it from Grav Admin
Know how your community is doing

Know how your community is doing

A metrics ledger tracks signups, topics, posts, likes, new contributors, daily active users, engaged users and the DAU/MAU ratio over 7, 30 or 90 days, alongside top posters, most viewed topics and queue health. There's a Forum Activity report in Tools, and an optional widget that puts the same numbers on your site-wide admin dashboard.

Member management that scales

Search and filter thousands of members by group, badge or moderator status, and edit accounts, ranks, badges, passwords and suspensions in place. Grav admin and staff accounts link in automatically and coexist with native forum accounts, so one login covers your whole site without you juggling two user systems.

Member management that scales

Your community, on your infrastructure

No per-seat pricing, no data sitting on someone else's servers, no vendor lock-in. Forum Pro runs on the same host as your Grav site, backs up with it, and moves with it. Members sign in once for the forum, your blog comments, and the rest of your site. And because it is built on a portable database layer rather than Grav's file-based users, a community of tens of thousands is a config change, not a rewrite.

Up and running in about five minutes

  1. Install the plugin and enable it.
  2. Set frontend.enabled: true and visit /forum. The schema migrates itself on first use and the forum is live immediately on SQLite.
  3. Add the Grav scheduler to your crontab. The admin Status tab prints the exact line for your install. The worker delivers email, awards badges, purges expired content and runs the scheduled scans.
  4. Open Admin → Forum to create your sections and categories, then work through the settings tabs.

Want it somewhere other than /forum? Create a page with the Forum page type and the forum takes over that route, including your home page. Real site pages always win over forum routes, so nothing else on your site breaks.

A full CLI for the operational side

BASH
bin/plugin forum-pro status            # connection, schema, jobs, scheduler health
bin/plugin forum-pro migrate           # apply pending migrations (--status to preview)
bin/plugin forum-pro work              # process background jobs once
bin/plugin forum-pro recount           # repair denormalized counters
bin/plugin forum-pro reindex           # rebuild the full-text search index
bin/plugin forum-pro integrity         # read-only consistency report
bin/plugin forum-pro import-discourse  # migrate a Discourse backup
bin/plugin forum-pro files-sync        # push local blobs to S3/R2

Full setup, configuration and migration documentation lives on the Learn site.

A peek at sites running Forum Pro.

Frequently Asked Questions

The most commonly asked questions about the Forum Pro plugin

Can I see it running somewhere?

You can, and it is not a sandbox. The Grav Community Forum is Forum Pro. It is our main working environment, it is where we answer questions and talk about releases, and anyone is welcome to sign up and take part.

It currently holds 41,000+ posts across 9,300+ topics from 3,800+ members, nine years of community history imported out of Discourse, and it runs great. Every screenshot on this page comes from the same software you would be installing.

How well does it handle a big forum?

Our own forum is the answer we point people at: 41,000+ posts, 9,300+ topics, 3,800+ members, with full-text search, live updates, private messages and the spam pipeline all switched on. Listings and topics are server-rendered with denormalized counters and efficient view counting rather than counting rows on every page view, so a busy board stays quick.

If you outgrow SQLite, moving to MySQL/MariaDB or PostgreSQL is a config change. The schema and the migrations are identical across all three engines, and our CI runs the full test suite against each of them on every commit.

Is this a one-time purchase or a subscription?

Forum Pro is a one-time purchase. You get all future updates and new features for free as long as your license stays active. There are no recurring fees, no per-seat pricing, and no cap on how many members your community can have. Compare that to a hosted forum that bills you monthly and gets more expensive the more successful your community becomes.

Does Forum Pro work on Grav 1.7?

No. Forum Pro is built for Grav 2.0 and requires the API plugin for its Admin Next integration. It uses a real database layer, the Grav 2.0 event and permission model, and Admin Next UI extension points that simply don't exist in 1.7. If you are still on 1.7, take a look at the Migration chapter on the Learn site.

Do I need a database server?

No. SQLite works out of the box with zero configuration. The database file is created under user/data/forum-pro/ with deny-all protection files written next to it, and the schema migrates itself on first use. When you outgrow it, point the config at MySQL 8+, MariaDB 10.6+ or PostgreSQL 14+ and the identical schema and migrations run there instead. Our CI runs the full test suite against all three engines on PHP 8.3 and 8.4.

How does it look with my theme?

Forum Pro resolves every color, radius, font and shadow through a token chain: --forum-* site overrides, then --grav-* theme design tokens, then --theme-accent, then accessible neutral fallbacks. If your theme publishes --grav-* tokens, the forum matches it automatically. If it doesn't, you get contrast-checked neutral styling in both light and dark schemes, and a single line of CSS (:root { --theme-accent: #8428df; }) is enough to give the forum your brand color. Anything you want to tune independently is a --forum-* custom property away.

Can I move my existing Discourse forum over?

Yes, and this is one of the things we are proudest of. Take a standard Discourse admin backup (Settings, then Backups, the .sql.gz kind) and run:

BASH
bin/plugin forum-pro import-discourse backup.sql.gz \
    --source-url https://discourse.example.com --download-files

The dump is stream-parsed in PHP, so you don't need a PostgreSQL install anywhere. Members keep working passwords because Discourse's pbkdf2 hashes verify natively and upgrade to bcrypt on first login. Categories, topics, posts, revision history, likes, tags, badges, titles, accepted answers, bookmarks, polls, watched topics and private messages all come across, internal links are rewritten, and --download-files rehosts every image and attachment into your own storage. Every row carries its Discourse id, so re-running an interrupted import never duplicates anything.

This is exactly how the Grav Community Forum got here: nine years and 41,000 posts, moved across in one command.

I'm on a different forum platform. Can you help?

Very likely, yes. Talk to us about building an importer for your platform. The Discourse importer is built on a general import layer (id mapping for idempotency, a Markdown conversion pipeline, password-hash adapters, resumable file rehosting), so adding a new source is mostly a matter of teaching it to read your export format.

Get in touch at [email protected] with what you're running and what an export looks like, and we'll tell you honestly what's involved. If your platform is a common one, other people are asking for it too.

Where do uploaded files live?

By default, on local disk under user/data/forum-pro/, served from a content-addressed path with immutable caching. You can point storage.driver at any S3-compatible store (we recommend Cloudflare R2) and new uploads go to the bucket while staying locally cached. A locally missing blob pulls back through on first request, so serving never depends on the bucket being reachable. Set a public_url and pages reference your CDN instead, applied at render time so flipping it on or off is instant with no database rewrite.

What does the forum need to run properly?

Grav 2.0 (>= 2.0.0-rc.8), PHP 8.3 or newer, and the API plugin. That's it for the core experience. Several optional plugins each unlock more:

  • Email for outbound notification mail
  • Sync and Sync Mercure for live updates and presence
  • AI Pro for the hourly AI spam review
  • YetiSearch Pro for fuzzy search with tuned relevance
  • CodeSH for server-side syntax highlighting in code blocks
  • Form for the invisible captcha on register and login

You'll also want the Grav scheduler in your crontab. The admin Status tab prints the exact line for your install. The background worker delivers email, awards badges, purges expired content and runs the scheduled scans.

Can the forum live at my site root?

Yes. By default the forum mounts at /forum, but create a page with the Forum page type and the forum takes over that page's route, including the home page. Real site pages always win over forum routes, so a home-mounted forum coexists happily with the rest of your content, and /forum keeps working when no mount page exists.

Do members need a Grav account?

No. Forum Pro runs its own account system with registration, email verification and password reset under reserved routes, and members never touch your Grav user files. At the same time, authenticated Grav users are treated as forum members automatically (a linked forum account is created on first visit), so your admins and staff are already there. You can turn that off entirely if you would rather keep Grav logins out of the forum.

How much spam is this actually going to stop?

Quite a lot, and in three independent stages. The heuristic scorer runs on every post instantly: honeypot, submit speed, link counts, blocklists, flood limits and new-member weighting, with thresholds you control for pending versus spam. An optional self-hosted ML classifier adds a second opinion on posts from low-trust members in about 200ms, and it fails open so it can never block posting. An optional hourly AI review through AI Pro then reads new members' posts with full context and queues confident spam with its reasoning logged. On top of that, provisional-member restrictions stop brand-new accounts from posting live links, uploading files or sending private messages until they have earned it.

Can I use Forum Pro on multiple sites?

Per the Grav Premium License, you need a license for each site. Development and staging copies of the same site are covered by the same license. Get in touch if you need bulk pricing.

$100 Buy Now

Forum Pro Changelog

v1.0.1

1 week ago

    • Category pages now use the category's own description as their meta description, so each one reads as itself in search results instead of repeating the site-wide default. Categories left without a description are unchanged
    • The forum index now keeps the meta description written on your forum page. The plugin builds its own page for the index and was carrying the title across but not the metadata, so the description was dropped and search engines fell back to whatever site-wide default the theme or an SEO plugin supplies
    • A topic's meta description no longer replaces the rest of a page's metadata, so robots and OpenGraph tags set on the forum page survive alongside it
    • Meta descriptions built from forum content now decode HTML entities and collapse whitespace before they are used. An imported category description holding a literal ' was reaching the tag as ', and post bodies carried their markdown newlines and indentation straight into the description. Descriptions are also cut on a word boundary rather than mid-word

v1.0.0

3 weeks ago

    • Topics can now be re-tagged after they are created: the topic wrench menu carries an "Edit tags" picker alongside "Edit title", pre-filled with the topic's current tags. Saving an empty field clears them all, so a topic posted without tags (or with the wrong ones) no longer has to be recreated to fix them
    • Moderators can now review and undo deletions and bans, so an accidental removal is no longer permanent. A new "Deleted" tab in the review queue lists everything recently removed — individually deleted posts and whole deleted topics alike (including spam threads taken down with "Delete & ban") — showing who removed each, when, and why, with a one-click Restore; deleted posts and topics also carry a Restore action inline for staff. Deleted content is still purged for good after the retention window (30 days by default), so this is a recovery window, not an archive
    • A new "Bans" area lists every active ban — who is banned, from where, why, by whom, and until when — with a one-click Lift that also brings back any content the ban had hidden. Staff can also lift a ban straight from the member's profile. In the admin the Bans view can show lifted and expired bans too, for a full history
    • Every post now has a browsable edit history: authors and staff can open a History page listing each prior version of the post (who replaced it and when) and restore any of them with one click; restores respect the normal edit rules and are themselves recorded in the history
    • New "Provisional Users" anti-spam controls keep brand-new accounts on a lighter footing until they have both posted a few times and been registered a little while (both thresholds configurable). While an account is provisional you can strip links out of its posts to plain text, hide its website, social links, signature and title and keep its profile out of search engines, show a "New" badge next to its name, and block file uploads and private messages. Every restriction is its own on/off switch in the Spam settings, so you decide exactly how strict to be with people who sign up just to drop links
    • Live toast notifications: a small card now slides in the moment a reply, mention, or private message arrives, naming who it's from (with a message preview for PMs), and clicking it jumps straight to the post or conversation
    • The messages inbox can now be cleaned up in bulk: tick conversations to Archive or Delete them together, with a "select all on this page" toggle and a "select all N conversations" option that clears out an entire tab at once. After selecting everything you can uncheck the few you want to keep and Delete the rest — handy for wiping thousands of old migrated messages while sparing a handful
    • Blog posts and other site pages can now carry a comments section backed by a real forum topic — comments are moderated, searched and browsed in the forum, and one account covers both
    • Themes enable article comments with a single Twig call, plus a counter helper for "12 comments" links on listings
    • The first comment on an article automatically opens its forum thread, seeded with the article excerpt and a link back
    • Every badge, state and action across the forum now uses crisp Lucide icons that recolor with the theme instead of emoji
    • Sections and forums can each have their own icon, and the forum index shows the latest topic with its author for every forum
    • Topic listings show overlapping avatars of the people in each conversation
    • A red "last visit" line in listings and inside topics marks what arrived since you were last here
    • Topics you have not read yet get a blue new-post counter that jumps you straight to the first unread reply
    • Suggested topics appear under every topic — your unread topics first, then related recent ones
    • A timeline rail beside topic posts tracks where you are in the conversation and lets you scrub through it, with an option to turn it off
    • Notification preferences per topic and forum via a Watching / Tracking / Normal / Muted picker that explains each level
    • Moderator and admin topic actions now live in a tidy wrench menu next to the topic title
    • Post actions are now compact icons with a "more" menu for moderation, including a copy-link button
    • Your avatar in the toolbar opens a menu with profile, notifications, messages, bookmarks, your topics and settings
    • Members without an uploaded picture get a letter avatar in a color all their own, picked from their username
    • Member groups (Core Team, Moderators, …) with a color and icon of their choosing, shown as badge bars under member names in posts and beside authors in topic lists
    • A Groups tab in the admin manages groups and their members; group badges also show on member profiles
    • Earned award badges show as compact icons beside group bars, naming themselves on hover so the author column stays tidy
    • The Discourse importer brings over custom groups and their members, including flair colors
    • The Discourse importer now also carries over custom award badges, member titles, and each post's edit history
    • Members can have a title that shows under their name in posts and on their profile, now editable straight from the admin member editor
    • Staff can grant a member a custom rank — a handpicked honor like "Founder" with its own icon (trophy, crown, medal, star…) — that takes the place of the automatic post-count rank on posts, profiles and the member directory
    • A Tags tab in the admin renames, merges, and deletes topic tags without losing what's tagged
    • Sections and categories get their icon pickers in the admin Structure manager
    • Every forum page now has its own browser title — topic, category, search — instead of all saying "Forum", and the title follows in-page navigation
    • Moving between pages now hands focus to the new content so screen readers announce where you landed
    • Icon-only buttons, the editor and its toolbar, and the live-update bar are now properly labeled and announced for assistive technology
    • Muted text and accents meet contrast guidelines on themes without their own design tokens, in both light and dark modes
    • Moderation queue badge counts stay fast as the forum grows thanks to new database indexes
    • Fenced code blocks in posts get server-side syntax highlighting when the Codesh plugin is installed
    • Code blocks that don't name a language get one detected automatically so highlighting still kicks in
    • New rerender command refreshes existing posts through the latest text pipeline
    • Marking a reply as the accepted solution is now a clearly labeled button on each reply instead of an easily missed icon
    • Optional hourly AI spam scanning through the ai-pro plugin reviews new members' posts and queues confident spam for moderator review
    • New posts can be checked instantly by a self-hosted spam-detection model, with a ready-to-run installer for the bundled classifier service
    • Moderators get a one-click "Delete & ban author" action on posts for dealing with spammers
    • Moderators get a Review queue page right on the forum for publishing or deleting caught spam and held posts, with a badge count in their user menu
    • Moderators and admins now see held and spam posts highlighted right inside topics, with a one-click Publish button on each
    • Review queue items link straight to the post in its topic so moderators can judge it in context
    • Jumping into a topic from the queue shows a review bar that counts what's waiting and steps to the next item, so the whole queue can be cleared without going back
    • The plugin settings are now organized into tabs — General, Posting, Members, Moderation, Spam, Storage and System — and every option is editable in the admin
    • A daily digest email tells moderators how many items await review and what happened in the last day, and stays quiet when there is nothing to report
    • Moderator digest emails can now be scheduled for a specific local time and timezone from the plugin settings
    • Admins can set a member's password from the Members editor, which also signs that member out everywhere
    • The admin Members list can filter by group, badge, or moderators only
    • The login page got a friendlier, more polished design, and error banners across the forum are gentler on the eyes
    • The forum can be mounted on any page: create a page with the new Forum page type and the forum lives at its route — including the home page — while /forum keeps working with zero setup
    • Real site pages always win over forum routes, so a home-mounted forum coexists with the rest of the site
    • Moving between forum pages no longer reloads the whole page — navigation, posting and moderation all happen in place, with full page loads still working everywhere
    • The forum brings its own in-page navigation engine and activates it only on themes that don't already provide htmx
    • Live updates, presence and the notification bell reconnect cleanly on every in-page navigation and after returning via the back button
    • Members can attach images and files to their posts — drag and drop onto the editor, paste a screenshot, or use the attach button
    • Private messages now take attachments too, with the same drag-drop, paste and attach-button composer as posts (and the same size, count and provisional-member limits)
    • Dropped or pasted images appear right in the editor the moment they land, previewing inline while they upload
    • Posting forms without JavaScript get a plain file picker that works the same way
    • Attached files dedupe by content, ride the same CDN-backed storage as imported files, and abandoned uploads clean themselves up
    • Per-file size, per-post count and per-member daily limits keep uploads in check, all configurable
    • The forum now follows the full site design system on themes that publish one — typography, cards, buttons, chips and labels all match the site
    • Member avatars now live in the same CDN-backed storage as attachments and serve from the CDN
    • New avatars-sync command moves existing avatars into that storage, and Discourse imports do it automatically
    • Profile pages now show the member's avatar
    • A Forum Activity report in the admin Tools area shows board totals, recent activity, weekly posting trends, top posters and the moderation queues
    • Every page now carries a breadcrumb trail back to the forum — settings, profiles and the sign-in pages were dead ends before
    • Attachment files can live in S3-compatible storage (Cloudflare R2, S3, Backblaze, MinIO) with the web server keeping a local cache, plus a sync command for moving existing files up
    • With a public CDN domain configured, pages link attachments straight to the CDN instead of the web server
    • Topics can have an accepted answer: the topic author or staff marks the reply that solved it, listings show a checkmark, and the answer's author gets notified
    • Topic tags with chips on listings, a tag browser, per-tag topic pages and a tags field when starting a topic
    • Members can bookmark topics and posts and review them on a private bookmarks page
    • New topics can include a poll — single or multiple choice, with vote changing and live results bars
    • The Discourse importer now also brings over accepted answers, bookmarks, polls and their votes
    • New Discourse migration command imports a full backup — members, categories, topics, posts, likes, tags, watched topics and private messages — without needing PostgreSQL installed
    • Members migrated from Discourse keep their existing passwords and can sign in right away
    • An optional second pass downloads every image and attachment from the old forum's CDN, rehosts them locally and updates the posts that reference them
    • Member avatars carry over from the old forum automatically
    • Re-running an interrupted import safely picks up where it left off instead of creating duplicates
    • Members can send private messages, with group conversations of up to five people
    • A message envelope in the toolbar shows unread conversations and updates live, and new replies appear in open conversations without a refresh
    • Conversations can be archived or left for good, and an inbox page keeps active and archived conversations separate
    • Members can block other members from their profile, which stops new conversations and direct replies both ways
    • Private messages can be reported to moderators, who see only the reported message
    • Private message notifications follow the same email preferences as everything else
    • Profile pages gained a send-message button
    • Moderators get moderation tools right on topic pages: pin, lock, hide and delete topics, and hide, mark as spam, restore or delete individual posts
    • In-app notification bell with live unread counts for replies, quotes, mentions, watched activity, moderation decisions and badges
    • Notifications page listing everything with one-click jump to the post and mark-all-read
    • Bursts of activity collapse into a single notification entry instead of stacking up
    • Members can @mention each other with autocomplete, and mentions become profile links in posts
    • Watching now covers whole forums as well as topics, and topics can be muted entirely
    • Members automatically watch topics they start or reply to, controllable in settings
    • Notification emails send right away or as daily/weekly digests, per member preference
    • Every notification email carries a one-click unsubscribe link
    • Email sending is queued and throttled so busy topics never flood an inbox
    • Unread topic links now jump straight to the first unread post
    • Settings page gained a notification preferences section
    • Full-text search across the forum with filters for keywords, author, a specific forum and topics-only
    • YetiSearch Pro can optionally take over search for fuzzy matching and better relevance ranking, with the built-in engine remaining the default
    • New reindex command rebuilds the search index on demand
    • Always-visible member toolbar with a search box and quick links to recent, unread, unanswered and participated topics
    • Members can watch topics from the topic page
    • Members can upload, change and remove a profile avatar
    • Post authors link to their public profiles and show their badges on every post
    • Quoting a post now inserts a properly formatted quote, and replying to a specific post opens the form right below it
    • Replies to a specific post now say so in the thread: the reply carries a link back to the post it answers (with the author's name and a snippet), and that post gains an expandable "N replies" list of everything that answered it. Both jump straight to the other post even when it is pages away. The stream stays flat and unindented, and a reply that already sits directly under its target is left unmarked, so ordinary back-and-forth threads gain nothing to read past
    • Reactions moved into a hover tray, and reaction types and emoji are configurable
    • Post actions sit in a tidy button bar on each post
    • The forum front page shows board statistics and who is online
    • Settings page now explains why Grav-account sign-ins manage credentials elsewhere
    • Polished breadcrumbs, button alignment and spacing across the forum pages
    • Initial Phase 0 foundation: portable database layer for SQLite, MySQL and PostgreSQL
    • Schema migrations with safe re-runs and a database run-lock
    • Background job queue with a scheduler-driven worker
    • Admin status page showing database, schema, jobs and scheduler health
    • Grav admin accounts link automatically to forum accounts
    • Admin structure manager for creating, editing and reordering sections and categories with per-category permissions
    • Public forum pages at /forum with section index, topic listings and post streams, fully server-rendered for search engines
    • Members can create topics, reply with quotes, and edit their own posts within a configurable time window
    • Every edit keeps a revision history and all content renders through a hardened markdown pipeline
    • Moderators can pin, lock, hide, move and delete topics with audit trails
    • Renamed categories redirect from their old addresses automatically
    • A WYSIWYG editor enhances the posting forms while plain forms keep working without JavaScript
    • Read-only forum data is available through a public, permission-filtered API
    • Topic view counts are tracked efficiently in the background
    • All visitor-facing text is translatable
    • Visitors can register forum accounts with email verification, log in, and reset forgotten passwords without needing a Grav account
    • Members get a settings page for changing their display name, signature, password and email address
    • Public member profiles show ranks, badges, reputation and recent posts
    • Posts can be reacted to with configurable reaction types that build the author's reputation
    • Members climb a configurable rank ladder automatically as they post
    • Badges are awarded automatically for milestones and can also be granted or revoked by staff
    • Admin members tab for searching members, editing accounts, suspending access and managing ranks and badges
    • The background worker now also cleans up expired sessions and awards pending badges
    • Moderator roles can be granted globally or limited to specific sections and categories
    • New content moves through clear states so nothing is counted or shown before it should be
    • Categories can require approval for posts from new members or from everyone
    • Members can be banned globally or per area, with optional expiry, appeals and a choice of what happens to their content
    • Banned members are recognized if they try to register again
    • New posts are automatically screened for spam signals and routed to a review queue when suspicious
    • Posting floods are slowed down with sensible rate limits
    • Members can report posts, and heavily reported posts hide themselves until reviewed
    • Admin moderation queue with pending, spam and flagged views, bulk actions and one-click bans
    • Moderators can merge topics and split posts out into new topics, with old links redirecting
    • Legal holds protect specific members, topics or posts from any cleanup
    • Old deleted and spam content is cleaned up automatically on a configurable schedule, along with aged IP data
    • Every staff action is recorded in a moderation audit log
    • New integrity command reports counter drift and broken references without changing anything
    • Topic pages update live: new replies appear in place, edits and removals apply instantly, and reaction counts tick without a reload
    • Category pages offer a one-click refresh when topics arrive or disappear
    • Topic pages show how many people are viewing and who is typing a reply
    • Live updates respect forum permissions, so private areas never broadcast to outsiders
    • Everything keeps working without the optional real-time plugins, falling back to plain page loads
    • The admin status page reports real-time health, including whether the push hub is answering
    • Reporting a post or private message now opens a clear panel with each reason explained and room for extra details
    • Old Discourse links keep working after a migration: topic, post, category and member URLs from the old forum now 301 to their new homes, matched by the original Discourse ID and host-gated so the rest of the site is untouched
    • Edited posts and comments now show a "last edited mm/dd/yy by " line in small print at the bottom right, naming whoever made the edit
    • Avatar uploads open a built-in cropper: pick an image, drag and zoom to frame it in a square, and a tidy 256px version is uploaded (no external library; falls back to a server-side crop when JavaScript is off)
    • A new Members setting, "Grav Users as Members", controls whether a signed-in Grav user counts as a forum member; turn it off to run the forum on its own native accounts only, so Grav logins are never auto-enrolled and no linked forum account is created for them
    • A public Members directory at /forum/members lists everyone in a table with their avatar, rank, post count, website, join date and last-active time — searchable by name, with clickable column headers that sort each way (oldest members first by default) — and a Members link in the toolbar; email addresses are never shown
    • Logged-in members can start a private message straight from the directory or a profile, and a new "Allow private messages" setting (on by default) lets anyone opt out while still letting moderators reach them
    • Profiles can now carry a website and GitHub, X and Mastodon links, shown on the profile, with the website also appearing as a link in the directory
    • Missed your activation email? The login page now has a "Resend activation email" option, and signing in before you've activated tells you so and automatically sends a fresh link — rate-limited so it can't be used to spam an inbox
    • Optional transparent captcha on the registration and login forms: turn on "Captcha on Register & Login" to add a Cap (proof-of-work) check that runs invisibly with no puzzle to solve, deterring bots while staying out of real members' way (needs the Form plugin; off by default)
    • The post editor has a Markdown tab that drops the WYSIWYG surface for the raw markdown source — handy for power users and for markdown the rich editor can't represent, such as a fenced code block shown inside a tilde-fenced block; posting from Markdown mode submits the source verbatim
    • Maintenance mode, toggleable in the admin, puts the forum in read-only: members can browse but can't post, reply, react or sign up, while staff keep full access to work during the window. A banner explains the state and you can set your own message; an "Apply to staff too" option locks staff and admins out as well for a full freeze
    • Members can delete their own account from Settings (GDPR right-to-erasure), confirmed by an email double opt-in so nobody else can trigger it. After a configurable cooling-off window (30 days by default) the account is erased; logging back in before then cancels it, and a banner reminds them while it's pending
    • Deleting an account scrubs the member's personal data but keeps their posts and topics, reattributed to a generic "Deleted User" so old conversations stay intact. Grav-linked members keep their site login — only their forum membership and data are removed
    • Staff can delete a member from the admin Members tab, with the same "keep the posts, erase the person" behaviour, taking effect immediately
    • Reply and new-topic drafts now autosave to your browser as you type and reappear automatically when you come back, so you can hop around the forum without losing post progress — replies are kept per thread, the new-topic form reopens itself with your draft, and a draft clears once its post is submitted (but is kept if the submit comes back with an error)
    • A "Mark all read" button clears unread topics in one click at every level: a single category, a whole section, or the entire forum from the index
    • The forum index now shows a blue unread-topic count on each category and section, and that count repeats beside the category title once you are inside, so you can see at a glance where new activity is
    • The first post in a topic gets the same copy-link button the replies already have, and every copy-link button now pops a brief "Link copied!" confirmation so you know it worked
    • Composing a private message now suggests recipients as you type: enter the first few characters of a name in the To field and a dropdown of matching members appears, so you can pick the right person instead of having to remember and type their exact username. It works for each name in a comma-separated list and reuses the same member lookup as the @mention typeahead
    • Moderators and admins can now hide deleted posts from the thread view: a new "Hide deleted posts in threads" toggle on the forum Settings page keeps removed replies out of your inline reading while you browse a topic, since they remain reachable for review and restore in the moderator queue's Deleted tab. It's a per-moderator preference (off by default, so nothing changes unless you opt in) and never hides a topic's opening post
    • Each moderator now controls their own queue email on the forum Settings page: choose to be emailed immediately when new items need moderation, get a once-a-day digest, or turn it off entirely, and optionally skip the daily email on days with nothing to moderate. Defaults to a daily digest that stays quiet when the queue is empty — auto-caught spam alone no longer counts as something to moderate, so the report only lands when there is real work waiting. The immediate option alerts you as soon as new posts, spam, or reports arrive (coalesced so a spam wave is one email, not dozens). The admin's "Moderator Queue Emails" setting remains the site-wide master switch
    • Moderators can now rename a topic from the wrench menu: a new "Edit title" action opens the current title for editing and saves the new one in place. The change follows through everywhere the title appears (the heading, the breadcrumb, listings and search), while the topic's link stays the same, since forum URLs carry the topic id
    • Categories now have a "New topic" button in the header beside the category title, so you can start a topic without scrolling past the whole list to reach the composer at the bottom. Clicking it lifts the composer up to the top, already open with the title field focused
    • Search results can now be sorted by "Newest first" or "Oldest first" as well as relevance. Relevance is still the default, but a common term whose highest-scoring hits are years old no longer buries recent posts, so you can search "flex" and jump straight to the latest discussion; the choice sticks through paging and works on both the built-in and yetisearch-pro engines
    • The forum index totals and who's-online list are served from a short-lived cache instead of recounting the whole board on every visit, and who's-online lookups got a supporting index — the two biggest costs on the busiest page at community scale
    • The schema check that ran on every single forum request (probing and re-reading every migration file) now costs one cached lookup once the database is known current
    • The JavaScript that ships to readers dropped from ~570 KB to ~29 KB: the rich-text editor loads as a separate piece only on pages with a composer, and htmx only on themes that don't already provide it
    • In-page (htmx) navigation now transfers just the forum content instead of the full theme page, and the live layer's per-event refreshes do the same — less server work and less bandwidth on every click
    • The forum stylesheet ships minified (a third smaller), member-directory avatars lazy-load, and the member directory computes its message-button visibility in one query instead of one per member
    • Reading a topic only writes your read-position when there is actually something new to record, and paging back through old posts no longer clears a topic's unread status by mistake
    • Live updates poll more gently: a quiet topic backs off its polling cadence automatically, hidden tabs slow right down, and the notification bell keeps one connection alive across in-page navigation instead of reconnecting on every click
    • The Discourse importer wraps its member and topic passes in transactions like the rest (a large import is now minutes, not hours, on SQLite) and the recount/integrity commands batch their work the same way
    • Icon rendering moved out of the templates into PHP, cutting hundreds of thousands of wasted allocations per topic view
    • Banning a member whose content runs past 500 posts now applies the content disposition through the background worker, so banning a prolific spammer can't time out the request; smaller cases still settle instantly
    • The "Tracking" notification level was removed from the Watching/Normal/Muted picker — it never behaved differently from Normal (per-member read baselines already give every topic unread counters)
    • Forum posts now render through Grav's own Markdown parser, so the site's Markdown settings and extensions (tables and GFM marks, for example) apply to forum content; the plugin no longer bundles its own copy of Parsedown now that Grav core provides it
    • The editor toolbar now uses consistent Lucide icons in place of the old emoji-and-text mix; the inline-code button (which rendered blank before) and a clearly labeled fenced code-block button are both back
    • The new-topic tag field is now a proper tag picker: type to filter the existing tags in a dropdown that keeps working as you go, click or press Enter to add each one as a removable chip, and Backspace to drop the last (the old field popped a one-shot browser dropdown and left everything as plain text)
    • Activity notification emails now lead with who replied and quote the first ~500 characters of their post, so you can tell what happened without opening the topic; images are stripped from the excerpt and noted as a "📎 N images" count
    • Granting a moderator in the admin is now a type-to-find member search — start typing a name, username or email and pick from the matching list — instead of a plain text box you had to paste an exact username into
    • Anti-spam now catches "contact-info" spam: a brand-new account dropping a bare phone or WhatsApp number (with no link at all, so every link-based check missed it) is held for moderation instead of publishing, and a new account repeating the same number across a run of near-identical posts is routed straight to the spam queue from the second post on
    • The moderator "Hide deleted posts in threads" setting is now "Hide moderated posts and topics from my view": with it on, hidden, spam and pending topics also drop out of your category listings (not just deleted replies inside a thread), so your own view stays clean and you review everything from the queue
    • The forum reads far better on a phone: the search box and its row of quick-links now collapse to a single "Search" button that expands on tap, so they no longer take up the top of every screen; the community-guidelines notice shows only on the forum index instead of repeating on every category and topic; and the page header and topic rows are tightened so more fits above the fold. Opening a topic now shows the first post straight away instead of a screen filled by the header and search box, and category lists show several topics at a glance again
    • The review queue's filter tabs wrap instead of running off the side of a phone screen — four pills needed 542px in a 390px viewport, which put the whole page into sideways scroll
    • The composer's own "New topic" toggle stayed readable once opened. CSS bases that treat a <details> as an accordion mute its summary while expanded, which greyed the label to 3.1:1 on themes built on one
    • The collapsed search control on phones follows the same font and casing as the toolbar links beside it
    • Grouped settings ("Email me about", "Moderator queue email") no longer sit in a grey box on themes with no elevated surface of their own — the fieldset now leans on its border and legend to do the grouping, instead of a fill that floated against a transparent card
    • Panel sub-headings such as the profile's "Badges" and "Recent posts" are pinned to a size that stays clearly below the page title. Left to the theme they could come out nearly as large as the title itself (Quark 2 renders them at 34px against a 38px heading, in its heaviest display face), reading as though the page had two titles
    • A theme's own heading face now reaches the forum's headings. --forum-font-display was only ever read from a theme's design-token set, so a theme without one had its forum headings fall back to the body font while the unclassed headings beneath them kept the theme's display face — leaving a page title lighter than its own subheadings
    • Breadcrumb trails follow the page's own font and sentence case, alongside the toolbar links
    • On themes built on PicoCSS (Grav's default Quark 2 among them) the toolbar's search field was squashed down to just its magnifier while the Search button stretched across the whole row. The same class of base rule was repainting disclosure buttons and, on every forum menu, pushing the rest of the page down about 16px each time one was opened. Those bases style bare elements (button[type="submit"], input:not(…), details[open] > summary) at a weight that outranks a plain class, so the forum's own controls now state their case at matching weight
    • Forum headings no longer collect the host theme's decorative heading rule on top of their own. Quark 2 draws a short bar above every <h2>, which stacked against the tick and divider a section heading already draws and left a stray dash above each settings panel. Headings inside post content are left alone, so a member's own markdown still reads like the rest of the site's writing
    • Borders and panel fills are lighter on themes that publish no design tokens — they were reading far heavier than the surrounding page in both light and dark
    • Small navigation labels follow the page's own font and sentence case instead of being forced to mono uppercase, which read as shouting on themes with a quieter voice. Themes that want the mono treatment opt in with --forum-nav-font / --forum-nav-transform / --forum-nav-spacing / --forum-nav-size
    • The forum now looks right on themes that ship no design tokens of their own — Grav's default Quark 2, for instance — in both light and dark mode. Dropdowns, popovers and dialogs take their solid background from the browser's color-scheme, which plenty of themes never update when they switch to dark mode, so a menu could open white on a dark page. The forum now recognises the usual dark-mode signals (data-theme, data-bs-theme, a dark class) and pins its own surfaces to the mode the page is actually showing
    • Filled controls on a theme with no accent of its own — primary buttons, letter avatars, the notification counter, the jump-to-latest pill — used the same blue as body links, which in dark mode was pale enough that their white labels fell to 2.3:1. They now use a deeper accent that keeps white readable in both modes
    • Small count badges on the secondary accent (notification counts in the user menu, review-queue tab counts, copy-link toasts) now take a black or white label depending on how light that accent really is, instead of always white — on the default blue that pairing was 2.8:1
    • "Delete & ban author" and the other disclosure buttons in the review queue keep their white label on themes whose CSS base styles details summary at a higher weight than a class (PicoCSS, and so Quark 2), where the label had been repainted to the page text colour and sat at 2.9:1 on the red fill
    • The moderator daily digest no longer arrives when there is nothing to actually moderate. A report on a post that was already hidden by a moderator or a ban, marked spam, or deleted (or whose whole thread was deleted, as when a spammer is banned) no longer counts as open work, so stale reports on removed spam stop forcing a daily "nothing to do" email. Auto-caught spam sitting in the spam bin likewise no longer triggers the digest on its own. The same rule cleans up the review-queue count and the on-forum "Reported" tab, which now list only reports still needing a decision (a post taken down by its own flags still shows for review)
    • The forum's own review queue now has a "Reported" tab, so member reports on posts can be reviewed and cleared from the forum itself instead of only in the admin. Each report shows the reason, who filed it, and the reported content, with one-click Publish, Delete, "Delete & ban", and Dismiss actions; acting on a reported post clears its open reports automatically. Private-message reports appear too, showing only the reported message and its sender. Previously the queue counted open reports and the moderator digest emailed about them, but the on-forum queue had no tab to see or act on them
    • The topic wrench menu now has a "Delete & ban author" action, so a spam thread with no replies can be removed and its author banned in one click — previously that shortcut lived only on the per-post moderator menu, which never appears on a topic's opening post, leaving spam-only threads with no ban path
    • Security: SVG and text attachments stored on S3/R2 now carry a download disposition, so a scripted SVG served from the CDN downloads instead of executing in the browser (run files-sync --force once to refresh existing objects)
    • Security: when no trusted site host is configured, password-reset and verification links now pin the first host the install ever used instead of trusting each request's Host header — a spoofed Host can no longer redirect a reset link
    • Security: single-use auth tokens (reset, verify, delete) are consumed atomically, so two simultaneous submissions of the same link can't both succeed
    • Grav super-admins without a forum moderator role are no longer shown as provisional "New" members on their public profile and posts — their staff status now syncs onto the forum account automatically
    • Members imported from Discourse who had not logged in since the migration could not change their email address (their legacy password never verified); they can now
    • Security: password-reset and email-verification links are now built from a configured trusted host (security.site_url, falling back to system.custom_base_url) instead of the request Host header, closing a host-header injection / reset-poisoning vector
    • Security: avatar uploads are limited to PNG/JPEG/WebP under 1 MB and are always re-encoded to a 256px PNG, stripping metadata and rejecting anything GD can't decode (GIF and the raw-bytes fallback are gone)
    • Security: registration no longer reveals whether an email is already in use; a duplicate signup gets the same neutral response and the real owner is notified out-of-band instead
    • Security: a self-service password change now revokes the member's other sessions, locking out any stolen session while keeping the current one
    • Security: password-reset requests are throttled per target email as well as per IP, blocking distributed inbox mail-bombing of one member
    • Security: the minimum password length is floored at 8 regardless of configuration
    • Jumping to a specific post now lands it below fixed page headers instead of underneath them
    • The bookmarks, notifications, messages, settings, review queue and topic listing pages now show a crisp icon matching their menu entry beside the page title, replacing leftover emoji
    • Search results are now post-style cards with the author's avatar, name and group badges, the post date, a solution flag on accepted answers, and the matching text highlighted
    • In-page navigation and background clicks no longer draw a focus outline around the whole page
    • The search, topic and review queue pages now show the member toolbar like every other forum page
    • Members imported from Discourse who only ever signed in with Google or GitHub are now pointed at the password reset instead of a dead-end "invalid password" error
    • Browsers pick up changed forum styles and scripts right away instead of serving stale cached copies
    • The composer's link panel no longer shows open before the link button is clicked
    • Report dropdown and other popovers are now readable in dark mode
    • Buttons follow the page colors in dark mode instead of staying light-themed
    • Theme-added bottom margins no longer misalign forum links, buttons and inline forms
    • The timeline rail, copy buttons and editor no longer go dead after clicking between pages on themes that boost links
    • Solved posts keep their green outline on all sides when hovered, with a soft green glow instead of a vanishing border
    • Topic listings now show members' real avatars in the participant stacks instead of letter placeholders
    • Members signed in through a Grav account now get a Log out entry in the avatar menu
    • Typing right after quoting a reply now continues below the quote instead of inside it
    • Notification emails now send on standard SMTP servers instead of failing for a missing sender address
    • Grav super users are recognized as forum admins again: admin and moderator status is read from the Grav 2.0 api.super permission instead of the legacy admin.super, which no longer exists on a Grav 2.0-only install
    • The Announcements management page (and its new/edit forms) no longer 404 for admins: rendering an announcement's markdown was resolving Grav's active page before the forum had registered its own page, caching a not-found result; the forum now registers the page first, then renders
    • Reading a private message no longer 404s: opening /messages/{id} rendered the conversation's markdown before the forum had registered its own page (the same cause as the Announcements 404), caching a not-found result; the message thread now registers its page first, then renders
    • Viewing a member's profile no longer 404s: rendering the member's signature markdown was resolving Grav's active page before the forum had registered its own page (the same cause as the Announcements and message 404s), caching a not-found result; the profile now registers its page first, then renders. This only affected members who had set a signature
    • Private message email notifications now include an excerpt of the message — leading with who wrote it and quoting the first part, just like reply notifications — instead of only saying "X sent you a private message", and their button reads "Read message" and links to the conversation. PM lines in the daily digest now read "X sent you a private message" instead of a bare "pm"
    • Editing your own posts now works from the forum itself: the inline edit action and composer were missing from the public topic page, so the time-window edit (and staff edits) could previously only be reached through the API
    • Acting on a post — edit, react, bookmark, mark or unmark a solution, report, or moderate — no longer jumps to the top of the thread; the page now stays on the post you acted on
    • @mention autocomplete matches on display name as well as username (the username shows in grey under the display name), and the suggestion dropdown reliably closes after you pick someone instead of leaving a floating overlay behind
    • Links inside a post now use the theme accent color like @mentions do, so they read clearly as clickable
    • The composer toolbar's Link button works again: no link extension was loaded, so Apply and Remove threw a console error and did nothing. Links now apply to the selected text, or insert the URL itself when nothing is selected, and show as accent-coloured links inside the editor
    • Hard line breaks (Shift+Enter) no longer show up as a literal "\": the editor was emitting a backslash hard break that Grav's Markdown renders verbatim, so it now uses a two-space hard break that becomes a real line break
    • Moderator digest no longer suppresses itself for the whole day when the first run after midnight finds an empty queue. The "already sent today" marker is now set only when a digest is actually sent, so moderation that arrives later in the day still triggers the digest
    • Review queue: deleting a spam or pending item that is itself a new topic (its opening post) now removes the whole topic instead of failing with "The opening post cannot be deleted — delete the topic instead". Both Delete and Delete & ban author are fixed, and posts left in a deleted topic no longer linger in the queue or its counts
    • Topic listings now read cleanly at every width: the status markers (pinned, locked, solved, unread) ride alongside the title instead of being stranded on their own line when a title wraps, and the unread dot leads each row so the markers line up down the list
    • Responsive layout from phone to tablet is much improved across the forum — topic listings, the member directory, search, settings, profiles and post headers were cramped, squished or overflowing on small screens and now reflow cleanly. On phones, topic rows stack into full-width titles with their tags on a line of their own and a compact "replies · activity" line, and wide tables collapse into readable stacked rows
    • The group and badge filter dropdowns in admin member management were rendering as white browser-default controls; they now use the dark admin theme like the rest of the UI
    • The Status panel's "Mercure hub" check no longer reports a healthy hub as Unreachable: it was probing /healthz on the public site URL, where the route doesn't exist (the reverse proxy only forwards the subscribe path), so it always 404'd. It now probes the hub's internal (loopback) URL, where /healthz actually lives
    • The Status panel's "Scheduler" check no longer shows Not detected while the scheduler is running every minute: it was looking for a status string Grav's scheduler never returns, and now keys detection on the scheduler's last-run time instead
    • The forum admin's tabs (Structure, Queue, Members, Groups, Tags, Moderators, Status) now put their name in the URL, so reloading or sharing the link lands back on the same tab instead of resetting to the Dashboard
    • Opening a topic at a specific post now actually scrolls to it. On themes that animate scrolling, the browser's jump to a #post anchor was being swallowed, so permalinks, notifications and "jump to first unread" all landed at the top of the topic instead. The forum now scrolls to the target reliably: tapping a notification opens the exact post that triggered it (on the correct page, even deep in a long topic) and briefly highlights it, and opening a topic with new activity lands on the "last visit" divider with the new replies just below
    • Adding an attachment while editing a post works now: the edit form was missing the file picker and drag-and-drop that new topics and replies already had, so a screenshot forgotten on the original post could not be added afterward. The edit composer now carries the full upload toolbar, and edited posts keep their new files
    • Search results no longer run off the right edge on a phone: long file paths and URLs in a result's excerpt now wrap instead of pushing the card past the screen