Skip to content

Custom Content

swcat can display custom information on entity detail pages based on entity annotations. This is useful for integrating external data or displaying specific metadata that does not fit into the standard catalog schema. This is also the primary way to visualize data generated by Sidecar Extensions.

How it works

You can configure swcat to look for specific annotations on your entities and render their values as dedicated cards in the user interface.

1. Configure swcat.yml

In your swcat.yml, use the ui.annotationBasedContent section to define which annotations should be rendered and how. You can optionally specify a rank to control the display order (lower ranks appear first).

ui:
  annotationBasedContent:
    # Key is the annotation name
    my-org.com/data:
      heading: Organization Data
      style: attrs  # text | list | json | attrs | table
      rank: 10      # Optional: Lower ranks appear first.

2. Annotate your entities

Add the corresponding annotation to your entity metadata.

apiVersion: swcat.dnswlt.me/v1alpha1
kind: Component
metadata:
  name: my-service
  annotations:
    my-org.com/data: |
      {
        "team": "Alpha",
        "cost-center": "12345",
        "criticality": "high"
      }
spec:
  type: service

Note

From the YAML parser's perspective, the annotation value is just a string. swcat always parses that string as JSON when interpreting it for custom content.

Supported Styles

The style property determines how the annotation value is parsed and displayed:

Style Description Expected Value Format
text Renders the value as plain text. A JSON string: "some text"
list Renders a bulleted list. A JSON array of strings: ["item1", "item2"]
json Renders a formatted code block with syntax highlighting. Any valid JSON value.
attrs Renders a key-value table. A simple JSON object: {"key": "value"}
table Renders a table with custom columns. A JSON array of objects: [{"a": 1}, {"a": 2}]

Adding Metadata to Annotations

Any annotation value can be wrapped in a $data/$meta envelope to attach metadata — such as a timestamp or version — that is displayed at the bottom of the card independently of the main content style:

{
  "$data": <the actual annotation value>,
  "$meta": {
    "key": "value"
  }
}

$data holds the payload that would otherwise be the full annotation value. $meta is a flat JSON object whose key-value pairs are rendered as a footer row beneath the main content.

Example: an attrs-style annotation written by an automation pipeline that records when it last ran:

metadata:
  annotations:
    my-org.com/data: |
      {
        "$data": {
          "team": "Alpha",
          "cost-center": "12345",
          "criticality": "high"
        },
        "$meta": {
          "updatedAt": "2025-03-07T14:32:00Z",
          "source": "pipeline/nightly"
        }
      }

The card will render the $data object as a key-value table (because style: attrs) and show updatedAt and source in a small footer line.

Custom Tables

The table style allows you to define a custom table structure. You must provide a columns list in the configuration, where each column has a header and a data template. The data template is a Go template that is executed for each item in the list.

Configuration example (swcat.yml):

ui:
  annotationBasedContent:
    asyncapi.com/channels:
      heading: AsyncAPI Channels
      style: table
      columns:
        - header: Topic
          data: {{ .address }}
        - header: Messages
          # You can use the 'join' helper to format string lists
          data: {{ .messages | join }}

Annotation example:

metadata:
  annotations:
    asyncapi.com/channels: |
      [
        {
          "address": "users/signup",
          "messages": ["UserSignedUp"]
        },
        {
          "address": "users/login",
          "messages": ["UserLoggedIn", "UserLoginFailed"]
        }
      ]