Rate this page:
This tutorial describes how to make API calls to an external API from your Forge app and display the result on a Confluence Cloud page. You’ll use the GIPHY API to display GIFs on the Confluence page. The result will look like this:
To complete this tutorial, you need the following:
npm install -g @forge/cli@latest
on the command line.npm install @forge/ui@latest --save
on the command line.npm install @forge/api@latest
on the command line.See Set up Forge for step by step instructions. We recommend that you complete all the steps in Getting started so that you’re familiar with the Forge development process.
Before we dive into the code, let's review how this app works.
The flow diagram shows the app’s 3 main parts.
These parts work together as follows:
Create an app based on the Hello world TypeScript template.
Create your app by running:
1
forge create
Open the app directory to see the app files.
This app uses a Confluence macro
module. Macros enable you to add functionality or include dynamic
content in a Confluence page.
manifest.yml
file.key
under macro
to giphy.title
under macro
to GIPHY.description
under macro
to View random GIPHY gifs![]
, an empty array.Your manifest file should look like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
permissions:
scopes: []
modules:
macro:
- key: giphy
function: main
title: GIPHY
description: View random GIPHY gifs!
function:
- key: main
handler: index.run
app:
id: '<your-app-id>'
name: giphy-app
See Manifest to learn more about the manifest file.
Add UI kit components that render when the app is called. You’ll use a sample response from the GIPHY API to make a static app (steps 1 and 3 from the flow diagram above).
src/index.tsx
file.Replace the contents of the file with:
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
// Import required components from the UI kit
import ForgeUI, { render, Text, Fragment, Image } from '@forge/ui';
// ImageCardProps interface which will be used by ImageCard component
interface ImageCardProps {
title: string;
src: string;
}
// ImageCard component containing text and image
const ImageCard = ({title, src}: ImageCardProps) => (
<Fragment>
<Text>{title}</Tect>
<Image src={src} alt={title}/>
</Fragment>
);
// App function will return the final output
const App = () => {
const {title, url} = {
title: "awesome avalanche GIF",
url: "https://media3.giphy.com/media/26vUJR5VABcUJaCTm/200.gif?cid=74f3ab6481fcd606c80e02418b301c17130050edc03b7521&rid=200.gif"
};
return (
<Fragment>
<Text>Random GIF!</Text>
<ImageCard src={url} title={title}/>
</Fragment>
);
};
// Exporting the above App function by exporting via 'run'
export const run = render(<App/>);
In this code:
Fragment
, Image
to display the GIF.
See UI kit components to learn more about these components.ImageCardProps
interface contains
title
and src
, which are used by the component ImageCard
. title
comes from the GIPHY API
response. src
is the URL and fixed height of the GIF.ImageCard
consists of a Fragment
, which contains a Text
component and an Image
component.App
function is where the GIPHY API call is linked to the components of the user interface.
This function returns a Fragment
that contains a Text
component and an ImageCard
component.
The code has values for a GIF. Later in this tutorial, you’ll update this to make a call to get
a random GIF. The sample response from GIPHY for obtaining a GIF by ID has the information you’ll use for title
and src
in ImageCard
.run
constant provides the mechanism that renders your app whenever the App
function returns.Build, deploy, and install the app to see it in your Confluence site.
In the app's top-level directory, deploy your app by running:
1
forge deploy
Install your app by running:
1
forge install
Edit a Confluence page and insert the app using the quick insert menu (activated by pressing /), as shown below.
Next, turn the static app into a dynamic app by replacing the hardcoded response with an API call (step 2 from the flow diagram above). You’ll speed up your development process by starting a tunnel, which uses the local code where your app is installed. You need to set the GIPHY API key as a local variable so your code can access it when making calls to the GIPHY API.
Start a tunnel with access to your GIPHY API key by running:
1
FORGE_USER_VAR_GIPHY_API_KEY=<your-giphy-api-key> forge tunnel
Open the src/index.txs
file.
Add the following code directly after the import statement to call the GIPHY API:
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
import api from "@forge/api";
// GIPHY API base URL
const GIPHY_API_BASE = 'https://api.giphy.com/v1/gifs/';
// GiphyJson interface to be used by our getRandomGif function
interface GiphyJson {
title: string;
url: string;
}
// getRandomGif function makes the GIPHY API call to get a random GIF and filter out title and url
const getRandomGif = async (): Promise<GiphyJson> => {
console.log("Making GIPHY API call...")
const response = await api.fetch(
`${GIPHY_API_BASE}random?api_key=${process.env.GIPHY_API_KEY}&rating=g`,
);
const {
data: {
title,
images: {
fixed_height: { url },
},
},
} = await response.json();
return {
title,
url,
};
};
In this code:
GIPHY_API_BASE
is a constant containing the URL to call the GIPHY API.GiphyJson
interface has title
and url
properties for the ImageCard
.getRandomGif
is an asynchronous function that makes the API call and returns the result in
the format of GiphyJson
.fetch
from the Runtime API makes a call to GIPHY’s random endpoint
and stores the response. This function uses the GIPHY API key from your environment variables
with process.env.GIPHY_API_KEY
.Add the UI kit hook useAction
to the import statement from @forge/ui
.
const { title, url }
and its value in the App
function with the following to update
the state:1
const [{ title, url }, setRandomGif] = useAction(getRandomGif, getRandomGif);
useAction
defines how to update the state, and the second parameter
is the initial value.
useAction
returns the current value, and a function you can call to update the value.Your index.tsx
file should look like this:
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 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
// Importing required components from the UI kit
import ForgeUI, { render, Text, Fragment, Image, useAction } from '@forge/ui';
// Importing the api object
import api from "@forge/api";
// GIPHY API base URL
const GIPHY_API_BASE = 'https://api.giphy.com/v1/gifs/';
// GiphyJson interface to be used by our getRandomGif function
interface GiphyJson {
title: string;
url: string;
}
// getRandomGif function makes the GIPHY API call to get a random GIF and filter out title and url
const getRandomGif = async (): Promise<GiphyJson> => {
console.log("Making GIPHY API call...")
const response = await api.fetch(
`${GIPHY_API_BASE}random?api_key=${process.env.GIPHY_API_KEY}&rating=g`,
);
const {
data: {
title,
images: {
fixed_height: { url },
},
},
} = await response.json();
return {
title,
url,
};
};
// ImageCardProps interface which will be used by ImageCard component
interface ImageCardProps {
title: string;
src: string;
}
// ImageCard component containing text and image
const ImageCard = ({title, src}: ImageCardProps) => (
<Fragment>
<Text>{title}</Text>
<Image src={src} alt={title}/>
</Fragment>
);
// App function will return the final output
const App = () => {
const [{ title, url }, setRandomGif] = useAction(getRandomGif, getRandomGif);
return (
<Fragment>
<Text>Random GIF!</Text>
<ImageCard src={url} title={title}/>
</Fragment>
);
};
// Exporting the above App function by exporting via 'run'
export const run = render(<App/>);
When you refresh the page in Confluence, a random GIF is displayed.
Instead of refreshing the page, add a button to load a new GIF. This will use the Button
component
from the UI kit.
src/index.tsx
file.Button
to the UI kit import statement.App
function with:1 2 3 4 5 6 7 8 9 10 11 12
return (
<Fragment>
<Text>Random GIF!</Text>
<ImageCard src={url} title={title} />
<Button
text="🔀 Shuffle!"
onClick={() => {
setRandomGif();
}}
/>
</Fragment>
);
Your index.tsx
file should look like this:
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 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
// Importing required components from the UI kit
import ForgeUI, { render, Text, Fragment, Image, useAction, Button } from '@forge/ui';
// Importing the api object
import api from "@forge/api";
// GIPHY API base URL
const GIPHY_API_BASE = 'https://api.giphy.com/v1/gifs/';
// GiphyJson interface to be used by our getRandomGif function
interface GiphyJson {
title: string;
url: string;
}
// getRandomGif function makes the GIPHY API call to get a random GIF and filter out title and url
const getRandomGif = async (): Promise<GiphyJson> => {
console.log("Making GIPHY API call...")
const response = await api.fetch(
`${GIPHY_API_BASE}random?api_key=${process.env.GIPHY_API_KEY}&rating=g`,
);
const {
data: {
title,
images: {
fixed_height: { url },
},
},
} = await response.json();
return {
title,
url,
};
};
// ImageCardProps interface which will be used by ImageCard component
interface ImageCardProps {
title: string;
src: string;
}
// ImageCard component containing text and image
const ImageCard = ({title, src}: ImageCardProps) => (
<Fragment>
<Text>{title}</Text>
<Image src={src} alt={title}/>
</Fragment>
);
// App function will return the final output
const App = () => {
const [{ title, url }, setRandomGif] = useAction(getRandomGif, getRandomGif);
return (
<Fragment>
<Text>Random GIF!</Text>
<ImageCard src={url} title={title} />
<Button
text="🔀 Shuffle!"
onClick={() => {
setRandomGif();
}}
/>
</Fragment>
);
};
// Exporting the above App function by exporting via 'run'
export const run = render(<App/>);
Now you can use the button to display a new GIF.
Now that the code is working, set your app environment variable and deploy the app so it keeps working after you close the tunnel.
Store the GIPHY API key in your app environment variables by running:
1
forge variables:set GIPHY_API_KEY <your-giphy-api-key>
Deploy the app by running:
1
forge deploy
That’s it. You now have an app that fetches data from an external API and renders the result in the Confluence editor.
Continue to one of the other tutorials or look through the reference pages to learn more.
Rate this page: