START here

XenForo forum installation, securing, and configuring

I’ve been using, moderating and administrating forums since they emerged after BBS and Usenet era (Wiki links). At the time of writing, XenForo (the official website link) is the best the-least-bad forum software in the world (at least in my opinion and for my use-case). This article is basically my notes on my XenForo installation and configuration – so I can get help and advice from people who actually know what they’re doing. 🙂
Oh, you can check out the BikeGremlin Forum here. 🙂

Why I built the BikeGremlin forum

Table Of Contents (T.O.C.):

  1. How to install XenForo
  2. How to secure a XenForo forum
    2.1. SPAM prevention
  3. Forum setup and configuration
    3.1. Emails
    3.2. Languages
    3.3. Style and push notifications (PWA)
    3.4. General settings
    3.5. Connected account providers
    3.6. Editing terms, privacy policy, and footer (copyright)
    3.7. Connecting Google Analytics
    3.8. Adding Google Custom (“programmable”) search
    3.9. No GIFs – no party!
  4. User groups and permissions
    4.1. User registration process
  5. Performance – LiteSpeed vs Redis cache
  6. Why, God, WHY?!
  7. Custom stuff
    7.1. Custom navigation and admin/mod only visible menu
    7.2. List users with unconfirmed emails
  8. Google AdSense and GDPR


1. How to install XenForo

This procedure is very simple and straightforward – nicely explained on XenForo’s website in an article called Installing XenForo (what else? 🙂 ).

Note: you must create a database, a database user, and set the user’s password, before you run the installation. The procedure is basically identical to WordPress installation procedure.

Recommended PHP version and extensions:

PHP version 8.0

Extensions:

  • imagick
  • exif
  • phar (for Gzip support)
  • mbstring
  • gmp
  • zip

Your admin dashboard may show:
“Suhosin enabled: No”

That’s OK. As far as I know, Suhosin (link to the project’s page) makes more problems than it solves (I suppose that info is shown for tech. support & troubleshooting purposes).

You could make a “php-info.php” file (simple text file, but with a .php instead of the .txt extension), with this code:

<?php phpinfo(); ?>

Upload it to you’r forum’s directory, and go to: “yourdomain.com/php-info.php” to see if you have all the needed extensions enabled (and general PHP info like version etc.). Make sure to not leave that file though – delete it after testing, just for increased security.

– T.O.C. –


2. How to secure a XenForo forum

The first thing I did was edit the .htaccess file by adding this at its beginning:

# BEGIN BikeGremlin edit

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^.well-known - [L]

# directory listing protection
Options -Indexes

# clickjacking attack protection
Header always append X-Frame-Options SAMEORIGIN

# MIME sniffing protection
Header set X-Content-Type-Options nosniff

# XSS protection
Header set X-XSS-Protection "1; mode=block"

# redirect from naked to www and https:
RewriteEngine on
RewriteCond %{HTTPS} !on [OR]
RewriteCond %{HTTP_HOST} !^www\.
RewriteRule (.*) https://www.bikegremlin.net%{REQUEST_URI} [L,R=301]

</IfModule>

# END BikeGremlin edit

XenForo forum user “digitalpoint” wrote an awesome guide with some tips on securing the forum using Cloudflare’s Zero Trust, here’s a link to that guide:
Cloudflare optimizations for XenForo

I’ve protected /install and admin-related paths with CloudFlare zero trust.

For better or for worse, I’ve decided to configure and implement Cloudflare Turnstile spam protection (it should work like a non-intrusive reCaptcha). XenForo offers a good integration for that:
Setup -> Options -> Basic Options -> Enable CAPTCHA for guests -> Use Cloudflare Turnstile

There, I could follow the Cloudflare Turnstile link with a simple guide for configuration.

Checking to confirm that Cloudflare Turnstile works for the register and login pages
Checking to confirm that Cloudflare Turnstile works for the register and login pages
Click on the image to see it full-sized

– T.O.C. –


2.1. SPAM prevention

Cloudflare is good, but it is probably a good idea to set up a few more spam-protection layers (why security is best done in layers). XenForo offers easy to set up integrations with following (free) services:
Setup -> Options -> Spam management

  • StopForumSpam
  • DNSBL
  • Akismet
  • Cloudflare Turnstile

– T.O.C. –


3. Forum setup and configuration


3.1. Emails

The first thing I did was go to Setup -> Options -> Email options
and configure the forum to send emails using my MXroute server.

Configuring XenForo to use my MXroute SMTP server for sending emails
Configuring XenForo to use my MXroute SMTP server for sending emails
Click on the image to see it full-sized

Tools -> Test outbound email
lets you test and confirm if you’ve configured it all properly.

Now, my MXroute account is limited to 300 outbound emails per hour. That’s not huge, not for a big forum.

In that same menu, there is an option called:
“Automated bounced email handler”
Enable it, to prevent sending emails that get nowhere.

I’ve created two separate additional email addresses. One for bounced, and another one for unsubscribe emails.

– T.O.C. –


3.2. Languages

Next up was the language setup: Appearance -> Languages & phrases -> Languages -> + Add language;
Where I added Serbian language (Serbocroatian).

Now was the time to make the post and page addresses look neatly:
Setup -> Options -> Basic options
Then checking the checkboxes under:
“Use full friendly URLs” and
“Romanize titles in URLs”

Every option has a nice, simple explanation of what it does – neat.

Setup -> Options -> Appearance
lets you select the default language (which will be active until users choose a different one).

This seems quite awkward. Apparently, I’m required to translate all the strings and phrases myself. I also find the computer-related terms in my native to be confusing (habit, probably). That would make offering support more difficult (if a user refers to something using the translation – as I never use interfaces in my native – LOL 🙂 ). So, I’ve decided to ditch the idea of a bilingual interface, for better or for worse.

– T.O.C. –


3.3. Style and push notifications (PWA)

I’ve created a new style (called it “BikeGremlin Style,” yes 🙂 ), to save all the edits in it. Setting it to inherit everything from the “Default style” and then customizing.

This part is important for the PWA setup:
Appearance -> Style -> Style properties -> Basic options
There, I uploaded all the icons.

In the page stup of the same menu, I set the Max. page width to 1010 px, and wide response break point at 1210 px.

Once all the icons are uploaded and configured properly, you can go to the PWA settings and enable the option for push notifications (some users like having that option).

XenForo’s PWA setup manual.

– T.O.C. –


3.4. General settings

Setup -> Options -> Node & forum list
Here, I’ve checked the option to “Create pages for categories” – which means clicking on a forum category will open a page listing its subcategories. Otherwise, clicking a category only scrolls the screen to show that category on top.

– T.O.C. –


3.5. Connected account providers

This might help with visitor registration by providing registration with Facebook and similar.

Linkedin login support seems to be botched – Sign in with LinkedIn deprecated (XenForo forum bug report link).

Facebook API seems to require a registered business.

So, apart from registering and logging in with an email and a password, I’ve managed to configure the following alternative (easier, probably more convenient) sign in options:

  • Google account
  • GitHub account
  • Microsoft account

Microsoft only allows a time-limited API (max. 2 years). And I’m not a huge fan. So I ditched that integration, after having confirmed that it works. 🙂

– T.O.C. –


3.6. Editing terms, privacy policy, and footer (copyright)

To edit these, I had to go to:
Appearance -> Phrases
and then find the things I wanted to customize, notably:

  • terms_rules_text
  • privacy_policy_text

It’s all basic HTML, and here are a couple of nice, free, online HTML editors:

I have also tried editing the footer, using this code, editing the template for:
extra_copyright

Note:
I paid for the XenForo license that allows for removing their default footer copyrigh (with a rel=”sponsored” link), but I wanted my footer to link and advertise what I consider to be the best the least bad (what?! I’m a pessimist, OK? 🙂 ) forum software in the world – that’s why I’ve included XenForo and Giphy links in the footer’s “final” version.

This is a basic version which is completely static:

<p>&copy; 2015 - 2023 <a title="BikeGremlin" href="https://www.bikegremlin.com/" target="_blank"><strong>BikeGremlin</strong></a> &bull; Powered by bacon, electricity &amp; <a title="XenForo" href="https://xenforo.com/" target="_blank"><strong>XenForo</strong></a></p>

Using this PHP code for the current year didn’t seem to be working:

// NOT WORKING:

<?php echo date("Y"); ?>

// NOR THIS:

<?php strftime("%Y"); ?>

Gox suggested I should try JavaScript – and that worked. Here’s the current date (year in this case) script that works with XenForo:

<script>document.write(/\d{4}/.exec(Date())[0])</script>

That allowed me to make the footer so I never have to update it for the current year, it should auto-update.

Here is the full code of my XenForo forum’s footer:

<p>&copy; 2023 - <script>document.write(/\d{4}/.exec(Date())[0])</script> <a title="BikeGremlin" href="https://www.bikegremlin.com/" target="_blank"><strong>BikeGremlin</strong></a> &bull; Powered by bacon, <a title="XenForo" href="https://xenforo.com/" target="_blank"><strong>XenForo</strong></a> &amp; <a title="GIPHY" href="https://giphy.com/" target="_blank"><strong>GIPHY</strong></a></p>

– T.O.C. –


3.7. Connecting Google Analytics

No need for any custom coding or extensions and similar (unlike WordPress).
Setup -> Options -> Search engine optimization (SEO)
And just copy/paste your Google Analytics tracking ID (“Google Analytics web property ID”).

– T.O.C. –


3.8. Adding Google Custom (“programmable”) search

Google does search a lot better – and it doesn’t put stress on the forum hosting server. That’s why I wanted to include that option to my forum.

In a separate (WordPress-related) article, I’ve explained the procedure of opening and configuring a Google Custom Search account.

But how do I add my Google custom search (now called Google Programmable search) code to my forum?

Appearance -> Styles -> Templates
find the “search_form” template and add your code at the end (or at the start if you want it to be shown first):

<xf:comment>BEGIN Google Programmable Search Form</xf:comment>
<div class="block-container">
  <div class="block-body block-row">
    <h1 class="p-title-value">Forum search by Google</h1>

    <script async src="https://cse.google.com/cse.js?cx=YOUR-GCSE-CODE-HERE"></script>
    <div class="gcse-search"></div>

    <div>
      <gcse:searchresults>
      </gcse:searchresults>
    </div>
  </div>
</div>
<xf:comment>END Google Programmable Search Form</xf:comment>

Update:

I’ve also created a separate search page. Why? Well, for several reasons:

  • It can work even if I disable the forum’s built-in search option. This will reduce any extra server load in case of very high demand & traffic – I like building things that can easily scale, right from the start.
  • I can make it clearly visible when visitors are watching all the topics (I aim to encourage people to use the search and find the info they need).
  • The page views of the search page are counted, so I can see if people are using the search without any additional visitor trackers or similar (more privacy is good).

Here’s what that looks like at the time of writing:

XenForo forum search by Google Programmable Search
XenForo forum search by Google Programmable Search

How I made that extra menu option is explained in section 7.1 (just disregard the “admin-only” stuff if you want it to be visible to all the visitors, of course).

For the page itself, I did:
Forums -> Nodes -> + Add node
and then chose the “Page” option.

Then I just copy/pasted the above listed code, and checked the “Log and count visits to this page” option. Of course, I gave it a Title (“Smart Forum Search”) and “URL portion” (“bg_search”), so the link to my search page is:
https://www.bikegremlin.net/pages/bg_search/

I could then easily make a custom menu navigation (section 7.1) item that leads to that link.

I suppose that I could still edit the “search_form” to show only my Google custom search (instead of completely removing that option for visitors), but I will leave the option of using the normal search bee for now.

– T.O.C. –


3.9. No GIFs – no party!

Animated GIFs can be pretty cool when added to posts (even when “fashionably overdone” as it happens with LES Black Friday deal threads). But they take up a lot of storage space, compared to static images.

Fortunately, XenForo offers a neat, out-of-the box integration with GIPHY. Giphy’s API is awesome – it lets you integrate GIFs stored and served from their servers. Awesome! 🙂

My GIPHY API application approved - AWESOME! :)
My GIPHY API application approved – AWESOME! 🙂

– T.O.C. –


4. User groups and permissions

XenForo has this sorted out pretty neatly by default.

I added a group called “Registered-approved.” Users from that group can post comments without prior moderators’ approval.

Groups & permissions -> User group promotions
menu let me configure conditions when users are automatically promoted from “Registered” to “Registered-approved” group.

A stupidity on my part:

By default, unregistered visitors (guests) are not allowed to view attachments.

Hence, when I wrote and published a tutorial on how to register and post a comment on my forum, guests could only see the small 150-pixel thumbnails of the screenshots in the tutorial. After Googling (apparently the wrong terms) and searching the forum, I posted a question on the XenForo support forum.

Apparently, my keyboard was faster than my brain – and I did not take my own advice related to tech. support. A minute after having written the problem down and posted it on the support forum, I remembered the user permissions about the attachments (that’s how XenForo calls any attachments, including the images).

Yes, allowing the guest users (“Unregistered / Unconfirmed”) to view the attachments has solved the problem:

Groups & permissions -> User group permissions -> Unregistered / Unconfirmed
-> Forum permissions -> View attachments to posts (set to “Yes”)

– T.O.C. –


4.1. User registration process

I wrote two brief tutorials for new members, because today, there are millions of people who’ve never ever used forums (and don’t even konw what a forum is). I published those as articles on my forum.

Then, I made a short HTML code that includes the email confirmation explanation in my native as well as in english, and added it here:
Appearance -> LanguagesEnglish (US) -> Phrases -> Edit phrase:
user_email_confirmation_body_html

<p><strong>English:</strong> Hi {username}, in order to complete your registration or reactivate your account at {board}, you need to confirm your email address by clicking the "Confirm your email" button below.</p>

<p><strong>Srpskohrvatski:</strong> Ćao {username}, da biste završili registraciju, kliknite na dugme "Confirm your email" dole.</p>

Here is what that looks like (in the mean time, I added a space before “Ćao” in the Serbocroatian section 🙂 ):

XenForo custom email confirmation note
XenForo custom email confirmation note

I also created a welcome e-mail with the basic instructions (how to post on a forum, yes, some people needed help):

Setup -> Options -> User Registration -> New User Welcome (section)

Checked the “Send welcome email on registration,” chose the HTML format option, and added this (text and links to my above-linked tutorial articles):

<p><strong>English:&nbsp;</strong>Welcome to the BikeGremlin forum. :)</p>
<p>Your account has been approved.</p>
<p>A brief tutorial (you can <strong>skip the section 1</strong>, since you've already done that :) ):<br /><a title="How to register and post a question/comment on the BikeGremlin forum" href="https://www.bikegremlin.net/threads/how-to-register-and-post-a-comment-question-on-bikegremlin-forum.24/" target="_blank"><strong>How to finish your registration and post a question or a comment</strong></a></p>
<p><strong>Srpskohrvatski: </strong>Dobrodo&scaron;li na BikeGremlin forum.&nbsp; :)</p>
<p>Va&scaron; nalog je odobren.</p>
<p>Kratko uputstvo (možete <strong>preskočiti sekciju 1</strong>, jer ste to već obavili :) ):<br /><a title="Kako se registrovati i postaviti pitanje/komentar na BikeGremlin forumu" href="https://www.bikegremlin.net/threads/kako-se-registrovati-i-postaviti-pitanje-komentar-na-bikegremlin-forumu.25/" target="_blank"><strong>Kako da zavr&scaron;ite registraciju i postavite pitanje ili komentar</strong></a></p>
<p>Relja Novović</p>

– T.O.C. –


5. Performance – LiteSpeed vs Redis cache

My server is LiteSpeed and that has been awesome for WordPress caching. Apparently, there is also a LiteSpeed XenForo add-on (link to its website).

It appears that the add-on is no longer maintained, according to the XenForo’s Resource section:
https://xenforo.com/community/resources/litespeed-cache-for-xf2-community.6248/

Redis cache add-on, on the other hand, seems to be still maintained:
https://xenforo.com/community/resources/redis-cache-by-xon.5562/

However, the last update date for the LiteSpeed plugin is just days before the latest XenForo version publish date (at the time of writing this). Perhaps the LiteSpeed folks just didn’t have any bugs to fix in the meantime?

What is the difference between LiteSpeed and Redis anyway?

LiteSpeed can cache any page that is created on the forum (this includes a forum page with a list of posts). It does that extremely well with WordPress and I can only assume (hope?) it is similar with XenForo.

Redis, on the other hand, can also cache any database querries. If one user searches for “best bicycle bearing grease,” the results of that forum search will be cached for the next user who does that search (oversimplified, but that’s roughly how it works).

Now, with WordPress, LiteSpeed cache plugin can use Redis for caching objects (as explained in the previous paragraph). It can “integrate” it, if Redis is present and properly configured on the server (as is the case with MDDHosting shared & reseller hosting servers). I couldn’t find any info on Redis in the LiteSpeed for XenForo installation manual.

At the time of writing, BikeGremlin Forum is running on PHP 8.0 and XenForo v2.2.13. As far as I know, a minor patch or two will be coming up in a few months, and a major update to version 2.3 is also in the making (and beta-testing). With a major change to 3.0 in sight.

From what I could gather, extensions don’t always work properly right away with a new version of forum software – especially in case of any major overhauls.

For these reasons, I’ve decided to keep running the “vanilla” forum version – with minimal changes. It’s running very smoothly now. When more people join the forum and if I notice any performance issues, I’ll see how to solve them – “crossing that bridge when I reach it” as the Americans say.

– T.O.C. –


6. Why, God, WHY?!

Forums are awesome. While WordPress sucks when it comes to handling comments – especially questions and response types of comments.

XenForo setup and configuration are pretty simple compared to most other forum software I’ve played with. But that is not all (I sound like a salesman now – LOL 🙂 ):

  • Practically every setting is clearly explained within the menu itself.
  • XenForo docummentation is good and well-written.
  • There’s an awesome support forum.
  • Most settings are pretty well configured out-of-the-box (i.e. by default).

So far so good (says a man falling from a 10-storey building)… 🙂

On my cycling website, I wrote in more details about why I thought building a forum is a jolly good idea.

On my forum, I wrote in a lot more detail about why I chose XenForo vs its alternatives.

– T.O.C. –


7. Custom stuff

7.1. Custom navigation and admin/mod only visible menu

To make a menu visible to only admins, or mods, go to:
Setup -> Public navigation

Add Navigation (top-right corner button), and set the display condition:

Admins only:

$xf.visitor.is_admin

Moderators only (and admins, of course):

$xf.visitor.is_moderator

Here’s an example:

XenForo custom menu visible to only admins (or mods)
XenForo custom menu visible to only moderators (and admins)

– T.O.C. –


7.2. List users with unconfirmed emails

I wanted to quickly list users with unconfirmed emails – so I can check and delete those who’ve been unconfirmed for month(s), or try emailing them first to see what the problem is.

After some playing with the member searh options, I figured out that this code will list users with unconfirmed emails, sorted by their registration dates:

https://www.example.com/admin.php?users/list&criteria[user_state][0]=email_confirm&order=register_date

Replace the “https://www.example.com” with your domain & forum path.

I combined this with the custom menu described in section 7.1.

This way, any moderators (and admins) can quickly check it out.

How to figure this out (the query parameters)?

I went to user search:
Users -> Search for users

There, I set the search parameters. If the search returns more than one result, then you can click on the option “Sort by: Username” at the top of the search results. Whichever option you choose (even if you use the Username), your browser’s address bar will show the link along with all the search results.

If a search has only one, or no results, then you won’t get the “Sort by:” option, and won’t get to see the search query used.

Here is the code to list “Discouraged users:”

https://www.example.com/admin.php?users/list&criteria[Option][is_discouraged]=1&order=last_activity

– T.O.C. –


8. Google AdSense and GDPR

Here is the relevant XenForo community discussion on GDPR & cookies.

Here are my notes on this – still unconfirmed as I’m waiting for my XenForo domain to be approved for AdSense.
Update, December 2023:
BikeGremlin forum has been approved for AdSense, and I can confirm that the below-described stuff actually works. 🙂

You can (and should) enable AutoAds for your XenForo domain. Then, you can use Google’s own cookie consent service – so you don’t have to pay for a separate service just for that.

My article about WordPress AdSense integration explains how to enable AdSense Auto ads (in section/chapter 3), and how to enable AdSense GDPR & cookie consent popups (section 4).

You can disable any other Auto ads options if you wish to, so you can manually place ads where you wish, and just harness the AdSense cookie consent options.

To add Auto ads code to your forum:

Setup -> Advertising -> + Add advertisement

Choose the option “Container header” for the position and copy/paste your AdSense auto ads code there:

Adding Google AdSense Auto ads to your XenForo forum
Adding Google AdSense Auto ads to your XenForo forum

The code example (replace the “XXXXXX” with your AdSense publisher number for it to work on your forum):

<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-XXXXXXXXXXXXX"
     crossorigin="anonymous"></script>

The display criteria lets you configure the auto ads to be removed for any logged in members, or for the members of certain user groups (haven’t tested this either, still waiting for AdSense approval).

Now, here is the code for the AdSense GDPR cookie revocation, which should be on your privacy policy page:

<a href=”javascript:googlefc.callbackQueue.push(googlefc.showRevocationMessage)”>Click here to revoke your choice</a>.

Yet to figure out and test a CPRA cookie revocation link/code.

To place the ads manually, what I did was:

Created an AdSense ad format and copied its code for manual placement (how to create AdSense units and get the code for manual placement).

Then, in the XenForo admin:

Appearance -> Widgets -> + Add widget

Copy/pasting the code in the “Template” section of the new widget (which I named “Adverts”).

Here is the example from my forum, containing a link to my patreon support, a list of forums I recommend, a header that says “Adverts” and the AdSense code for a vertical manually placed advert (replace the “XXXXXXX” and “NNNNN” with your AdSense code to make it work for your forum, of course):

<hr />
<p>
<a title="BikeGremlin Patreon support" href="https://www.patreon.com/bikegremlin" target="_blank">
<strong>Help BikeGremlin stay online</strong></a> with a Patreon donation:
<br />
<form action="https://www.patreon.com/bikegremlin"><input type="submit" value="Support BikeGremlin" /></form>
</p>

<hr />
<p>
<a title="Bike Forums .net" href="https://www.bikeforums.net/" target="_blank"> <strong>BikeForums.net</strong></a> is the best cycling-related forum in the world!
<br />
<img src="https://www.bikegremlin.net/bg-images/bikeforums-net-200x79.png" alt="Bike Forums .net" width="200" height="79" />
<br />
<em><a title="2Bike.rs Forum" href="https://www.2bike.rs/forum/" target="_blank">
<strong>2bike.rs</strong></a> je najbolji biciklistički forum na srpskohrvatskom</em>
</p>

<hr />
<p>
<a title="LowEndSpirit .com" href="https://lowendspirit.com/" target="_blank"> <strong>LowEndSpirit.com</strong></a> is a good forum for IT-enthusiasts on a budget (web-hosting, networks, computers...).
<br />
<img src="https://www.bikegremlin.net/bg-images/lowendspirit-com-200x33.png" alt="LowEndSpirit .com" width="200" height="33" />
</p>

<hr />

<h3 class="block-minorHeader">Adverts</h3>

<!-- io-text-display-vertical -->
<ins class="adsbygoogle"
     style="display:block"
     data-ad-client="ca-pub-XXXXXXXXXXXXX"
     data-ad-slot="NNNNNNNN"
     data-ad-format="auto"
     data-full-width-responsive="true"></ins>
<script>
     (adsbygoogle = window.adsbygoogle || []).push({});
</script>

<hr />

– T.O.C. –


Please use the BikeGremlin.net forum for any comments or questions.

If you've found any errors or lacking information in the article(s) - please let me know by commenting on the BikeGremlin forum.
You can comment anonymously (by registering with any name/nickname), but I think it is good to publicly document all the article additions (and especially corrections) - even if their author chooses to remain anonymous.

Skip to content