Last updated Sep 11, 2023

Rate this page:

Build a custom UI app in Jira Service Management

Tunneling with custom UI apps is only supported on Chrome and Firefox browsers.

This tutorial walks through creating a Forge app to display content on the queues page of Jira Service Management. Using custom UI, you can define your own user interface using static resources, such as HTML, CSS, JavaScript, and images. The Forge platform hosts your static resources, enabling your app to display custom UI on Atlassian products. Custom UI apps inherit modern security features to ensure high trust between Atlassian, developers, and users.

At the end of this tutorial, you’ll have created a Forge app in Jira Service Management that uses custom UI to display customized UI content.

When you create a new app, Forge will prompt you to set a default environment. In this tutorial we use the development environment as our default. See Default environments for more information.

Forge also provides a staging and production environments where you can deploy your app. See Environments and versions for more information.

Before you begin

This tutorial assumes you're already familiar with developing on Forge. If this is your first time using Forge, see Getting started for step-by-step instructions on setting up Forge.

To complete this tutorial, you need the following:

  • The Forge CLI (latest version). To update your CLI version, run npm install -g @forge/cli@latest on the command line.
  • An Atlassian cloud site with Jira Service management where you can install your app. You need to be an admin on the site to install the app.
Forge apps can't be viewed by anonymous users. To use a Forge app, you must be logged in to Jira Service Management.

Create your app

This app displays custom content in the Queues page of a Jira Service Management using custom UI.

  1. Navigate to the directory where you want to create the app. A new directory with the app’s name will be created there.

  2. Create your app by running:

    forge create
  3. Enter a name for your app. For example, hello-world-custom-ui.

  4. Select the Custom UI category.

  5. Select the jira-service-management-queue-page template.

  6. Change to the app subdirectory to see the app files.

    cd hello-world-custom-ui

Jira Service Management queuepage custom UI template

The jira-service-management-queuepage-custom-ui template has React JS for the static frontend and Node JS for the FaaS backend. The template contains the following structure:

|-- src
|   `-- index.js
|-- static
|   `-- hello-world
|       `-- src
|           `-- index.js
|           `-- App.js
|       `-- public
|           `-- index.html
|       `-- package.json
|       `-- package-lock.json
|-- manifest.yml
|-- package.json
|-- package-lock.json

Let’s have a look at what these files are:

Change the panel title

This app displays content in a Jira Service Management project's Queues section using the jiraServiceManagement:queuePage module. Jira Service Management shows the title of the jiraServiceManagement:queuePage as the page's heading. Let's change the title to include your name.

  1. In the app’s top-level directory, open the manifest.yml file.
  2. Find the title entry under the jiraServiceManagement:queuePage module.
  3. Change the value of title from hello-world-app to Hello World from <your name>. For example, Hello World from Emma Richards.

Your manifest.yml file should look like the following, with your values for the title and app ID.

    - key: hello-world-panel
      resource: main
        function: resolver
      title: Hello World from Emma Richards
    - key: resolver
      handler: index.handler
  - key: main
    path: static/hello-world/build
  id: '<your app id>'

Build the content for your custom UI

In this template, we're using create-react-app to generate the static content that your app will be using. This library is generally used to create new single-page React applications. We'll use the library to generate a simple Hello, world! message in a Jira Service Management Queue page by serving a single-page React app.

You need to install and build these resources so your app can use them. Follow these steps to build the resources for your app:

  1. Navigate to the static/hello-world directory.

  2. Install the needed dependencies:

    npm install
  3. Build the assets:

    npm run build
  4. Navigate back to the top-level directory of your app.

Deploy and install your app

Any time you make changes to your app code, rebuild the static frontend as prescribed above and then run a deploy using the forge deploy command. This command compiles your FaaS code, and deploys your functions and static assets to the Atlassian cloud.

To install your app on a new site, run the forge install command. Once the app is installed on a site, it will automatically pick up all minor app deployments, which means you don't need to run the install command again. A minor deployment includes any change that doesn't modify app permissions in the manifest.

  1. Navigate to the app's top-level directory and deploy your app by running:

    forge deploy
  2. Install your app by running:

    forge install
  3. Select your Atlassian product using the arrow keys and press the enter key.

  4. Enter the URL for your development site. For example, View a list of your active sites at Atlassian administration.

Once the successful installation message appears, your app is installed and ready to use on the specified site. You can always delete your app from the site by running the forge uninstall command.

Running the forge install command only installs your app onto the selected product. To install onto multiple products, repeat these steps again, selecting another product each time. Note that the Atlassian Marketplace does not support cross-product apps yet.

You must run forge deploy before running forge install in any of the Forge environments.

View your app

With your app installed, it’s time to see the app in the Queues section.

  1. Create a new Jira Service Management Project.
  2. View the app you created in the Queues section of the JSM project.

The app should display on the page with the content of your custom UI, like the image below.

A Jira Service Management Queue page displaying a custom UI forge app

While your app is deployed to either a development or staging environment, `(DEVELOPMENT)` or `(STAGING)` will appear in your app title. This suffix is removed once you've [deployed your app to production](/platform/forge/staging-and-production-apps/#environments).

Modify the content of your custom UI

By now, you can now see your app displaying the message Hello, world! in the Jira Service Management Queues page. This is the product of setting up your static assets and using a resolver function to dynamically generate the message.

Modify the static assets for the frontend

Follow these steps to modify the static assets:

  1. Navigate to the static/hello-world/src directory.

  2. Open the App.js file. The default content of the file is shown below.

    import React, { useEffect, useState } from 'react';
    import { invoke } from '@forge/bridge';
    function App() {
     const [data, setData] = useState(null);
     useEffect(() => {
       invoke('getText', { example: 'my-invoke-variable' }).then(setData);
     }, []);
     return (
         {data ? data : 'Loading...'}
    export default App;
  3. Modify the content of the file.

  4. Rebuild the static assets for your custom UI frontend by running the npm run build command from the static/hello-world directory.

  5. Navigate to the app's top-level directory and start a tunnel for your app by running:

    forge tunnel

    You can see your changes by refreshing the page that your app is on.

  6. Redeploy your app by running the forge deploy command.

Modify the FaaS backend resolver

Follow these steps to modify the value of the message returned by your FaaS backend resolver:

  1. Navigate to the src directory.

  2. Open the index.js file. The default content of the file is shown below.

    import Resolver from '@forge/resolver';
    const resolver = new Resolver();
    resolver.define('getText', (req) => {
     return 'Hello, world!';
    export const handler = resolver.getDefinitions();
  3. Modify the content of the file.

  4. Navigate to the app's top-level directory and start a tunnel for your app by running:

    forge tunnel

    You can see your changes by refreshing the page that your app is on.

  5. Redeploy your app by running the forge deploy command.

Next steps

You now know enough to develop your own Forge apps. Continue on to our tutorials, explore the example apps, or look through the reference pages to learn more.

Rate this page: