Custom Metadata & Templating
Codex allows you to store and display custom metadata for your series beyond the standard fields (title, genre, tags, etc.). This guide covers how to use custom metadata and configure its display using Handlebars templates.
Overview
Custom metadata is a flexible JSON object that can contain any data you want to associate with a series. It's displayed on the series detail page using a configurable Handlebars template that renders to Markdown.
Use cases:
- Track reading progress and personal ratings
- Link to external databases (MyAnimeList, AniList, etc.)
- Store collection details (edition, condition, purchase info)
- Add personal notes and reviews
- Track technical information (resolution, audio, subtitles)

Storing Custom Metadata
Custom metadata is stored as a JSON object on each series. You can set it via the API or through the series metadata editor.
JSON Structure
Custom metadata can be any valid JSON object:
{
"status": "In Progress",
"rating": 8.5,
"priority": 5,
"started_date": "2024-01-15",
"notes": "Great series, highly recommended!",
"links": [
{ "name": "MyAnimeList", "url": "https://myanimelist.net/manga/1" },
{ "name": "AniList", "url": "https://anilist.co/manga/1" }
],
"tags": ["favorite", "action", "must-read"]
}
API Endpoints
Update custom metadata via the API:
# Update series custom metadata
PATCH /api/v1/series/{id}
Content-Type: application/json
{
"custom_metadata": {
"status": "Completed",
"rating": 9
}
}
Display Templates
Custom metadata is rendered on the series detail page using a Handlebars template. The template is configured in Settings > Server Settings > Custom Metadata Template.
How Templates Work
- Your custom metadata is passed to the template as
custom_metadata - The template is rendered using Handlebars syntax
- The output (Markdown) is displayed using styled components
Default Template
The default template displays all fields as a simple bullet list:
Configuring Templates
- Navigate to Settings > Server Settings
- Find the Custom Metadata Template section
- Edit the template or select a pre-built example
- Use the live preview to test your changes
- Save your changes


Handlebars Syntax
Templates use Handlebars syntax with additional custom helpers.
Basic Syntax
Available Helpers
Codex provides these custom helpers:
| Helper | Description | Usage |
|---|---|---|
formatDate | Format a date string | {{formatDate value "MMM d, yyyy"}} |
ifEquals | Check if two values are equal | {{#ifEquals value1 value2}}...{{/ifEquals}} |
ifNotEquals | Check if two values are not equal | {{#ifNotEquals value1 value2}}...{{/ifNotEquals}} |
json | Output JSON representation | {{json value}} |
truncate | Truncate string to length | {{truncate value 100 "..."}} |
lowercase | Convert to lowercase | {{lowercase value}} |
uppercase | Convert to uppercase | {{uppercase value}} |
first | Get first N items of array | {{#first items 3}}...{{/first}} |
join | Join array with separator | {{join array ", "}} |
exists | Check if value exists | {{#exists value}}...{{/exists}} |
length | Get length of array/string | {{length array}} |
gt | Greater than comparison | {{#gt value1 value2}}...{{/gt}} |
lt | Less than comparison | {{#lt value1 value2}}...{{/lt}} |
and | Logical AND | {{#and cond1 cond2}}...{{/and}} |
or | Logical OR | {{#or cond1 cond2}}...{{/or}} |
lookup | Dynamic property access | {{lookup object key}} |
default | Provide default value | {{default value "fallback"}} |
Helper Examples
Date Formatting:
Date formats use date-fns format strings:
yyyy-MM-dd→ 2024-01-15MMM d, yyyy→ Jan 15, 2024MMMM d, yyyy→ January 15, 2024MMMM d, yyyy 'at' h:mm a→ January 15, 2024 at 2:30 PM
Conditional Display:
Array Operations:
Default Values:
Supported Markdown
The template output is rendered as Markdown with support for:
Headings
# Large Heading
## Section Heading
### Subsection
Lists
- Item 1
- Item 2
- Item 3
List items with **label**: value pattern are styled as key-value rows:
- **Status**: Completed
- **Rating**: 9/10
- **Priority**: High
Tables
| Column 1 | Column 2 | Column 3 |
|----------|----------|----------|
| Value 1 | Value 2 | Value 3 |
| Value 4 | Value 5 | Value 6 |
Links
[Link Text](https://example.com)
External links (starting with http) open in a new tab.
Code
Inline code:
File ID: `ABC123`
Code blocks:
```
Resolution: 1920x1080
Audio: Japanese 5.1
```
Blockquotes
> This is a blockquote for important notes or warnings.
Text Formatting
**Bold text**
*Italic text*
~~Strikethrough text~~
Horizontal Rules
---
Example Templates
Codex includes several pre-built templates to get you started:
Simple List
Basic key-value display:
Reading List
Track reading progress and ratings:
External Links
Link to external databases:
Collection Info
Track physical collection details:
With Tables
Display data in tables:
Best Practices
Template Design
- Use conditional blocks: Always wrap sections in
{{#if}}to handle missing data gracefully - Provide defaults: Use
{{default value "fallback"}}for optional fields - Keep it readable: Use headings and sections to organize information
- Test with sample data: Use the live preview in settings to test your template
Data Structure
- Use consistent keys: Stick to a naming convention (snake_case recommended)
- Use ISO dates: Store dates as ISO strings (e.g.,
2024-01-15) for reliable formatting - Group related data: Use nested objects for related information
- Use arrays for lists: Store multiple items as arrays for easy iteration
Performance
- Keep templates simple: Complex nested loops may slow rendering
- Limit output size: Templates have a 100KB output limit
- Use efficient helpers: Prefer
existsoveriffor null checks
Troubleshooting
Template Errors
If your template shows an error:
- Check for unclosed blocks (
{{#if}}needs{{/if}}) - Verify helper names are spelled correctly
- Check for mismatched quotes in strings
- Use the live preview to see error messages
Data Not Displaying
If custom metadata isn't showing:
- Verify the series has custom metadata set
- Check that your template handles the data structure correctly
- Ensure conditional blocks match your data (e.g.,
custom_metadata.fieldvscustom_metadata.nested.field)
Styling Issues
If the output doesn't look right:
- Verify your Markdown syntax is correct
- Check that tables have proper header rows
- Ensure code blocks use triple backticks
Next Steps
- Filtering & Search - Filter series by custom metadata
- API Documentation - Full API reference
- Libraries - Library management