# Skills for authoring themes and blocks

**URL:** https://meta.discourse.org/t/skills-for-authoring-themes-and-blocks/401629
**Category:** Development
**Tags:** theme-guides, blocks, skills
**Created:** [April 27, 2026, 5:39pm UTC](https://meta.discourse.org/t/skills-for-authoring-themes-and-blocks/401629 "2026-04-27T17:39:44Z")
**Posts on this page:** 20
**Page:** 1

<div class="post-metadata">

### Author: ![manuel](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/manuel/32/468169_2.png) [@manuel](https://meta.discourse.org/u/manuel)
#### Post date: [April 27, 2026, 5:39pm UTC](https://meta.discourse.org/t/skills-for-authoring-themes-and-blocks/401629/1 "2026-04-27T17:39:45Z")

</div>

A repository of Claude Code skills for building Discourse themes and block components:

[https://github.com/discourse/discourse-theme-skills](https://github.com/discourse/discourse-theme-skills)

### :toolbox: What’s included

**Theme Authoring Skill** — covers a comprehensive scope of building a Discourse theme: scaffolding with the `discourse_theme` CLI, SCSS architecture, viewport library, localization, settings, modifiers, value transformers, icons, and CSS variables. Detailed reference files for icons, variables, and transformers are included separately and can be loaded on demand. [SKILL.md](https://github.com/discourse/discourse-theme-skills/blob/main/.claude/skills/discourse-theme-authoring/SKILL.md)

**Block Authoring Skill** — covers the theme-side of the Blocks API: writing block components with the `@block` decorator, defining args schemas, rendering blocks into the available core outlets, conditions, container blocks and layout grouping, and integrating theme translations and settings into block args. [SKILL.md](https://github.com/discourse/discourse-theme-skills/blob/main/.claude/skills/discourse-block-authoring/SKILL.md)

**Example Theme** — a working theme with a custom homepage built with blocks, demonstrating real patterns for outlets, conditions, and layout composition.

* * *

### :jigsaw: About the Blocks API

The Blocks API is Discourse’s new framework for building modular, composable UI components in themes and plugins. Blocks are Glimmer components registered into named outlets — like `homepage-blocks`, `hero-blocks`, or `sidebar-discovery` — and can be conditionally shown based on route, user, viewport, site settings, or plugin availability.

A key strength of the system is that blocks have small, focused scope and consistent patterns. This makes them well-suited for AI-assisted development: a model with the block skill can scaffold a working block component, register it to an outlet, and wire up conditions in a single pass.

The example theme in this repo demonstrates a homepage that adapts based on what plugins and content are available. Here’s what the basic homepage looks like, with a hero block and a featured topic list:

 ![Screenshot 2026-04-23 at 11-30-55 Discourse](https://global.discourse-cdn.com/meta/original/4X/e/3/8/e38d83686e5e13f1e0f06a0e81d9fe7f8a7a254d.png)  
 ![Screenshot 2026-04-23 at 11-46-29 Discourse](https://global.discourse-cdn.com/meta/original/4X/9/c/a/9caebd42d9d30c7fbfefdad697a4784d30098bdf.png)

When additional conditions are met (a featured tag is configured, the Discourse Events plugin is active, and the Discourse Leaderboard plugin is available) additional blocks are conditionally rendered into the layout:

 ![Screenshot 2026-04-23 at 12-07-01 Discourse](https://global.discourse-cdn.com/meta/original/4X/8/f/9/8f9530d8ccfc3e55ea8a54e92bd9274845d22fcb.png)  
 ![Screenshot 2026-04-23 at 12-07-18 Discourse](https://global.discourse-cdn.com/meta/original/4X/f/b/5/fb556535f0809403fefaefc79a046cb233cebc47.png)

Blocks aren’t limited to the homepage. The example theme also uses the `sidebar-blocks`-outlet to add a _Home_ link, the `sidebar-discovery` outlet to add category-specific sidebar content, and a `category-banner` block at the top of category pages:

 ![Screenshot 2026-04-23 at 11-46-02 Latest General topics - Discourse](https://global.discourse-cdn.com/meta/original/4X/9/4/6/946ec58f4a43a9496c057a5f3ffab2a4da5d67ad.png)  
 ![Screenshot 2026-04-23 at 11-46-14 Latest General topics - Discourse](https://global.discourse-cdn.com/meta/original/4X/8/3/4/83449a4f292674879aaa08bdc627efed3701cbbf.png)

The blocks inspector on DevTools shows the outlet labels and block identifiers overlaid on the page. This makes it easy to understand the layout structure and debug what’s rendering where:

 ![Screenshot 2026-04-23 at 11-36-45 Discourse](https://global.discourse-cdn.com/meta/original/4X/6/a/e/6ae12a39a34199a2fe8ca25128737ecf3c4003d6.png)  
 ![Screenshot 2026-04-27 at 18-32-00 Latest General topics - Discourse](https://global.discourse-cdn.com/meta/original/4X/5/2/5/5251501b8b0b5b6bdb466898500059a25e619c6a.png)

* * *

### :art: Using with a design platform MCP

The skills pair well with design platform MCPs (such as the Penpot or Figma MCP). With one connected, Claude can read component specs and design tokens directly from your design files and implement them using the skill’s conventions. It’s a tighter loop between design and code, especially when working from a structured design system.

* * *

### :fork_and_knife: Fork and adjust

Some conventions in the skills are more preference than convention, like the SCSS folder architecture. You can fork the repo and adjust the skills to match your own workflow and conventions.

* * *

### :speech_balloon: Share what you build

Give it a try and let us know how it goes! We’d love to hear how you’re using the skills, what you’ve built with them, and where they fall short. Feedback, corrections, and forks are all welcome.

---

<div class="post-metadata">

### Author: ![NateDhaliwal](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/natedhaliwal/32/313494_2.png) [@NateDhaliwal](https://meta.discourse.org/u/NateDhaliwal)
#### Post date: [April 27, 2026, 11:17pm UTC](https://meta.discourse.org/t/skills-for-authoring-themes-and-blocks/401629/2 "2026-04-27T23:17:09Z")

</div>

Will there be a dedicated Blocks topic or is that this?

If it’s the latter, maybe some code snippets could help? Or is what is in the `plugin-api.gjs` file the current docs?

Thanks.

---

<div class="post-metadata">

### Author: ![manuel](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/manuel/32/468169_2.png) [@manuel](https://meta.discourse.org/u/manuel)
#### Post date: [April 28, 2026, 7:35am UTC](https://meta.discourse.org/t/skills-for-authoring-themes-and-blocks/401629/5 "2026-04-28T07:35:40Z")

</div>

> [@NateDhaliwal](#):
>
> Will there be a dedicated Blocks topic or is that this?

There’ll still be documentation that covers the full Blocks API, including implementation in core and plugins. For theming with Blocks, the [SKILL.md](https://github.com/discourse/discourse-theme-skills/blob/main/.claude/skills/discourse-block-authoring/SKILL.md) should already touch on all relevant aspects. It’s compact and very readable.

> [@NateDhaliwal](#):
>
> If it’s the latter, maybe some code snippets could help? Or is what is in the `plugin-api.gjs` file the current docs?

The example theme includes both initializer files and blocks. The initializer files declare the layout per BlockOutlet: [discourse-theme-skills/javascripts/discourse/api-initializers at main · discourse/discourse-theme-skills · GitHub](https://github.com/discourse/discourse-theme-skills/tree/main/javascripts/discourse/api-initializers).

To me that’s the biggest change when working with themes: We don’t inject custom components directly into the app, as with PluginOutlets. We rather have a few dedicated layout frames now. All blocks that should render in that frame are registered in the same initializer file, even they show under different conditions.

It helps us keep a clean interface between customizations and the core app layouts.

---

<div class="post-metadata">

### Author: ![manuel](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/manuel/32/468169_2.png) [@manuel](https://meta.discourse.org/u/manuel)
#### Post date: [May 1, 2026, 9:48am UTC](https://meta.discourse.org/t/skills-for-authoring-themes-and-blocks/401629/6 "2026-05-01T09:48:40Z")

</div>

Having some actual fun with this :winking_face_with_tongue: … As other AI design tools it’s really performant for quickly prototyping ideas that would have been too costly to sketch out manually.

Asked for a very brutalist style editorial homepage, with highly unconventional content featured from the community. Got this layout, which indeed has some pretty nice ideas for featured blocks. Most funnily, it named the theme _Newspaper from Hell_ :grinning_face_with_smiling_eyes:

 ![Screenshot 2026-05-01 at 11-02-58 Discourse](https://global.discourse-cdn.com/meta/original/4X/a/8/b/a8b49e496cecf89487f1fa4b01b1220909aac1d4.png)  
 ![Screenshot 2026-05-01 at 11-03-14 Discourse](https://global.discourse-cdn.com/meta/original/4X/0/c/3/0c376ef8f7772cfdfef1000a526c2263379a7b61.png)

Then asked for something I always wanted to explore, a Japanese-style portal homepage with dense blocks, pastel colors, lots of small animations.. Love this initial take:

 ![Screenshot 2026-05-01 at 10-54-54 Discourse](https://global.discourse-cdn.com/meta/original/4X/7/5/d/75d92890e4bc82a97491f28238f2dd213806f99a.png)

And more fun when it’s all moving :carp_streamer: [Theme Creator](https://discourse.theme-creator.io/theme/manuel/community-plaza)

---

<div class="post-metadata">

### Author: ![Canapin](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/canapin/32/119591_2.png) [@Canapin](https://meta.discourse.org/u/Canapin)
#### Post date: [May 1, 2026, 10:45am UTC](https://meta.discourse.org/t/skills-for-authoring-themes-and-blocks/401629/7 "2026-05-01T10:45:58Z")

</div>

> [@manuel](#):
>
> And more fun when it’s all moving :carp_streamer: [Theme Creator](https://discourse.theme-creator.io/theme/manuel/community-plaza)

 ![image](https://global.discourse-cdn.com/meta/original/4X/b/2/4/b244de702db0275b3dc165789c167c44f69ae793.png)

flushy

---

<div class="post-metadata">

### Author: ![jrgong](https://avatars.discourse-cdn.com/v4/letter/j/c57346/32.png) [@jrgong](https://meta.discourse.org/u/jrgong)
#### Post date: [May 6, 2026, 11:07am UTC](https://meta.discourse.org/t/skills-for-authoring-themes-and-blocks/401629/8 "2026-05-06T11:07:22Z")

</div>

Finally!!! Will try it asap to update my experimental theme components :smiley:

![Elmo Surrounded by Intense Fire](https://global.discourse-cdn.com/meta/original/4X/3/6/1/361353d0375ad32180412f6acf4bf3faf78babc7.webp)

---

<div class="post-metadata">

### Author: ![BrianC](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/brianc/32/487568_2.png) [@BrianC](https://meta.discourse.org/u/BrianC)
#### Post date: [May 10, 2026, 7:27pm UTC](https://meta.discourse.org/t/skills-for-authoring-themes-and-blocks/401629/9 "2026-05-10T19:27:49Z")

</div>

This is great work and very creative. If we fork and build off this theme are there considerations for the parent not staying updated with Discourse over time? Trying to think how this should be approached.

Thanks for the resources!

---

<div class="post-metadata">

### Author: ![manuel](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/manuel/32/468169_2.png) [@manuel](https://meta.discourse.org/u/manuel)
#### Post date: [May 11, 2026, 9:36am UTC](https://meta.discourse.org/t/skills-for-authoring-themes-and-blocks/401629/10 "2026-05-11T09:36:54Z")

</div>

Thanks @BrianC!

On the parent staying updated: the skills track Discourse’s theme and Blocks APIs, so as long as we actively use them, they will be kept in sync as the APIs evolve. The example theme is more of a snapshot to demonstrate patterns. If you fork it, you own your fork. But you can refer back to the skills or new examples when updating your theme.

A central goal for the Blocks API itself is a stable, small surface area, that helps keep customizations resilient across Discourse updates. So If you mostly add custom blocks (as the example theme does) you should already operate within a stable environment. The main thing to watch for would be changes to outlet names or block API signatures. Right now the API is still considered experimental, so there might be changes to names etc.

I’d put the recommended approach like this: fork the theme freely, and lean on the skills docs as the living reference for how things should be done going forward.

---

<div class="post-metadata">

### Author: ![nathank](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/nathank/32/290039_2.png) [@nathank](https://meta.discourse.org/u/nathank)
#### Post date: [July 23, 2026, 4:16am UTC](https://meta.discourse.org/t/skills-for-authoring-themes-and-blocks/401629/11 "2026-07-23T04:16:46Z")

</div>

I’m just starting to mess around with this (without agentic coding).

I get the impression that it wouldn’t take too much to convert this into a Theme Component which controls just the Homepage of a site - for example, one already using the Horizon Theme. Would that be stupid?

Also, I’ve noticed a couple of issues:

### Upcoming Events Block doesn’t sort topics

It simply dumps event topics by creation date; this is most unhelpful!!

[ask.discourse.com](http://ask.discourse.com) suggests this type of change to fix this, which I can confirm works (forgive my lack of critical human thought):

```js
@bind
async fetchEvents() {
  const count = this.args.count || 5;
  const results = await ajax("discourse-post-event/events");

  if (!results.events?.length) {
    return null;
  }

  const now = new Date();

  // Separate past and future events, then sort ascending by start date
  const upcoming = results.events
    .filter((e) => new Date(e.starts_at) >= now)
    .sort((a, b) => new Date(a.starts_at) - new Date(b.starts_at));

  return upcoming.slice(0, count);
}

```

### Category Banners Block doesn’t respect the settings

It displays on all categories (not just the specified ones), and doesn’t seem to refresh on navigation (only on a page refresh).

---

<div class="post-metadata">

### Author: ![manuel](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/manuel/32/468169_2.png) [@manuel](https://meta.discourse.org/u/manuel)
#### Post date: [July 23, 2026, 10:24am UTC](https://meta.discourse.org/t/skills-for-authoring-themes-and-blocks/401629/12 "2026-07-23T10:24:16Z")

</div>

Thanks for giving it a try @nathank! It’s still considered experimental and we will make changes to the API, so I wouldn’t build a homepage-builder-type theme component on top of it for now.

The demo blocks are just basic examples. We also have some API changes coming up that will improve how we can load data. I’ll push changes to the all the blocks on the demo theme once this is available.

The category banners block should show on all categories. I think the category picker you reference is for the featured categories block on the homepage.

---

<div class="post-metadata">

### Author: ![satonotdead](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/satonotdead/32/447830_2.png) [@satonotdead](https://meta.discourse.org/u/satonotdead)
#### Post date: [August 29, 2026, 12:26am UTC](https://meta.discourse.org/t/skills-for-authoring-themes-and-blocks/401629/13 "2026-08-29T00:26:18Z")

</div>

Finally I took the step and started to play a little with this. Thank you very much for sharing it.

I wonder how possible could be to generate a custom block that displays the user’s avatar and name (which I’ve already achieved) along with their topic and posts count, likes, cheer points, and something similar to [See TL3 Progress](https://meta.discourse.org/t/see-tl3-progress/410166) but in relation to specific badges (custom trust level built on them)?

Inspired by role-playing games, where one can see on a card the own character’s EXP, basic information and their main skills.

---

<div class="post-metadata">

### Author: ![NateDhaliwal](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/natedhaliwal/32/313494_2.png) [@NateDhaliwal](https://meta.discourse.org/u/NateDhaliwal)
#### Post date: [August 29, 2026, 2:52am UTC](https://meta.discourse.org/t/skills-for-authoring-themes-and-blocks/401629/14 "2026-08-29T02:52:52Z")

</div>

If you want to add a block, I think you’d need to submit a PR to core.

---

<div class="post-metadata">

### Author: ![nickdb](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/nickdb/32/444510_2.png) [@nickdb](https://meta.discourse.org/u/nickdb)
#### Post date: [August 29, 2026, 9:45am UTC](https://meta.discourse.org/t/skills-for-authoring-themes-and-blocks/401629/15 "2026-08-29T09:45:45Z")

</div>

I have been reading up on the blocks API, ask.discourse has been quite helpful.

I would like to try imitate (plagiarise) the meta category banner with the icons, amongst some other ideas.

Most of the materials I have read seem to lean towards self-hosted sites and not hosted sites.

Are there any limitations for hosted sites?

---

<div class="post-metadata">

### Author: ![manuel](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/manuel/32/468169_2.png) [@manuel](https://meta.discourse.org/u/manuel)
#### Post date: [August 31, 2026, 10:53am UTC](https://meta.discourse.org/t/skills-for-authoring-themes-and-blocks/401629/16 "2026-08-31T10:53:40Z")

</div>

> [@satonotdead](#):
>
> I wonder how possible could be to generate a custom block that displays the user’s avatar and name (which I’ve already achieved) along with their topic and posts count, likes, cheer points, and something similar to [See TL3 Progress](https://meta.discourse.org/t/see-tl3-progress/410166) but in relation to specific badges (custom trust level built on them)?

That should be entirely possible and an agent using the skills and the example blocks from the shared theme should be fully capable of coding this.

I actually did a similar block a while ago. It’s not yet using the new Blocks API, but you could still look at the approach at [Manuel Kostka / Discourse / Blocks / User Profile · GitLab](https://gitlab.com/manuelkostka/discourse/blocks/user-profile). Looks like that for example, on the Canvas Central theme:

 ![image](https://global.discourse-cdn.com/meta/original/4X/5/1/8/51800277c465c73be5fd29197a0f3c9089d18314.jpeg)

> [@NateDhaliwal](#):
>
> If you want to add a block, I think you’d need to submit a PR to core.

We don’t have blocks in core (yet). All blocks are just added using themes or theme components.

> [@nickdb](#):
>
> Are there any limitations for hosted sites?

You can add blocks to existing BlockOutlets using themes and theme components and I think you need to be on a Pro plan or above to add custom themes. Else there should be no limitations.

---

<div class="post-metadata">

### Author: ![nickdb](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/nickdb/32/444510_2.png) [@nickdb](https://meta.discourse.org/u/nickdb)
#### Post date: [August 31, 2026, 11:31am UTC](https://meta.discourse.org/t/skills-for-authoring-themes-and-blocks/401629/17 "2026-08-31T11:31:15Z")

</div>

I’m busy arguing with your ask AI bot that insists on telling me not to use it as it is too experimental and is “being dogfooded” on meta. About to give up and wait for it to be more mature.

---

<div class="post-metadata">

### Author: ![manuel](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/manuel/32/468169_2.png) [@manuel](https://meta.discourse.org/u/manuel)
#### Post date: [August 31, 2026, 11:38am UTC](https://meta.discourse.org/t/skills-for-authoring-themes-and-blocks/401629/18 "2026-08-31T11:38:26Z")

</div>

The bot is likely getting its direction from the official announcement: [Creating a 'Blocks' API for injecting content](https://meta.discourse.org/t/creating-a-blocks-api-for-injecting-content/411090)

But I agree, you should not use it in production for now, there will likely be breaking changes that are not announced ahead of time.

---

<div class="post-metadata">

### Author: ![nickdb](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/nickdb/32/444510_2.png) [@nickdb](https://meta.discourse.org/u/nickdb)
#### Post date: [August 31, 2026, 11:40am UTC](https://meta.discourse.org/t/skills-for-authoring-themes-and-blocks/401629/19 "2026-08-31T11:40:33Z")

</div>

Fiddling on a staging site, wouldn’t muck about with prod.

---

<div class="post-metadata">

### Author: ![manuel](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/manuel/32/468169_2.png) [@manuel](https://meta.discourse.org/u/manuel)
#### Post date: [August 31, 2026, 11:44am UTC](https://meta.discourse.org/t/skills-for-authoring-themes-and-blocks/401629/20 "2026-08-31T11:44:20Z")

</div>

That should be fine though. The caveat is not that it’s not comprehensive yet, but rather that we will not hedge against breaking changes as with other stable APIs or interfaces.

---

<div class="post-metadata">

### Author: ![NateDhaliwal](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/natedhaliwal/32/313494_2.png) [@NateDhaliwal](https://meta.discourse.org/u/NateDhaliwal)
#### Post date: [August 31, 2026, 12:22pm UTC](https://meta.discourse.org/t/skills-for-authoring-themes-and-blocks/401629/21 "2026-08-31T12:22:04Z")

</div>

> [@manuel](#):
>
> We don’t have blocks in core (yet). All blocks are just added using themes or theme components.

Oh of course. Silly me. I thought it was referring to adding block locations.

---

<div class="post-metadata">

### Author: ![manuel](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/manuel/32/468169_2.png) [@manuel](https://meta.discourse.org/u/manuel)
#### Post date: [August 31, 2026, 12:47pm UTC](https://meta.discourse.org/t/skills-for-authoring-themes-and-blocks/401629/22 "2026-08-31T12:47:49Z")

</div>

> [@NateDhaliwal](#):
>
> I thought it was referring to adding block locations.

Yes, BlockOutlets are in core. Though you could also add them with a plugin.

[Next page](https://meta.discourse.org/t/skills-for-authoring-themes-and-blocks/401629.md?page=2)
