When building corporate sites or sites for clients, you often run into this situation: the client wants a completely different front-end design, but this template belongs only to this client, must not go into the product package, and should not appear on other sites. KingCMS X1's 'private themes' are designed for exactly this scenario: placed in the site's private directory, visible only to this site, and not overwritten during upgrades.

KingCMS X1 前台首页示例
The same admin backend can be paired with completely different front-end themes for different sites.

Where private themes go

The default directory is local/themes/<id>/ under the site root (in the development repository it is x1/local/themes/). Each theme gets one subdirectory, with a structure exactly the same as official themes: theme.json is required, templates/ holds Twig templates, assets/ holds images and styles, lang/ holds theme text, and preview.png is optional and used as the backend preview image.

<id> must match the id in theme.json, and may contain only lowercase letters, digits, underscores, and hyphens. This directory goes into neither Git nor release or upgrade packages; during upgrades the whole package is replaced, and local/ is preserved as-is.

Minimal manifest

theme.json must contain at least four fields: id, name, version, and author. If any is missing or malformed, the theme is skipped. Common fields also include screenshot (preview image filename), supported_modules (dependent modules), options, and ad_slots. The latter two use the same validation rules as official themes; invalid structures are ignored.

The easiest approach: copy an official theme and modify it

Don't write from scratch. First copy an entire official theme directory to local/themes/, change it to your own id and name, then replace templates and assets page by page. Provide templates only for the pages you need: missing templates fall back to the official default theme, and only then to the module's built-in templates, so you can change only the homepage, list, and detail pages first and leave the rest using defaults.

Theme assets are served via the /n/<id>/... path: it first looks in the official theme root's assets/, then in the private root's assets/, and if neither exists falls back to the default theme. Theme text is read from the directory where the theme actually resides.

KingCMS X1 前台商品详情页示例
A private theme can redo only the shop pages while other pages continue to use default templates.

Enabling and conflicts

After the directory is in place, the backend 'Themes' list will show this theme with a 'Private' label; you can preview, enable, and delete it. Private themes do not provide online template editing. Once enabled, theme.active records the theme id; switching back to an official theme requires no extra steps.

There is one hard rule: when ids are the same, the official theme takes precedence. If a private directory contains an id that matches an official theme, the official theme is displayed as usual, the private one is skipped, and an error_log entry is written and added to the diagnostics list; the site will not error. So a custom theme should use its own id, not default or furniture.

Notes

  • Backup: local/ is not included in release packages. Although upgrades preserve it, you should still back it up separately; when moving servers, remember to take it with you.
  • Deletion: after deleting a private theme that is in use, the current theme automatically falls back to default, with no blank page.
  • Version: increment version when modifying a theme, so it is easier to identify which version is actually running online.
  • Licensing: private themes only address 'site-specific design'; they must not be used to bypass commercial licensing or distribute official themes.

Summary

Private themes separate 'client customization' from 'product upgrades': designs live in local/themes/, while upgrade packages only handle the core and official themes, and the two do not overwrite each other. For agencies and multi-site operations, this is much more reliable than manually merging templates before every upgrade.