Configuration allows you to customize what the macro displays by adjusting settings in a form. To access these settings, you need to go into the edit mode for the macro, as demonstrated below. This gives you the ability to customize the macro's output according to your preferences.
Make sure you have the following:
npm install -g @forge/cli@latest
on the command line.npm install @forge/react@latest --save
on the command line.In this tutorial, we will add fun facts about pets which are passed through configuration we create.
We recommend you to change the values as listed in the below manifest.yml
file.
To add configuration to the Confluence macro module:
manifest.yml
file.config
property with the value set to true
.After doing this, your manifest.yml
should look like the following, with your own values
for each of the properties.
1 2modules: macro: - key: pet-facts resource: main render: native resolver: function: resolver title: Pet config: true function: - key: resolver handler: index.handler resources: - key: main path: src/frontend/index.jsx app: id: "<your app id>"
We recommend clearing the src/frontend/index.jsx
file and replacing it with the provided code
for error-free results.
You can create a new function component that will return the configuration(Config) components. The config components must be selected from the following list:
Configuration is stored in key-value pairs corresponding to each form component.
src/frontend/index.jsx
file, create a function component that constructs
the configuration of the UI Kit components you're using:1 2import React from 'react'; import { Textfield } from '@forge/react'; const Config = () => { return ( <Textfield name="age" label="Pet age" /> ); };
src/frontend/index.jsx
file, call the addConfig
method on ForgeReconciler
with your config element. Ensure you have ForgeReconciler
imported at the top.1 2import React from 'react'; import ForgeReconciler, { Textfield } from '@forge/react'; const Config = () => { return ( <Textfield name="age" label="Pet age" /> ); }; ForgeReconciler.addConfig(<Config />);
Use config to store general data, but not sensitive information. The config data is stored in plaintext, so other users and apps can access and modify the values.
You access the config for a macro in your app code with the
getContext method. When this method resolves,
it returns the product context, which will include the key-value pairs set in the config.
The key is the name
property on the form component in configuration, and the value is what the user enters.
In your src/frontend/index.jsx
file:
useState
and useEffect
.1 2import React, { useState, useEffect } from 'react'; // useState: Adds and updates local state to a component. // useEffect: Executes a specific function whenever any value in its dependency array (the second argument of the hook) changes.
view
from @forge/bridge
in your app code.1 2import { view } from '@forge/bridge';
Text
and Textfield
components.1 2import ForgeReconciler, { Text, Textfield } from '@forge/react';
App
and call the getContext
method in the useEffect
.1 2const Config = () => { ... }; const App = () => { const [context, setContext] = useState(undefined); useEffect(() => { view.getContext().then(setContext); }, []); return ( <> <Text>Hello World</Text> </> ); };
age
to the return statement.1 2const App = () => { ... const config = context?.extension.config; const age = config?.age; return ( <> <Text>Hello World</Text> <Text> {age || 'Fetching config...'} </Text> </> ); }
The index.jsx
file should look like this:
1 2import React, { useState, useEffect } from 'react'; import ForgeReconciler, { Text, Textfield } from '@forge/react'; import { view } from '@forge/bridge'; const Config = () => { return ( <> <Textfield name="age" label="Pet age" /> </> ); }; const App = () => { const [context, setContext] = useState(undefined); useEffect(() => { view.getContext().then(setContext); }, []); const config = context?.extension.config; const age = config?.age; return ( <> <Text>Hello World</Text> <Text> {age || 'Fetching config...'} </Text> </> ); }; ForgeReconciler.render( <React.StrictMode> <App /> </React.StrictMode> ); ForgeReconciler.addConfig(<Config />)
We recommend you add sensible defaults for each of your configuration values.
If it's more sensible for the macro to not have default configuration values, we recommend you display a section message with the appropriate instructions, as shown below:
1 2import ForgeReconciler, { Text, Textfield, SectionMessage } from '@forge/react'; //Add SectionMessage to the import statement <SectionMessage title="You need to configure this macro" appearance="warning"> <Text> While editing the page, select the macro, and click on the pencil icon to display configuration options. </Text> </SectionMessage>
You can also add a state to only display the section message if the macro has not already been configured; otherwise, it will always show on the macro.
In this example, by default, the macro displays Unnamed Pet is 0 years old.
Create a default configuration for the pet's name and age, and then
add defaultConfig
variable to const config = context?.extension.config
In your src/frontend/index.jsx
file outside the Config
and App
components, add:
1 2const defaultConfig = { name: 'Unnamed Pet', age: '0' };
Then replace the const config
inside the App
component with the following:
1 2const config = context?.extension.config || defaultConfig;
Now that we have created configurations (name
and age
) for your macro, we can now enhance
this feature to include dynamic input for the pet's name and age.
For example, if a user submits the name Fluffy and age 2, the macro displays Fluffy is 2 years old.
In your index.jsx
file:
1 2const Config = () => { return ( <> <Textfield name="name" label="Pet name" defaultValue={defaultConfig.name} /> <Textfield name="age" label="Pet age" defaultValue={defaultConfig.age} /> </> ); };
In the return
statement of the App
component:
Replace
1 2<Text>Hello World</Text> <Text> {age || 'Fetching config...'} </Text>
with
1 2return ( <Text>{config.name} is {config.age} years old.</Text> );
Your main file containing the application's root component (here index.jsx
) should look like this:
1 2import React, { useEffect, useState } from 'react'; import ForgeReconciler, { Textfield, Text, SectionMessage } from '@forge/react'; import { view } from '@forge/bridge' const defaultConfig = { name: 'Unnamed Pet', age: '0' }; // Function that defines the configuration UI for the pet's name and age const Config = () => { return ( <> <Textfield name="name" label="Pet name" defaultValue={defaultConfig.name} /> <Textfield name="age" label="Pet age" defaultValue={defaultConfig.age} /> </> ); }; const App = () => { const [context, setContext] = useState(undefined); // Retrieve the context useEffect(() => { view.getContext().then(setContext); }, []); const config = context?.extension.config || defaultConfig; // Displaying the pet's name and age using the configuration values. SectionMessage component is optional. return ( <> <Text>{config.name} is {config.age} years old.</Text> <SectionMessage title="You need to configure this macro" appearance="warning"> <Text> While editing the page, select the macro, and click on the pencil icon to display configuration options. </Text> </SectionMessage> </> ); }; // Adding the Config function to the ForgeReconciler to allow for configuration changes ForgeReconciler.render( <React.StrictMode> <App /> </React.StrictMode> ); ForgeReconciler.addConfig(<Config />);
If you haven't done so already, make sure you have installed the latest version of UI Kit
before you begin deploying your app. Navigate to the top-level directory of the app
and run npm install @forge/react@latest --save
on the command line.
Build, deploy, and install the app to see it in your Confluence site.
To use your app, it must be installed onto an Atlassian site. The
forge deploy
command builds, compiles, and deploys your code; it'll also report any compilation errors.
The forge install
command then installs the deployed app onto an Atlassian site with the
required API access.
You must run the forge deploy
command before forge install
because an installation
links your deployed app to an Atlassian site.
Navigate to the app's top-level directory and deploy your app by running:
1 2forge deploy
Install your app by running:
1 2forge install
Select your Atlassian product using the arrow keys and press the enter key.
Enter the URL for your development site. For example, example.atlassian.net. 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.
Pet age
, Pet name
, and then close the configuration page. The config values are saved automatically.You should now see the config values displayed within the app.
Rate this page: