Theme Configuration
Configure your theme with theme.json and make it customizable.
theme.json Reference
Complete reference for the theme configuration file.
{
"name": "My Theme",
"version": "1.0.0",
"description": "A beautiful, responsive theme",
"author": "Your Name",
"authorUrl": "https://yourwebsite.com",
"license": "MIT",
"homepage": "https://github.com/yourname/my-theme",
"assets": {
"css": ["css/main.css"],
"js": ["js/main.js"]
},
"supports": {
"customLogo": true,
"customFavicon": true,
"featuredImages": true,
"menus": ["primary", "footer"],
"widgets": ["sidebar", "footer-1", "footer-2", "footer-3"],
"postFormats": ["standard", "gallery", "video"],
"customColors": true,
"darkMode": true
},
"settings": [
{
"key": "accentColor",
"type": "color",
"label": "Accent Color",
"default": "#007bff",
"section": "colors"
}
],
"layouts": {
"default": "layouts/main",
"home": "layouts/home",
"post": "layouts/single",
"page": "layouts/page",
"category": "layouts/archive"
}
}Basic Properties
Required Fields
| Property | Type | Description |
|---|---|---|
name | string | Display name of the theme |
version | string | Semantic version (e.g., "1.0.0") |
Optional Fields
| Property | Type | Description |
|---|---|---|
description | string | Short description |
author | string | Author name |
authorUrl | string | Author's website |
license | string | License type |
homepage | string | Theme's homepage or repo |
screenshot | string | Path to screenshot image |
tags | array | Theme tags for discovery |
Assets Configuration
{
"assets": {
"css": [
"css/normalize.css",
"css/main.css"
],
"js": [
"js/vendor/lib.min.js",
"js/main.js"
]
}
}Assets are loaded in the order specified.
Feature Support
Declare what features your theme supports:
{
"supports": {
"customLogo": true,
"customFavicon": true,
"featuredImages": true,
"menus": ["primary", "footer", "mobile"],
"widgets": ["sidebar", "footer-1", "footer-2"],
"postFormats": ["standard", "gallery", "video", "quote"],
"customColors": true,
"darkMode": true,
"rtl": true
}
}Menus
Declare menu locations:
{
"supports": {
"menus": ["primary", "footer", "mobile", "social"]
}
}In templates:
{{{ sdk.ui.menu('primary') }}}
{{{ sdk.ui.menu('footer') }}}Widget Areas
Declare widget areas:
{
"supports": {
"widgets": ["sidebar", "footer-1", "footer-2", "footer-3", "before-content", "after-content"]
}
}In templates:
<aside class="sidebar">
{{{ sdk.ui.widgetArea('sidebar') }}}
</aside>Theme Settings
Make your theme customizable from the admin panel:
{
"settings": [
{
"key": "accentColor",
"type": "color",
"label": "Accent Color",
"description": "Primary color used throughout the theme",
"default": "#007bff",
"section": "colors"
},
{
"key": "headerStyle",
"type": "select",
"label": "Header Style",
"options": [
{ "value": "default", "label": "Default" },
{ "value": "centered", "label": "Centered Logo" },
{ "value": "transparent", "label": "Transparent" }
],
"default": "default",
"section": "header"
},
{
"key": "showAuthor",
"type": "boolean",
"label": "Show Author on Posts",
"default": true,
"section": "posts"
},
{
"key": "footerText",
"type": "textarea",
"label": "Footer Copyright Text",
"default": "© {{year}} {{siteName}}. All rights reserved.",
"section": "footer"
},
{
"key": "postsPerPage",
"type": "number",
"label": "Posts Per Page",
"min": 5,
"max": 50,
"default": 12,
"section": "posts"
},
{
"key": "socialLinks",
"type": "group",
"label": "Social Links",
"fields": [
{ "key": "facebook", "type": "text", "label": "Facebook URL" },
{ "key": "twitter", "type": "text", "label": "Twitter URL" },
{ "key": "instagram", "type": "text", "label": "Instagram URL" }
],
"section": "social"
}
]
}Setting Types
| Type | Description | Options |
|---|---|---|
text | Single line text | placeholder, maxLength |
textarea | Multi-line text | rows, maxLength |
number | Numeric input | min, max, step |
boolean | Toggle switch | - |
select | Dropdown | options |
color | Color picker | - |
image | Image upload | - |
range | Slider | min, max, step |
group | Grouped fields | fields |
Sections
Organize settings into sections:
{
"settingSections": [
{ "id": "general", "label": "General" },
{ "id": "colors", "label": "Colors" },
{ "id": "header", "label": "Header" },
{ "id": "footer", "label": "Footer" },
{ "id": "posts", "label": "Posts" },
{ "id": "social", "label": "Social Media" }
],
"settings": [
{ "key": "accentColor", "section": "colors", ... },
{ "key": "headerStyle", "section": "header", ... }
]
}Using Settings in Templates
Access settings via the themeSettings object:
<header style="--accent-color: {{ themeSettings.accentColor }}">
...
</header>
{% if (themeSettings.showAuthor && post.author) { %}
<div class="author">By {{ post.author.name }}</div>
{% } %}
<footer>
<p>{{ themeSettings.footerText }}</p>
</footer>Layout Configuration
Map pages to layout templates:
{
"layouts": {
"default": "layouts/main",
"home": "layouts/home",
"post": "layouts/single",
"page": "layouts/page",
"category": "layouts/archive",
"tag": "layouts/archive",
"search": "layouts/search",
"404": "layouts/error"
}
}index.js Configuration
For dynamic configuration, use index.js:
module.exports = function(sdk) {
return {
// Custom template helpers
helpers: {
formatDate: (date) => {
return new Date(date).toLocaleDateString('en-US', {
year: 'numeric',
month: 'long',
day: 'numeric'
});
},
readTime: (content) => {
const words = content.replace(/<[^>]*>/g, '').split(/\s+/).length;
return Math.ceil(words / 200);
}
},
// Initialization
init: async (settings) => {
// Called when theme is activated
console.log('Theme activated with settings:', settings);
},
// Before render hook
beforeRender: async (context) => {
// Add data to all templates
context.currentYear = new Date().getFullYear();
return context;
}
};
};Use helpers in templates:
<time>{{ helpers.formatDate(post.createdAt) }}</time>
<span>{{ helpers.readTime(post.content) }} min read</span>Complete Example
{
"name": "Modern Blog",
"version": "2.0.0",
"description": "A clean, modern blog theme with dark mode support",
"author": "Your Name",
"license": "MIT",
"assets": {
"css": ["css/main.css"],
"js": ["js/main.js"]
},
"supports": {
"customLogo": true,
"customFavicon": true,
"featuredImages": true,
"menus": ["primary", "footer"],
"widgets": ["sidebar", "footer-1", "footer-2", "footer-3"],
"darkMode": true,
"customColors": true
},
"settingSections": [
{ "id": "general", "label": "General" },
{ "id": "colors", "label": "Colors" },
{ "id": "layout", "label": "Layout" },
{ "id": "social", "label": "Social Media" }
],
"settings": [
{
"key": "primaryColor",
"type": "color",
"label": "Primary Color",
"default": "#007bff",
"section": "colors"
},
{
"key": "layout",
"type": "select",
"label": "Homepage Layout",
"options": [
{ "value": "grid", "label": "Grid" },
{ "value": "list", "label": "List" },
{ "value": "masonry", "label": "Masonry" }
],
"default": "grid",
"section": "layout"
},
{
"key": "postsPerPage",
"type": "number",
"label": "Posts Per Page",
"min": 6,
"max": 24,
"default": 12,
"section": "layout"
},
{
"key": "enableDarkMode",
"type": "boolean",
"label": "Enable Dark Mode Toggle",
"default": true,
"section": "general"
},
{
"key": "facebook",
"type": "text",
"label": "Facebook URL",
"placeholder": "https://facebook.com/yourpage",
"section": "social"
},
{
"key": "twitter",
"type": "text",
"label": "Twitter URL",
"placeholder": "https://twitter.com/yourhandle",
"section": "social"
},
{
"key": "instagram",
"type": "text",
"label": "Instagram URL",
"placeholder": "https://instagram.com/yourprofile",
"section": "social"
}
],
"layouts": {
"default": "layouts/main",
"home": "layouts/home",
"post": "layouts/single",
"page": "layouts/page",
"category": "layouts/archive"
}
}