Theme Configuration (settings.json)
Themes can expose customizable settings to the store administrator (e.g., colors, toggleable features, logo uploads). This is managed entirely via the config/ directory inside your theme.
Directory Overview
Every theme should have a config/ directory containing two JSON files:
theme/
└── config/
├── settings.json ← Defines the admin UI options
└── values.json ← Stores the saved values (auto-generated)
settings.json
The settings.json file is the schema for your theme's customization panel. It defines what fields appear in the admin UI.
The file is a JSON array. The first object must be the theme metadata. Subsequent objects define groups of settings.
1. Theme Metadata
The first object in the array defines the theme itself:
[
{
"name": "meta",
"theme_name": "My Custom Theme",
"package": "com.tag31.mytheme",
"version": "1.0.0",
"screenshot": "theme_preview.jpg",
"minify": false
},
// ... setting groups ...
]
| Key | Description |
|---|---|
name |
Must be "meta" |
theme_name |
Human-readable theme name |
package |
Unique identifier string |
version |
Theme version string |
screenshot |
Path to a preview image (stored in theme public/images/) |
minify |
Boolean. Set true to disable CSS/JS minification |
2. Setting Groups
The rest of the array consists of groups (which become tabs/sections in the admin panel). Each group contains an array of settings.
{
"name": "footer_settings",
"label": "Footer Configurations",
"description": "Customize the footer area",
"settings": [
// ... input fields ...
]
}
3. Supported Input Types
Inside the "settings" array, you can define various HTML5 input fields. Every setting object typically requires:
- type: The field type
- id: The unique key to access the value later
- label: Admin-facing label
- default: The default value
Text Input
{
"type": "text",
"id": "footer_copyright",
"label": "Copyright Text",
"default": "© 2026 Store Name"
}
Checkbox (Toggle)
Select Dropdown
{
"type": "select",
"id": "header_layout",
"label": "Header Style",
"default": "sticky",
"options": [
{ "value": "sticky", "label": "Sticky Header" },
{ "value": "static", "label": "Static Header" }
]
}
Image Picker (File Upload)
Returns an asset ID that must be resolved with getPath().
{
"type": "image_picker",
"id": "footer_logo",
"label": "Upload Footer Logo",
"default": "default_logo.png"
}
Other HTML5 Types
You can also use standard HTML5 input types like color, date, number, url, time, and password. The system will render the appropriate browser-native input field.
Summernote (Rich Text Editor)
Provides a WYSIWYG editor for HTML content.
{
"type": "summernote",
"id": "homepage_welcome_text",
"label": "Welcome Message",
"default": "<p>Welcome to our store!</p>"
}
Code Editor
Provides a raw textarea suitable for scripts or CSS injections.
values.json
When the administrator saves their customizations in the backend, the system writes the chosen values to config/values.json.
You do not need to manually edit values.json. It is entirely auto-generated and acts as a caching layer for the database. A sample values.json looks like this:
{
"footer_copyright": "© 2026 Acme Corp",
"enable_footer_logo": "1",
"header_layout": "sticky",
"primary_brand_color": "#0055ff",
"footer_logo": "4253"
}
Using Settings in Blade Templates
There are two primary ways to access the saved configuration values in your Blade templates:
1. The Global $themes Object
The system parses values.json and injects it into every template as the $themes object. You can access properties directly:
{{-- Checking a toggle --}}
@if($themes->enable_footer_logo ?? false)
{{-- Resolving an image picker asset --}}
<img src="{{ getPath($themes->footer_logo) }}" alt="Logo">
@endif
{{-- Outputting text or colors --}}
<div style="background-color: {{ $themes->primary_brand_color ?? '#ffffff' }};">
{{ $themes->footer_copyright ?? '' }}
</div>
2. The theme_setting() Helper
For safer access with built-in default fallbacks, you can use the theme_setting() helper:
<div style="background-color: {{ theme_setting('mytheme', 'primary_brand_color', '#ffffff') }};">
</div>
Note on Images: Values returned by an
image_pickerare internal asset IDs. You must pass them throughgetPath()orgetAsset()to convert them into a usable URL.