Custom Content

Want to quickly build your UI?

Confluence Custom Content in Forge lets you quickly build user interfaces consistent to Atlassian Design using pre-built components.

Already have a Connect app? Start adding Forge features in less than an hour.

You can declare custom content in Confluence. This content behaves like built-in Confluence content types, such as page, blog post, or comment.

Custom content can be:

You can also find a step by step tutorial series covering all the aspects of custom content here: Custom Content with Confluence Connect

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
{
  "modules": {
    "customContent": [
      {
        "uiSupport": {
          "contentViewComponent": {
            "addonKey": "addon-key",
            "moduleKey": "dialog-module-key"
          },
          "icons": {
            "item": {
              "width": 16,
              "height": 16,
              "url": "/item.png"
            }
          }
        },
        "apiSupport": {
          "bodyType": "storage",
          "supportedContainerTypes": [
            "space",
            "page"
          ],
          "supportedChildTypes": [
            "attachment",
            "comment"
          ],
          "supportedSpacePermissions": [],
          "preventDuplicateTitle": false,
          "indexing": {
            "enabled": true
          }
        },
        "name": {
          "value": "My Content Type Name"
        },
        "key": "my-custom-content"
      }
    ]
  }
}

Create custom content via the Confluence REST API

The above snippet defines your custom content: my-custom-content. You can create a new piece of content with this type by posting the following JSON to the Confluence /rest/api/content endpoint.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

 {
     "type":"ac:my-addon-key:my-custom-content",
     "title":"My content title",
     "space":{
         "key":"ds"
     },
     "body":{
         "storage":{
             "value":"This is my content body",
             "representation":"storage"
         }
     }
 }
 

The content type key

The content type key for custom content is defined in 3 parts:

  • ac
    This is always the same, indicating that this content type is defined in a Connect add-on.
  • my-addon-key
    The key of the Connect add-on.
  • my-custom-content
    The key of the module which defines the custom content.

For example:

Content type key ac:my-addon-key:my-custom-content should be used for creating custom content that's defined in a Connect add-on with the key of my-addon-key and module key of my-custom-content

Properties

apiSupport
Type
Required
Yes
Description

This property allows you to specify the container types your custom content can appear in, and its supported child content types. It also allows you to enable indexing of your custom content.

This property allows you to specify the container types your custom content can appear in, and its supported child content types. It also allows you to enable indexing of your custom content.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
{
  "bodyType": "storage",
  "supportedContainerTypes": [
    "space",
    "page"
  ],
  "supportedChildTypes": [
    "attachment",
    "comment"
  ],
  "supportedSpacePermissions": [],
  "preventDuplicateTitle": false,
  "indexing": {
    "enabled": true
  }
}

In the above example, you'll see we specify content type keys in the supportedContainerTypes and supportedChildTypes fields. There are 2 categories of content type you can reference \u2013 built-in content and custom content.

Built-in content types example

The following snippet shows the content type we're defining can:
  • Be contained in a space or a page
  • Have a child comment or a child attachment

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
{
  "bodyType": "storage",
  "supportedContainerTypes": [
    "space",
    "page"
  ],
  "supportedChildTypes": [
    "attachment",
    "comment"
  ],
  "supportedSpacePermissions": [],
  "preventDuplicateTitle": false,
  "indexing": {
    "enabled": true
  }
}

Custom content example

The following snippet shows the content type we're defining can:
  • Be contained in a content item with type type1 or type2, defined in the app with the key my-first-addon
  • Have a child of a content item with type type1 or type2, defined in the app with the key my-second-addon

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
{
  "bodyType": "storage",
  "supportedContainerTypes": [
    "ac:my-first-addon:type2",
    "ac:my-first-addon:type1"
  ],
  "supportedChildTypes": [
    "ac:my-second-addon:type1",
    "ac:my-second-addon:type2"
  ],
  "supportedSpacePermissions": [],
  "preventDuplicateTitle": false,
  "indexing": {
    "enabled": true
  }
}

Raw body type custom content example

You can define custom content to support a content body with a type of raw.
This is useful when you want to store, for example, stringified JSON to the content.

1
2
3
4
5
6
7
8
9
10
11
12
13
{
  "bodyType": "raw",
  "supportedContainerTypes": [
    "space"
  ],
  "supportedChildTypes": [],
  "supportedSpacePermissions": [],
  "preventDuplicateTitle": false,
  "indexing": {
    "enabled": true
  }
}

Content with a raw body looks like this:

1
2
3
4
5
6
7
8
9
10
11
12
13

 {
     "title": "My title",
     "space": {"key": "DS"},
     "type": "ac:add-on-key:module-key",
     "body": {
         "raw": {
             "value": "{\"field\": \"value\"}",
             "representation": "raw"
         }
     }
 }
 

Properties

supportedContainerTypes
Type
Required
Yes
Description

Defines types that this custom content can be contained in.
The supported content types are:

  • space: This custom content can be contained in a space.
  • page: This custom content can be contained in a page.
  • blogpost: This custom content can be contained in a blog post.
  • Any other content type of defined custom content within the same app.
    Any other custom content type defined in the same app.
    Please refer to The content type key for how to construct the content type key.

bodyType
Type
Defaults to
storage
Allowed values
  • storage
  • STORAGE
  • raw
  • RAW
Description

Defines the content body type of this custom content. Currently supported content body types are:

  • storage: This is Confluence's default storage representation which can be rendered using the Content Body Conversion API
  • raw: This representation is used for storing raw data in the body that is not storage format, this format is opaque to Confluence

indexing
Type
Description

Defines how this content type will be indexed

Defines how this macro parameter will be indexed for site search

1
2
3
4
{
  "enabled": true
}

The macro parameter indexing property allows apps to hook into the mechanism by which Confluence populates its search index for site search. Each time macro is created or updated in Confluence, the value that is stored in the macro parameter will be added to the search index. The value of this macro parameter will also be used in displaying the excerpt text for search result.

This is useful when the body of the macro is not searchable, for example: macros with bodyType: none. The app can still provide meaningful search text for this content by storing the extracted information to the macro parameter. The data in this macro parameter will get indexed as is without any modification.

preventDuplicateTitle
Type
Defaults to
false
Description

Defines whether Confluence should prevent content with duplicate title from being created in the same space or container.

supportedChildTypes
Type
Description

Defines types that can be contained in this custom content.
Currently supported content types:

  • attachment: This custom content can contain attachment.
  • comment: This custom content can contain comment.
  • Any other custom content type defined in the same app.
    Please refer to The content type key for how to construct the content type key.

supportedSpacePermissions
Type
Description

Defines the space permissions that this custom content supports. Allowable values are : read, create and delete. It is required that these permissions be granted through the space permissions UI in order to perform the given operation.

Otherwise the default permissions will be used.


key
Type
Max length
100
Required
Yes
Pattern
^[a-zA-Z0-9-]+$
Description

A key to identify this module.

This key must be unique relative to the add on, with the exception of Confluence macros: Their keys need to be globally unique.

Keys must only contain alphanumeric characters and dashes.

The key is used to generate the url to your add-on's module. The url is generated as a combination of your add-on key and module key. For example, an add-on which looks like:

{ "key": "my-addon", "modules": { "configurePage": { "key": "configure-me", } } }

Will have a configuration page module with a URL of /plugins/servlet/ac/my-addon/configure-me.


name
Type
Required
Yes
Description

A human readable name.

Represents a string that can be resolved via a localization properties file. You can use the same i18n Property key and value in multiple places if you like, but identical keys must have identical values.

Example

1
2
3
4
{
  "value": "My text"
}

Properties

value
Type
Max length
1500
Required
Yes
Description

The human-readable default value. This will be used if no translation exists. Only the following HTML tags are supported: b, i, strong, em, and code.

i18n
Type
Max length
300
Description

The localization key for the human-readable value. Translations for the keys are defined at the top level of the add-on descriptor.


uiSupport
Type
Required
Yes
Description

Declares information for rendering the custom content in the UI.

Declares information related for rendering the custom content in the UI.
Add-ons have the ability to control the UI components for user to view the custom content.

1
2
3
4
5
6
7
{
  "contentViewComponent": {
    "addonKey": "addon-key",
    "moduleKey": "general-page-module-key"
  }
}

View component example

Suppose we already defined a general page module like following:

1
2
3
4
5
6
7
8
{
  "url": "/my-general-page?content.plugin={content.plugin}&content.id={content.id}&content.version={content.version}&space.key={space.key}&customParameter={ac.customData}",
  "name": {
    "value": "My viewer page"
  },
  "key": "my-viewer"
}

And also the general page is used as a view component in ui support section.

1
2
3
4
5
6
{
  "contentViewComponent": {
    "moduleKey": "my-viewer"
  }
}

When a user clicks the title of the corresponding custom content in the search result. /my-general-page will be rendered in a iframe with following context parameters being passed.

  • content.plugin: The content type key of the content. eg: ac:addon-key:module-key
  • content.id: The id of the content
  • content.version: The version of the content
  • space.key: The key of the space which content is contained in
Note, that if an optional custom value is defined in the url string, such as {ac.customData} in the example above, it will be substituted with the value of the ac.customData parameter that will be taken from the Confluence's current URL. Add-on developers can specify any number of custom parameters, provided that they have names that follow this convention: ac.parameter_name. If more than one custom parameter with the same name is defined in Confluence's current URL, only the first value will be used. For additional information on custom parameters see Context Parameters.

Context Parameters

View components support Confluence context parameters. When rendering the view component the context variables will be passed to the URL that is defined in the corresponding view component module.
You can retrieve the content or space information with these parameters via Confluence REST API and render it according to your needs.
Please consult Context Parameters for what parameters are currently supported.

Properties

contentViewComponent
Type
Required
Yes
Description

Defines a module for viewing custom content.
The module referenced must be a generalPage.

The view component is displayed in these places:

  • Search result
    When a user clicks the title of a custom content entry in site search result.
  • Space List View result
    When a user clicks the title of a custom content entry in the space list view.
  • Page List View result
    When a user clicks the title of a custom content entry in the page list view.

A reference to a module defined in either this or another add-on

1
2
3
4
5
{
  "addonKey": "addon-key",
  "moduleKey": "general-page-module-key"
}
icons
Type
Required
Yes
Description

Defines icons used for displaying the content.

Defines icons that used for displaying the custom content.

1
2
3
4
5
6
7
8
{
  "item": {
    "width": 16,
    "height": 16,
    "url": "/item.png"
  }
}
breadcrumbs
Type
Description

Defines the breadcrumbs used in

  • Result of quick search dropdown
  • Result of site search

Defines the breadcrumbs for this content

Use Relation API to generate breadcrumbs

An add-on can specify multiple content relationships for generating the breadcrumbs. Suppose we have ac:add-on-key:employee defined with following breadcrumbs setting:
1
2
3
4
5
6
7
8
9
10
11

 ...
 "breadcrumbs": {
   "relations": [
     {
       "name": "worksFor"
     }
   ]
 }
 ...
 

And we have following custom content created in the Confluence:

Example custom content for building search breadcrumbs
Content IDContent TypeTitle
1ac:add-on-key:organizationCompany A
2ac:add-on-key:organizationCompany B
3ac:add-on-key:employeeCharlie

By using the Relation API we can create following relations between these content:

  • Charlie works for Company A: PUT /rest/relation/worksFor/from/content/3/to/content/1
  • Charlie works for Company B: PUT /rest/relation/worksFor/from/content/3/to/content/2

Since we have let ac:add-on-key:employee to use worksFor relation to generate the breadcrumbs. Confluence will fetch the relations that were created under name worksFor, then display the titles in the creation order of their relations in the search result like this: Quick search breadcrumbs

Similarly the site search will display the breadcrumbs as well: Quick search breadcrumbs

editComponent
Type
Description

Defines a module for adding or editing custom content.
The module referenced must be a generalPage. Following context variable will be provided to the edit component URL

  • customcontent.create: Indicates whether user is creating or editing a piece of custom content
Please consult Context Parameters for how to use a context variable.

Confluence will provide the breadcrumbs, title input, submit and cancel button on the edit component. Add-on needs to supply the editor area like the screenshot shown below in a general page module.
Please refer to the Custom Content JavaScript API for how to intercept the edit component events and override the default behavior.

Custom Content Edit Component

A reference to a module defined in either this or another add-on

1
2
3
4
5
{
  "addonKey": "addon-key",
  "moduleKey": "general-page-module-key"
}
editComponentCancelButtonLabel
Type
Description

Defines the label for cancel button on edit component

Represents a string that can be resolved via a localization properties file. You can use the same i18n Property key and value in multiple places if you like, but identical keys must have identical values.

Example

1
2
3
4
{
  "value": "My text"
}
editComponentSubmitButtonLabel
Type
Description

Defines the label for submit button on edit component

Represents a string that can be resolved via a localization properties file. You can use the same i18n Property key and value in multiple places if you like, but identical keys must have identical values.

Example

1
2
3
4
{
  "value": "My text"
}
editComponentTitlePlaceholder
Type
Description

Defines a placeholder for title input box that will be used in the edit component. Following variables will be replaced at runtime:

  • {spaceName}: Name of the current space
  • {spaceKey}: Key of the current space
  • {contentTypeName}: Name of the current custom content

For example:
"What do you want to know about {SpaceName}" will become "What do you want to know about Demonstration Space" if user is creating a new piece of custom content in "Demonstration Space" space.

Represents a string that can be resolved via a localization properties file. You can use the same i18n Property key and value in multiple places if you like, but identical keys must have identical values.

Example

1
2
3
4
{
  "value": "My text"
}
listViewComponent
Type
Description

Defines a module that will be used when a user clicks the navigation link displayed in the space sidebar.
The module referenced must be a generalPage. A default list view will be provided if no view component was specified in this field.

A reference to a module defined in either this or another add-on

1
2
3
4
5
{
  "addonKey": "addon-key",
  "moduleKey": "general-page-module-key"
}

description
Type
Description

The description of the custom content

Represents a string that can be resolved via a localization properties file. You can use the same i18n Property key and value in multiple places if you like, but identical keys must have identical values.

Example

1
2
3
4
{
  "value": "My text"
}

Properties

value
Type
Max length
1500
Required
Yes
Description

The human-readable default value. This will be used if no translation exists. Only the following HTML tags are supported: b, i, strong, em, and code.

i18n
Type
Max length
300
Description

The localization key for the human-readable value. Translations for the keys are defined at the top level of the add-on descriptor.


Rate this page: