Administrator checking a printed style-change list beside a monitor showing a muted forum layout

Changing a forum theme is not “upload a ZIP and refresh.” On XenForo it is a new style in an inheritance tree, a new default for guests, a second default for HTML email, a pile of add-on templates that assume the old parent, and a guest cache that will keep serving last week’s CSS until you evict it. Skip any one of those and the board looks fine in your admin session while members see a broken header.

This is the pre-flight list: what you copy, what you do not edit, who you log in as, and which switches you flip before you make the new style the public default. It is not the breakage cookbook that comes next, not the 2.3 variation switch, and not a buy-versus-commission argument — that TCO lives in premium versus custom. If you already flipped the default and the homepage is wrong, stop here and open the cookbook.

Official facts below come from the styles and style-properties manuals (docs.xenforo.com/manual/appearance/styles and …/style-properties). Community operations fill add-on tax, guest cache, and the three-session habit. If a control is not on those pages, this article does not invent an ACP name for it.

What you are actually changing

XenForo does not have a “theme” object. It has a Style: HTML templates + CSS/LESS templates + style properties. The Resource Manager calls the ZIP a style. Members call it a skin. You should still think in the ACP noun, because the options are named that way.

Three different jobs get sold as “we changed the theme”:

Job What moves What must stay true
Palette / branding Style properties on a child Parent templates stay stock; extra.less stays in the child
New parent A vendor or RM style imported as a parent Your child is re-parented; you merge outdated templates
Default swap Appearance options: which installed style guests get Email style, user-selectable styles, and cache all follow

A colour tweak is not a parent swap. A parent swap is not “set Default style and go to lunch.” If you do not know which row you are on, you are about to edit the wrong style.

Official inheritance, said once so the rest of the list makes sense:

  • A new style with no parent inherits the hidden Master style.
  • A child of Default style inherits Default, which inherits Master.
  • Customizations in the child override the parent. Uncustomized values keep inheriting.
  • Do not edit Master. Do not edit the vendor parent you will overwrite on the next paid update. Create a child and work there.

The official tree example (Custom header → Big footer / Small text → Red / Blue backgrounds) is for brand forks. Night mode is not a sibling style. Night mode is two variations inside one style. The dark-mode article already owns that switch. If your “theme change” is “we want dark,” enable variations. Do not import a second paid skin to fake it.

0. Write the sentence

One sentence in a staff thread before you download anything.

  • “We are recolouring Default so the header matches the marketing site.”
  • “We are installing UI.X 2 as a parent and keeping our child.”
  • “We are swapping the public default from Default to Legend, both variations readable, email stays light.”

If the sentence is “make it look modern,” you do not have a change. You have a mood. Moods do not survive an upgrade. The 2.3 upgrade article already explained why a 2.2 fork of PAGE_CONTAINER becomes a merge weekend. This list assumes you will not add another fork tonight.

Write down, in the same thread:

  1. The current default style name and its parent.
  2. Whether variations are enabled on that style.
  3. The HTML email default style (official: set in the same Appearance options group as the public default).
  4. Whether members may choose a style.
  5. Every add-on that injects templates or CSS you actually use (portal, ticker, stream directory, listing cards).
  6. Whether guest page cache or LiteSpeed Cache is on.

That inventory is the rollback map. Without it you will not know what “put it back” means.

1. Backup is a style change

A style lives in the database. Your extra.less, template modifications, and outdated-template queue live there too. Vendor ZIP files live on disk. A screenshot of the homepage is not a backup.

Take the same trio the XenForo backup article already named, and that the engine-agnostic backup inventory generalises:

  • Database (styles, properties, templates, TMS, options).
  • data/ (public avatars and thumbs — not the style, but you will restore the whole board if this goes badly).
  • internal_data/ (code cache, install lock, private data). Merge on restore, never replace those folders with an empty tree.

Close Setup → Options → Board active if this is a production parent swap, not a child-palette experiment on staging. A backup taken while members post is a moving target. For a planned default flip, close, wait a minute, dump.

Also export, or at least screenshot and copy:

  • The child’s extra.less (Appearance → the child → Templates, or the designer workflow you already use).
  • The list under Appearance → Template modifications.
  • Appearance → Outdated templates as it stands before you import anything. If it is already dirty, merge first. Do not stack a new parent on an unmerged child.

Prove the backup once if you have never restored this board. A file that has never been restored is a rumour. Staging is the right place to import a new parent the first time.

2. Work in a child, or create one now

Official: adding a style asks whether it is a child of an existing style. If you skip the parent, you inherit Master. If you pick Default (or the vendor style you just imported), you inherit that tree.

Create the child before you paint:

  1. Appearance → Styles → Add style.
  2. Title it something you will still understand in a year (Board, not newtheme2).
  3. Set the parent to the style you intend to serve — Default, or the imported vendor parent.
  4. Leave it not user-selectable until both variations are readable.
  5. Do not make it the Default style yet.

If a vendor parent is already installed, do not customize the parent “just this once.” The next update of that parent overwrites its templates. Your customizations belong in the child so they become outdated (mergeable) instead of gone.

If you have been editing Default itself, stop. Add a child of Default. Re-apply the few property changes and the extra.less there. Then leave Default stock. That is a one-hour job that saves every future upgrade. The cookbook will show you what “I edited the parent” looks like when extra.less silently does nothing.

Designer mode ($config['designer']['enabled'] = true) exists for people who keep templates on disk. It is not required for this checklist. Do not turn it on because a blog from 2019 said real designers use it. Most boards never should.

3. Import the new parent the boring way

Pre-built styles live in the Resource Manager category Styles [2.x]. Official: applying one takes a few minutes for most administrators. The minutes are the import. The hours are everything after.

Order that does not invent a second homepage:

  1. Import the vendor style as a new style. Do not overwrite Default.
  2. Read the vendor’s 2.3 notes. If the package requires an add-on (UI.X 2 requires the UI.X add-on), install that add-on on staging first.
  3. Re-parent your child onto the new parent, or create a fresh child of the new parent and move extra.less / TMS across.
  4. Open Appearance → Outdated templates. Merge. Blue is auto-merged. Yellow is a conflict you must read.
  5. Walk both variations if the parent ships them. A 2.2 “dark sibling” is not a variation. Prefer a 2.3 package that documents default + alternate.
  6. Only then consider making the child the public default.

If the vendor still ships two complete styles instead of one style with variations, you are buying two outdated-template lists. Prefer the 2.3 variation package. If you already own a pair, pick one as parent, enable variations, copy the dark chips into alternate, and retire the sibling when the child is stable.

UI.X 2 (ThemeHouse) is a framework: it wants its add-on, and a rebuild can hit operating-system file limits on a cheap host. XenBase (PixelExit) is a foundation style. One-shot skins (a DohTheme at $30–55, Legend at $59.50) are a different TCO. Decide which class you imported before you promise “we can always go back to Default in five minutes.” Going back is a default-style flip. Keeping your customizations is a child you did not throw away.

4. Add-on compatibility is a list, not a vibe

A new parent restyles templates add-ons already forked or modified. The crash is rarely the vendor demo. The crash is XenPorta, a slider, a ticker, a stream widget, or a listing card that assumed last year’s PAGE_CONTAINER.

Inventory, on paper:

Add-on / feature What it injects What you test
Stock widgets HTML / new posts / featured Portal first screen, both variations
XenPorta 2 (if you still run it) Magazine homepage, sliders Slider vs lazy-load; guest first paint
UI.X add-on (if the parent is UI.X 2) Framework templates Rebuild completes; no “too many open files”
Stream directory / XenRio Extra pages and widgets /streams/ or the page node; no autoplay on /
Server listing cards Prefix / field CSS Directory still filterable
Notices Overlay / ticker-shaped HTML Contrast on both variations
LiteSpeed Cache / guest page cache Cached HTML + CSS URLs Guests see new CSS after the flip

If an add-on has no 2.3 build, it is not a theme problem. It is an upgrade blocker the 2.3 article already named. Do not import a 2.3-only parent onto a board whose portal still calls jQuery.

Template modifications (Appearance → Template modifications) survive a parent swap better than direct template edits. A find/replace bound to an add-on ID is the upgrade-safe version of “I forked PAGE_CONTAINER.” If your branding lives as a direct edit of a core template, that template will go outdated the moment the new parent or a core upgrade ships a new version. Merge is not optional.

extra.less is community standard, not a page in the official styles manual. Put custom CSS in the child’s extra.less. Include extra files with <xf:include template="your_custom_file.less" /> if you split them. A TMS into extra.less is how you share a tweak across colour children. If you type CSS into the parent’s extra.less and then serve the child, you will file a ticket titled “extra.less does nothing.” That ticket is the next article.

5. Variations, email, and the two defaults

Official Appearance options, two controls people mix up:

  • Default style — what visitors who have not chosen a style receive.
  • Default style for HTML email — a style, not a variation. Set it in the same options group.

The style called “Default style” is just the name of the one that shipped. You can rename it. The public default need not be that row.

Walk this before you flip the public default:

  1. On the style you will serve, enable variations if you want a light/dark flip. Slots are default and alternate. 2.3 can follow prefers-color-scheme; guests get a footer gadget; the choice is cookie-shaped. 2.3.8 keeps the preference on logout (community / notebook). You do not need a third-party switcher.
  2. Set Color palette style type Light on the light half and Dark on the dark half so xf-intensify / xf-diminish push the right way.
  3. Point Basic colors at palette chips (@xf-paletteNeutral3, @xf-textColor), not pasted hex.
  4. Set the HTML email default to a style whose default variation is readable in a desktop mail client — usually stock Default, light. A public dark variation as the email style is how you ship a black brick.
  5. Turn user style selection off unless you truly have two brands. A chooser plus a variation gadget is a matrix you will not finish testing tonight.
  6. Setup → PWA setup meta theme colour and page background should survive both variations, or you accept that the installed icon bar follows the default variation.

Official style-property types, so you know what you are about to customize: colours, text, numbers with units, numbers without, switches, multiple-choice, and CSS groups (text / background / border / padding / extra CSS). Inherit unless you must override. Every customized property is a thing you will re-check after the next parent update.

Send one test mail to a throwaway you can open on a phone and on a desktop client. A dark-on-dark conversation notification is a style-change bug. A missing mail is transport (Setup → Options → Email options) and not this list.

6. Cache will lie to you

Guest page cache and LiteSpeed Cache for XF2 are how a successful style flip looks like a failure for twenty minutes — or until the TTL dies.

Official guest pages: $config['pageCache']['enabled'] needs a dedicated $config['cache']['context']['page'] provider. Community LiteSpeed Cache serves whole guest responses, CSS URLs included.

Before you flip the public default:

  • Know whether page cache or LSCache is on.
  • Plan to purge guest HTML and CSS after the flip. Purging HTML but leaving an old css.php URL is how guests keep the previous header.
  • Do not debug the new style only while logged in. Logged-in people skip guest cache. The configuration mistakes article already has the ticket “logged-in users see the guest homepage” — that one is cookies. This one is the inverse: guests see last Tuesday.

If you also run Cloudflare, do not enable JS minify or “auto optimize” as part of the theme night. 2.3 already deferred and split JS. The speed article owns that fight. Tonight you only need: cache is not serving the old sheet.

A clone that still has production Board URL plus guest cache is how you debug the wrong site. Disable page cache on staging until the URL is right.

7. Test users, not your admin session

The ACP is not the public style. Staff permissions are not Registered. Guests do not have a variation cookie until they flip.

Create or keep three windows:

Session What it proves
Guest (private window) Default style, first paint, footer variation gadget, guest cache, login/lost-password forms
Throwaway Registered Chooser (if any), variation cookie after refresh, editor, conversations, member card, prefixes
Staff Mod tools, ACP preview vs public, notices you hid from guests

Walk both variations in each window that can flip. Surfaces that usually fail after a parent swap:

  • Forum list and 2.3 SVG node icons (a leftover 2.2 webfont rule).
  • Thread view: quotes, code, attachments.
  • Quick editor and full editor chrome.
  • Member profile and hover card.
  • Widgets and HTML blocks with inline colours.
  • Notices.
  • Login / lost password (sometimes still on Default if you left a second style selectable).
  • The portal first screen if Index page route is not forums/.
  • Mobile width. Responsive is core. A “mobile style” is a second style you do not need.

Do not test only the homepage. Open a long thread, a conversation, a page node, and a forum with prefixes. Prefix colours that were tuned in extra.less against the old palette will vanish or clash.

If you use user style selection, test a member who still has the old style ID stored. After you retire a style, those members may fall back to default — or they may keep a zombie ID. Flip the option off for a week if you can.

8. Staging, then a quiet flip

Official upgrade advice applies here too: if you can, try it on a test installation. A style parent swap is closer to an upgrade than to a colour tweak.

Staging checklist:

  1. Restore last night’s backup onto a clone (same XenForo version).
  2. Point Board URL at the staging host. Fix cookie path. Mute outbound mail.
  3. Import the parent. Re-parent the child. Merge outdated templates.
  4. Walk the three sessions and both variations.
  5. Rebuild UI.X (or any framework) on staging so “too many open files” happens where members cannot see it. Raise open_files_limit or rebuild via CLI if the host dies mid-rebuild.
  6. Time the work. Production flip should be the default-style option plus a cache purge, not a first-time import.

Production flip, when staging is boring:

  1. Board active off if the import is still ahead of you. If the parent is already imported and you are only changing the default, you can leave the board open — but purge cache immediately after.
  2. Appearance options → Default style → the child. Email style → the light style you already tested.
  3. Purge guest page cache / LSCache / any CDN HTML+CSS.
  4. Guest private window. Hard refresh. Flip variation. Refresh again.
  5. Throwaway Registered. Same.
  6. Send yourself one email.
  7. Board active on if you closed it.
  8. Watch the first hour of “the header is gone” tickets. Nine times out of ten it is cache or a member still on the old selectable style.

Keep the old parent installed for a few days. Uninstalling it is how you discover a child still pointed at it. Hiding it from the chooser is enough.

Printable pre-flight

Copy this into the staff thread. Tick in order.

Inventory

  • One-sentence job written (palette / new parent / default swap).
  • Current default style, parent, variations on/off, email style, chooser on/off.
  • Add-on list that injects templates or CSS.
  • Guest page cache / LSCache / CDN named, with a purge method.

Safety

  • Database + data/ + internal_data/ copied off-box.
  • Child extra.less and TMS list copied.
  • Outdated-template queue empty before import.
  • Staging restore proved, or you accept that production is the first restore.

Structure

  • Child style exists. Parent is the style you will actually serve.
  • Master and vendor parent are untouched.
  • New RM style imported as a new parent, not over Default.
  • Required framework add-on installed on staging first.

2.3 and mail

  • Variations enabled on the style you will serve (if you want a flip).
  • Palette type Light / Dark matches the two halves.
  • Basic colors use @xf- chips.
  • HTML email default is a readable light style.
  • User style selection off unless two brands are real.

Add-ons and cache

  • Portal / XenPorta / slider / notices checked on both variations.
  • Stream and listing pages still work; no autoplay on /.
  • Guest cache purge planned for HTML and CSS.

Three sessions

  • Guest, throwaway Registered, staff.
  • Forum list, thread, editor, profile, conversations, login, one page node.
  • Both variations, desktop and a phone-width window.
  • One real HTML email opened in two clients.

Flip

  • Default style → child.
  • Cache purged.
  • Old parent still installed, not selectable.
  • First-hour watch.

What this is not

It is not permission to edit Master “because I will export it later.” It is not a second language pack. Appearance → Languages is a different tree. It is not a mobile-only style. It is not the buy-versus-build TCO. It is not a Core Web Vitals pass — if the new parent ships a slider that waits on JS, the speed article is the next ticket, not a reason to skip this list.

If something already broke, do not add another style. Open the common problems cookbook and fix the one you have.

Takeaways

  • A theme change is a style change: inheritance, two Appearance defaults, and a cache.
  • Backup the database (and the two directories) before you import a parent. Styles are data.
  • Child, never Master, never the vendor parent you will overwrite.
  • Test as guest, Registered, and staff, both variations, after you purge guest CSS.
  • HTML email is a style, not the member’s public flip. Keep it light unless you measured otherwise.
  • Add-ons and guest cache break more style flips than the ZIP you downloaded.

Write the sentence. Take the copy. Create the child. Then change the default — not the other way around.