Newbie Confluence plugin developer, a few answers could help me out

I am at my first steps of developing Confluence JS code to create my own plugins. Starting out I have chosen to use forge, create the forge hello-world app, and adapt that a little and that has all gone pretty easily. But after these first steps I have a few questions.

My code will read and write stuff in various pages inside a space in specific fragment (sub)types I want to create and use.

My test/learning is on Confluence Cloud, but I want to make sure the stuff runs both on Confluence Cloud and Confluence Datacenter (though the latter only much later)

My initial questions for which I haven’t been able to find documentation/introduction yet are:

  1. If I have code that runs in a certain fragment on a page, how do I get the space I am in? The context when I do this in a space called DL-dev contains a JSON entry "spaceKey": "DLDEV", is that indeed the key that enables me to find the root space of my fragment? If so, how could I have found out that this is the case, if not, how should I have found out how to solve this.
  2. I have started by using forge but in some of the documentation pages and comments I have read, I read that forge is limited. Is forge a wise choice?
  3. The hello-world app code creates aa single Fragment type, how do I create a single plugin that contains multiple Fragment types? And how should I have found out about that without bothering all of you with my newbie questions?

Hi @GerbenWierda ,

Firstly, you are asking quite broad and disparate questions which can be difficult to answer. I think it’s better to reduce the scope of each topic. Nevertheless, I’ll try to provide some help:

  1. Yes, a space key identifies a space and is used in the Confluence API. e.g. GET /wiki/rest/api/space/{spaceKey}.
  2. At this stage (March 2023) and at a very high level, Forge has a few limitations relating to back end processing, data storage and integrating with third party applications. It’s front end features (i.e. app iframes) are quite comprehensive and comparable to Connect’s iframe capabilities. We are continuing to invest in Forge so over time the limitations will reduce.
  3. I’m not sure what you mean by “fragment type”, but a Forge UI kit fragment is just a container component which can contain any other UI kit components.

Regarding your statement:

My test/learning is on Confluence Cloud, but I want to make sure the stuff runs both on Confluence Cloud and Confluence Datacenter

There are vast differences between Forge and Data Centre development, both in relation to APIs, deployment and supported languages (Javascript vs Java), such that I don’t think it is feasible to share code between the two. The only exception to this is if the apps integrated with a third party service that you developed and is common to both apps.



Ah, too bad, I want to create a functional demo of something pretty cool on top of Confluence, which should be developed in full and run on Datacenter if successful, but I cannot develop on Datacenter for now, so I have to move to cloud. That both have a complete different plugin structure is a surprise for me (newbie as I am).

This means I can only create a protoype in JS on cloud, but when the prototype works I need to do everything all over again for cloud.

Or there should be an affordable way to develop for Datacenter directly. Is there?

With the fragment type, I meant this: when I deploy my code in my development cloud Confluence, I can use it by typing / when I start with a new fragment on a page, then a popup comes up and I select my own fragment type. The hello-world app is an example for that. But how do I create a single plugin that contains multiple different elements to add to the UI?

Hi @GerbenWierda ,

I think your references to “fragment type” is what we refer to as a “macro”. Both a Forge and Connect app can define any number of macros that each might render different kinds of content. Here’s how the Forge manifest might look for an app with two macros:

    - key: macro-a
      function: macro-renderer-a
      title: Macro A
      description: Macro A bla bla
    - key: macro-b
      function: macro-renderer-b
      title: Macro B
      description: Macro B bla bla
    - key: macro-renderer-a
      handler: index.renderMacroA
    - key: macro-renderer-b
      handler: index.renderMacroB
  id: ari:cloud:ecosystem::app/xxx


I get it, I think. Expanding form the hello-world app, I get multiple run functions, the run functions (in your example e.g. renderMacroA) are called for each macro defined. Then the render function could call one or more App() functions (as it is called in the hello-world example).

Thank you. Where could I have found this so that I would not have to bother the community with this question?