Skip to content
● Grav 2.2 is out: 2x faster cold starts and 96% less memory on big sites. Read the announcement →
Premium / Forum Pro
Premium Plugin · v1.0.11

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 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+
Live Demo Documentation

Forum Pro is built for Grav 2 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 and requires the API plugin for its Admin Next integration. It uses a real database layer, the Grav 2 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 (>= 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.

Forum Pro Changelog

v1.0.11

1 day ago

    • database.persistent (off by default): keeps the MySQL/MariaDB or PostgreSQL connection open in the PHP-FPM worker between requests instead of opening a new one every time. No effect on SQLite or on a named connection; see the setting's help text for the max_connections budget and the PHP-FPM restart it needs after a database settings change. grav-db-kit 1.0.3
    • Topic pages failed on MySQL and MariaDB. The query that finds reply links named a column before, a reserved word on both, so every topic view there hit a syntax error. SQLite and PostgreSQL were unaffected
    • Member directory search and the @mention lookup failed on MySQL and MariaDB. Both escaped LIKE wildcards with ESCAPE '\', which MySQL reads as an unterminated string because a backslash is also a string escape there. They use ! as the escape character now, as the XenForo importer already did
    • The attachment link backfill links a post's files in the order the post mentions them on every engine, instead of the order the database happened to return them (MariaDB returned them sorted by hash)

v1.0.10

1 week ago

    • The database layer, migrator, job queue, KV store, rate limiter and unsubscribe signer now come from grav-db-kit, the shared database package KahunaCart and Helpdesk Pro already use, bundled under Forum Pro's own namespace so it never clashes with another plugin's copy. Existing forums keep their tables and data. The first request after updating runs one migration (0027), which adds any unflushed topic view counts to their topics, rebuilds forum_rate_limits in the kit's layout and adds the kit's columns to forum_jobs. Rate-limit counters start fresh, and unsubscribe links already sent keep working

v1.0.9

1 week ago

    • Forum admin and moderator rights granted through a Grav group now count on the forum itself. The forum read admin.forum-pro.admin and admin.forum-pro.moderate only from the account's own access settings, while the API checks groups too, so a moderator made one through a group could use the moderation API but got no staff tools on the forum pages and was treated as a regular member. Both now resolve permissions the same way, and the member stats count group-granted admins

v1.0.8

1 week ago

    • Attachments now follow the access rules of the posts that use them. A file in a members-only, group or staff forum answers 404 to anyone who can't read that post, and the same goes for files on posts that are pending, deleted or hidden, message attachments for anyone outside the conversation, and draft uploads for anyone but the uploader. Before, anyone with the link could download it, including guests on a private forum. Files a guest could see still cache forever and go through the CDN; restricted ones are sent with a private cache and always go through the forum, even with storage.s3.public_url set. Avatars stay public, and a file that isn't tied to any post or message follows the forum as a whole (public on an open forum, members-only on a private one)
    • New bin/plugin forum-pro link-files command. Files brought in by the Discourse importer were never tied to the posts and messages that use them, so the new access check couldn't apply to them. The command scans posts and private messages for file references and adds the missing links. Run it once on a forum imported before this release (--dry-run shows the counts first); it's safe to repeat. The importer's --download-files pass now does this on its own

v1.0.7

2 weeks ago

    • Sign-up blocklists. auth.blocked_email_domains refuses registrations and email changes at listed domains (example.com, or *.example.com for every subdomain too), and auth.blocked_username_patterns refuses usernames matching simple patterns (1win*, *melbet*). A refused sign-up gets a plain "Registration is not available for these details" that doesn't say which rule tripped, creates no account and sends no email. Each refusal is logged at info level with the rule, domain and IP, never the full address
    • Sign-ups at a domain with no MX and no A record are refused with "That email address can't receive mail" instead of sending a verification email that can only bounce (auth.check_email_domain, on by default). A failed DNS lookup never blocks anyone, and answers are cached per domain for a day
    • Accounts that never verified their email and never did anything (no posts, topics, messages, uploads, reactions or votes) are deleted once they're a week old, by a daily scheduler job (auth.prune_unverified_days, 0 turns it off). Imported and Grav-linked accounts are never touched. The new bin/plugin forum-pro prune-unverified command runs it by hand with --days, --domain and --dry-run
    • The invisible captcha now works when the login or register page is reached by clicking through the forum. In-forum navigation swaps in the page without its script tags, so the Cap check never ran and every login or sign-up from those pages failed with "captcha failed" until the page was reloaded

v1.0.6

3 weeks ago

    • Deleting a category from the Structure tab always failed with "No route matches 'DELETE /forum-pro/categorys/…'": the admin built the URL by adding an "s" to the word category. Sections were unaffected

v1.0.5

3 weeks ago

    • Group-based access. A category's Read, Reply and New topics settings take a new groups audience alongside public, members and staff: pick one or more member groups in the category editor and only their members (plus staff) get in. Subcategories inherit it like any other setting, so a paid "Pro" group can open a whole branch of the forum that free accounts and guests never see
    • Sign-in panel for members-only forums. When every forum is closed to a guest, the index shows a panel with Log in and Create account buttons instead of "No forums have been set up yet", and a link into a members-only category or topic (a notification email opened while logged out, a shared link) shows the same panel instead of a 404. Logging in from it returns to the page that was asked for. Signed-in members whose groups open nothing get their own message. Both messages take Markdown under the new gate settings on the Members tab. Staff-only and hidden forums stay a 404
    • On an index where some forums are public, guests get a one-line hint saying how many more forums open up after logging in (gate.teaser)
    • Private forum (gate.private). Guests see only the sign-in panel, on every forum page: no categories, topics, member directory, profiles, who's online, stats, search, tags or announcements. Logging in, registering, password resets and the unsubscribe links in forum emails keep working, the forum's public API routes need a login, and article comments on site pages are hidden from guests
    • Forum groups can follow a Grav user group. Name one from user/config/groups.yaml on the group and its membership comes from the Grav accounts: a member is added or removed on their next visit, and straight away when their account is saved in Admin2 or the admin (with flex accounts, on any save). Groups without a link keep their hand-managed members. Paired with a groups audience, a purchase that puts someone in a Grav "premium" group opens the paid forums, and a lapsed membership closes them
    • A new bin/plugin forum-pro sync-groups command brings every Grav-linked member's groups up to date at once, for use right after linking a group
    • The structure tab shows who can read each category that isn't public, with group names for a groups audience
    • Deleting a group that controls access to a category is refused with the names of the categories involved, instead of quietly locking its members out
    • Reply and New topics permissions now also require read access. A member could post a new topic into a category they couldn't read (a staff-only or members-only one left at the default "members" New topics setting) by sending the form directly
    • The login return path now rejects backslashes and paths that don't start with /, which a root-mounted forum let through
    • Article comments on site pages ignored the comments category's read access, so a members-only comments category still showed its comments to guests. Comments and comment counts now follow the category's audience

v1.0.4

3 weeks ago

    • XenForo migration. A new bin/plugin forum-pro import-xenforo command imports a XenForo 2.2 MySQL dump directly, no MySQL server needed: members with working passwords (XenForo 2 bcrypt hashes verify as-is, XenForo 1 sha256 hashes upgrade to bcrypt on first login), staff as moderator grants, custom groups, bans, the node tree as sections and categories, threads, posts converted from BBCode to Markdown, edit history, reactions, tags and thread prefixes, watches, bookmarks, polls, Q&A solutions, conversations and trophies. Attachments and avatars adopt straight from a copy of XenForo's internal_data/attachments and data/avatars folders into blob storage. Every row keeps its XenForo id, so an interrupted import resumes without duplicating anything
    • Legacy redirects now support more than one source platform. A frontend.legacy_redirects.xenforo block 301s old XenForo URLs (/threads/slug.123/, /posts/456/, /forums/slug.7/, /members/name.45/, /tags/x/, plus the index.php?threads/... form and subfolder installs via base_path) to their Forum Pro equivalents. Unlike the Discourse source it does not catch unmapped paths unless catch_all: true, because a XenForo site usually keeps its hostname
    • A new onForumProRenderBody Grav event lets other plugins take part in rendering. It fires for every body the forum renders — posts, private messages, signatures, announcements, email excerpts — after the Markdown parse and before the sanitizer, with the source, the parsed HTML to replace, and a context saying what is being rendered and which post, topic, category or member it belongs to. The sanitizer still runs on what a listener returns. See "Extending post rendering" in the README
    • Legacy redirect lookups on sections, categories, topics and posts are now indexed on external_id
    • XenForo [SPOILER] blocks import as a headed quote, since the renderer never emits raw HTML
    • XenForo [MEDIA] embeds from Twitter/X, Instagram, TikTok, Imgur, Reddit, Facebook, Dailymotion, SoundCloud, Giphy, Flickr, Pinterest and Spotify now import as links to the original post, rebuilt from the id XenForo stores. Only YouTube and Vimeo did before; everything else was dropped, and a post that was nothing but a tweet came through as raw BBCode
    • XenForo reactions now map onto whatever reaction types the forum configures. A reaction whose title names a configured type keeps its identity, with Love read as heart and Haha as laugh, so a forum that adds wow, sad and angry to reactions.types gets XenForo's six back one for one; a reaction the forum has no type for falls back to like. Previously Wow, Sad and Angry all became confused
    • The XenForo import spool is now keyed on what it keeps, not just the dump, so widening the importer no longer replays an older, narrower spool from a previous run
    • A bare [word] with no closing tag now survives the XenForo import as text. Changelog-style posts label their entries [GUI], [Bug], [Wallet], and the unknown-tag sweep used to eat them; XenForo itself shows them verbatim
    • A category whose slug matched one of the forum's own routes (announcements, members, tag, queue, history and others) was unreachable: the route won and the topic page bounced to the index. The reserved-slug list now covers every frontend route, both importers apply it, and such a category gets the -forum suffix the admin already used for login, search and friends
    • A XenForo dump whose CREATE TABLE carried a quote inside a column comment — stock xf_user does, on the gravatar column — lost the name of every column after it, so user_state, is_moderator and is_admin imported as null and the forum arrived with no staff. The dump reader now re-escapes what it reads back, and refuses a row it cannot name rather than spooling it
    • Long XenForo quotes (a 13 KB proposal quoted in full, a couple of hundred tags inside) exhausted the PCRE JIT stack, so the whole post kept its raw BBCode. The quote, spoiler, list and inline-tag patterns now match a bracket at a time instead of a byte at a time
    • Bold or italic inside a XenForo [URL] label came through as literal \[B\] text; inline tags are now converted before links are built
    • Slugs built from titles in scripts that use combining marks (Devanagari, Thai, Arabic diacritics) dropped the marks and split the word: "India इंडिया" became india-इ-ड-य. Slugs keep them now, for imported and admin-created categories, sections, topics and tags alike
    • A forum mounted at the site root (frontend.route: '', the forum page as Grav's home) redirected / to itself forever: Grav reports the home request under its alias route, which is also the mount page's slug the plugin canonicalizes to /. The request line now decides what was asked for
    • Legacy redirects no longer 301 a request to the page it is already on. A XenForo forum that keeps its hostname and mounts at the root maps the old index onto the new one, which was a redirect loop
    • A forum mounted at the site root had no way back to its index: the "Forum" breadcrumb was plain text and the post-action redirects pointed at an empty route, because the base route is empty there. Index links and redirects now resolve to /. The "Forum" eyebrow on a category page and the category eyebrow on a topic page are links now, on every mount
    • bin/plugin forum-pro rerender unlinked every @mention on the site: posts get their mention links after the Markdown pass, and the command re-rendered without that step. It also built its own bare renderer, so nothing it did went through onForumProRenderBody. It now uses the forum's renderer and relinks mentions, which makes it the way to apply a new render listener to existing posts
    • A category or topic whose slug is not ASCII — 한국어-korean, español-spanish — answered 404 on the frontend: Grav hands the plugin the percent-encoded route, and the slug lookup compared it against the stored, decoded slug. The route is decoded once on the way in

v1.0.3

1 month ago

    • Category, section and group icons can now be any icon in the Lucide set — all 2,049 of them — instead of the 78 the plugin happened to have inlined. Names like store, shopping-cart and credit-card that previously fell through to a generic chat bubble now render the icon you asked for. An emoji still works in the icon field too
    • The Icon field in the admin now autocompletes from the full icon list and tells you when a name isn't an icon, as you type. Previously an unrecognised name saved without complaint and only showed up as a chat bubble on the forum, which read as a bug rather than a typo
    • Icons have been refreshed to current Lucide artwork. Most are visually identical; a few are slightly redrawn where Lucide has refined them
    • Eight icon aliases that were standing in front of real Lucide icons of the same name — pen, edit, medal, delete, unlock, help-circle, check-circle and bar-chart — have been dropped, so those names now give you the genuine Lucide icon. No forum used any of them. The remaining aliases (chat, fire, gear, poll and friends) are all names Lucide doesn't define, so they still resolve as before

v1.0.2

1 month ago

    • Inline code in posts and comments now renders on a tinted background with a soft border, so a bin/grav clearcache mid-sentence reads as code instead of blending into the text around it. Code backgrounds are tinted from the theme's accent colour, and can be retargeted with the --forum-code-bg, --forum-code-block-bg and --forum-code-border variables
    • Article comments now style code the same way posts do. Both bodies run through the same Markdown pipeline but only the post body was styled, so a fenced block in a comment came out unformatted
    • On phones the forum's quick links (New Posts, Unanswered, Tags, Members, Unread, My Topics, Bookmarks) are now visible as a scrollable row instead of being hidden behind the Search button, where there was nothing to suggest they were there. Search still collapses to its icon
    • Category descriptions on the forum index now use the full width of the card on phones instead of wrapping inside a narrow column beside the icon
    • On phones a category's name now sits centred against its icon instead of being pinned to the top of the row, so short titles no longer float above the tile beside them