This guide is designed for coding agents (Claude Code, Cursor, etc.). All customization lives in
site/custom/. Never modifyapp.js.
- Edit
site/custom/brand.json— name, tagline, theme, fonts - Replace
site/custom/logo.svgwith your logo - To add a language: copy
site/custom/strings/en.jsontosite/custom/strings/{locale}.json, translate values - To customize templates: edit files in
site/custom/templates/ - Deploy with
npx tsx deploy.ts
File: site/custom/brand.json
| Field | Type | Default | Description |
|---|---|---|---|
name |
string | "Krello" |
App name — appears in header, page title, hero, and {app_name} in strings |
tagline |
string | "Trello-style collaboration..." |
One-liner shown in page meta description and login page |
logo |
path | "custom/logo.svg" |
SVG logo relative to site/ |
favicon |
path | "favicon.svg" |
Favicon relative to site/ |
defaultTheme |
string | "sunrise" |
One of: sunrise, cobalt, gallery, aurora, ember, harbor |
defaultAccent |
string | "ember" |
One of: ember, gold, rose, moss, cobalt, sand, mist |
File: site/custom/brand.json → fonts
| Field | Default | Description |
|---|---|---|
display.family |
"Fraunces" |
Headings, brand wordmark |
display.weights |
[600, 700] |
Font weights to load |
body.family |
"Space Grotesk" |
Body text, buttons, inputs |
body.weights |
[400, 500, 700] |
Font weights to load |
source |
"google" |
"google" loads from Google Fonts CDN |
For CJK languages, use Noto Sans/Serif variants (e.g., "Noto Sans JP").
For Arabic/Hebrew, also set _meta.direction to "rtl" in the strings file.
Directory: site/custom/strings/
Default: en.json (always shipped, used as fallback for missing keys)
- Copy
site/custom/strings/en.jsontosite/custom/strings/{locale}.json(e.g.,nl.json) - Translate all string values — keys must stay identical
- Update the
_metaobject: setlanguage,name(human-readable), anddirection - Add the locale code to
brand.json→languagesarray (e.g.,["nl", "en"]) - Set
brand.json→defaultLanguageto the preferred default
{app_name}is automatically replaced withbrand.json→name{count}is used for numeric interpolation{variable}placeholders must be kept as-is in translations- For plurals: translate both the base key and the
_onevariant (e.g.,board.membersandboard.members_one) - The
_onevariant is used whencount === 1
{
"_meta": { "language": "nl", "name": "Nederlands", "direction": "ltr" },
"nav.dashboard": "Overzicht",
"nav.brand": "{app_name}",
"nav.new_board": "Nieuw bord",
"board.members": "{count} leden",
"board.members_one": "{count} lid"
}Directory: site/custom/templates/
Each .json file defines a board template. The filename (without .json) is the template ID.
{
"theme": "cobalt",
"accent": "gold",
"labels": [
["Frontend", "cobalt"],
["Backend", "moss"]
],
"lists": [
{
"title": "Backlog",
"color": "mist",
"cards": [
{
"title": "Example task",
"description": "Task description",
"priority": "high",
"points": 3,
"labels": ["Backend"],
"checklist": ["Step 1", "Step 2"]
}
]
},
{ "title": "In Progress", "color": "cobalt", "cards": [] }
]
}For each template, add string keys to your locale files:
template.{id}.title— shown in the template pickertemplate.{id}.description— description below the title
Templates are auto-discovered at deploy time — just drop a .json file in the directory.
- Create
site/custom/templates/{id}.jsonwith the structure above - Add
template.{id}.titleandtemplate.{id}.descriptionto all locale files - Deploy — the template appears automatically in the picker
Replace site/custom/logo.svg with your logo. Recommended: square SVG that works on both light and dark backgrounds.
Update brand.json → logo if you use a different filename or path.
To rebrand Krello as "TeamBoard" with Dutch and English:
// site/custom/brand.json
{
"name": "TeamBoard",
"tagline": "Projectborden voor het hele team.",
"logo": "custom/logo.svg",
"favicon": "favicon.svg",
"fonts": {
"display": { "family": "Inter", "weights": [600, 700] },
"body": { "family": "Inter", "weights": [400, 500, 700] },
"source": "google"
},
"languages": ["nl", "en"],
"defaultLanguage": "nl",
"defaultTheme": "cobalt",
"defaultAccent": "gold"
}Then copy en.json to nl.json and translate all values.