Is there a way I can have an 'init' function in a Forge app?

I am creating an experimental confluence app with forge where multiple components on multiple pages within a space have to interact. They will exchange (limited amounts of) data via the storage API.

It would be nice if I can somehow have a function run when the app loads for the first time. That way, I can have a single place where I make sure some basics are set up in app storage. As it is now, every component render function calls a ‘storage init’ function which checks if init is necessary, but it is still overkill.

Is such a ‘app-global’ init function possible?

Hi @GerbenWierda ,

When you say “when the app loads for the first time”, I think it might be more appropriate to think in terms of a per-tenant context here so you should be able to register for installation events. Here is some code to get you started:


    - key: forge-install-event-demo-hello-world
      function: main
      title: Forge Install Event Demo
      description: Forge Install Event Demo
    - key: my-installation-handler
        - avi:forge:installed:app
      function: installation-func
    - key: main
    - key: installation-func
      handler: index.onInstallation
  id: ari:cloud:ecosystem::app/...


import ForgeUI, { render, Fragment, Macro, Text } from "@forge/ui";

const App = () => {
  return (
      <Text>Hello world!</Text>

export const run = render(
    app={<App />}

export const onInstallation = (event) => {
  console.log(`Oh wow, I've been installed:`);

Also see the Lifecycle events documentation.


1 Like

I do not get events when I try this.

    - key: dl-spike-one-trigger-appinstalled
      function: dl-trigger-appinstalled
        - avi:forge:installed:app
        - avi:forge:upgraded:app

    - key: dl-trigger-appinstalled
      handler: index.dl_handleTriggerAppInstalled

    - read:confluence-content.summary
    - read:confluence-content.all
    - read:page:confluence
    - storage:app
    - read:space:confluence

export async function dl_handleTriggerAppInstalled( event, context) {
  console.log( `dl_handleTriggerAppInstalled`);
  console.log(`All info about my context: ${JSON.stringify(context, null, 2)}`);
  console.log(`All info about my event: ${JSON.stringify(event, null, 2)}`);

Not on logging in and loading anything from a space for the first time (which is what I am looking for and which I don't think this does), nor on `forge deploy` and `forge install --upgrade`

My app uses storage and before any component does anything (rendering, macro config) I want to run some logic to make sure the data in Storage is OK. A I understand it, the app storage scope is per-space, so I need an event per-space.

Hi @GerbenWierda ,

I tested my app and did get the avi:forge:installed:app event after the app was installed in a site since I was able to see my console.log(Oh wow, I’ve been installed:) log after installing by running forge logs. Did you try testing if you get the avi:forge:installed:app event after running forge install rather than forge install --upgrade?

The app gets storage scoped to it’s installation rather than a separate storage area per space.


Indeed. I had to uninstall/install the app to see these console messages. I had expected forge install -upgrade to have the same effect.

Thank you.

By the way, the event part of the result of that trigger is funny when printed via JSON.stringify. Fragment:

INFO    2023-03-23T09:39:45.923Z babd3d21-bb5a-4b13-851d-dbbe21c597a1 All info about my event: {
  "id": "e8e95feb-77de-44e8-84f7-76013a45e564",
  "context": {
    "0": "a",
    "1": "r",
    "2": "i",
    "3": ":",
    "4": "c",
    "5": "l",
    "6": "o",
    "7": "u",
    "8": "d",
    "9": ":",
    "10": "c",
    "11": "o",
    "12": "n",
    "13": "f",
    "14": "l",
    "15": "u",
    "16": "e",
    "17": "n",
    "18": "c",
    "19": "e",
    "20": ":",
    "21": ":",
    "22": "s",
    "23": "i",
    "24": "t",
    "25": "e",
    "26": "/",
    "27": "f",
    "28": "a",
    "29": "4",
    etc. ...

What I also found surprising was that Storage survived an app uninstall/install cycle.

Hey @GerbenWierda ,
regarding the persistence of Storage after app uninstall see this answer: How do I delete all forge storage data for an instance - #2 by rmassaioli

I already have this function triggered by a button:

const deleteAppStorage = async () => {
  console.log( `deleteAppStorage`);
  const myDict = await storage.query()
        .limit( 20)
//  console.log(`deleteAppStorage: All info about my storage: ${JSON.stringify(myDict, null, 2)}`);
  myDict.results.forEach(function (i) { console.log(`deleting ${i.key}`); storage.delete(i.key);});
  console.log( `deleteAppStorage will return`);

This one deletes up to 20 entries (I do not have that much) but could be extended to a loop that runs until the query returns nothing anymore.