As themes grow more powerful, there’s more to remember about how they work. We have loads of detailed documentation under #howto / #themes, but if you just need something to jog your memory, this guide may help.
General Resources
 Beginner’s guide
 Beginner’s guide
 Designer’s guide
 Designer’s guide
 Developer’s guide
 Developer’s guide
 Theme Creator
 Theme Creator
 Theme CLI
 Theme CLI
 Theme Directory
 Theme Directory
 Component Directory
 Component Directory
 Theme Modifiers
 Theme Modifiers
 Themeable site settings
 Themeable site settings
File/Folder Structure read more
about.json
settings.yml
common/, desktop/, mobile/
  {common|desktop|mobile}.scss
  head_tag.html
  header.html
  after_header.html
  body_tag.html
  footer.html
  embedded.scss (common only)
locales/
  en.yml
  ...
assets/
  (arbitrarily named files, referenced in about.json)
stylesheets/
  (arbitrarily named files, can be imported from each other, and common/desktop/mobile.scss)
javascripts/
  (arbitrarily named files. Supports .js .hbs and .raw.hbs)
about.json structure info, available metadata
{
  "name": "My Theme",
  "component": false,
  "license_url": null,
  "about_url": null,
  "authors": null,
  "theme_version": null,
  "minimum_discourse_version": null,
  "maximum_discourse_version": null,
  "assets": {
    "variable-name": "assets/my-asset.jpg"
  },
  "color_schemes": {
    "My Color Scheme": {
      "primary": "222222"
    }
  }
}
SCSS
Javascript read more
// {theme}/javascripts/api-initializers/init-theme.gjs
import { apiInitializer } from "discourse/lib/api";
export default apiInitializer((api) => {
  // Your code here
});
Settings read more
settings.yml:
fruit:
  default: apples|oranges
  type: list
  description: # Old method. It's better to define these in the locale files (see below)
    en: English Description
    fr: Description Française
Access from JavaScript:
console.log(settings.fruit);
Access from gjs templates:
<template>{{settings.fruit}}</template>
Access from scss:
html {
  font-size: #{$global-font-size}px;
  background: $site-background;
}
Themeable site settings read more
about.json:
"theme_site_settings": {
  "enable_welcome_banner": false
}
Access from JavaScript:
@service siteSettings;
this.siteSettings.enable_welcome_banner;
Access from gjs templates:
<template>{{this.siteSettings.enable_welcome_banner}}</template>
Translations read more
locales/en.yml
en:
  my_translation_key: "I love themes"
  theme_metadata: # These are used in the admin panel. They are not made available to your js/hbs files
    description: This theme lets you do amazing things on your Discourse
    settings:
      fruit: A description of the whitelisted_fruits setting
Access from JavaScript:
import { i18n } from "discourse-i18n";
i18n(themePrefix("my_translation_key"));
Access from gjs templates:
import { i18n } from "discourse-i18n";
<template>
  {{i18n (themePrefix "my_translation_key")}}
  <DButton @label={{theme-prefix "my_translation_key"}} />
</template>
This document is version controlled - suggest changes on github.
 Available CSS Variables
 Available CSS Variables