The full page module allows you to create fully customized app experiences that occupy the entire web page, providing ample space to deliver UI for a broader range of use cases, such as specialized content views or internal tools that reflect your own branding.
This tutorial will walk you through creating a Forge app for Confluence using the full page module that displays a dashboard with interactive charts and user information. You'll learn how to configure the manifest, build the frontend using either UI Kit or Custom UI, integrate with Confluence APIs, and deploy your app.
At the end of this tutorial, you'll have created an app using the full page module that displays:
It is currently available as Confluence full page module, in both UI Kit and Custom UI.
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.forge create and select the confluence-global-page template.Update your manifest.yml to add the confluence:fullPage module. The key differences from confluence:globalPage are:
confluence:globalPage with confluence:fullPageroute with routePrefixtitle is optional for the full page modulerender: native is setYour manifest.yml should look like the following:
1 2modules: confluence:fullPage: - key: my-full-page-module resource: main render: native resolver: function: resolver routePrefix: ui-kit title: My full page module # Optional function: - key: resolver handler: index.handler resources: - key: main path: src/frontend/index.jsx app: id: "<your app id>" runtime: name: nodejs22.x permissions: scopes: - read:confluence-user
Add the following code into the frontend file of your app.
Place this code inside the file src/frontend/index.jsx.
1 2import React, { useState, useEffect } from "react"; import ForgeReconciler, { Box, Stack, Heading, Text, BarChart, Button, Inline, Image, xcss } from "@forge/react"; import { requestConfluence } from "@forge/bridge"; const chartContainerStyle = xcss({ maxWidth: "600px", }); const App = () => { const [selectedPeriod, setSelectedPeriod] = useState("Q1"); const [userInfo, setUserInfo] = useState(null); const [loading, setLoading] = useState(false); const [error, setError] = useState(null); // Dashboard usage data for different periods const q1Data = [ { month: 'Jan', usage: 45 }, { month: 'Feb', usage: 52 }, { month: 'Mar', usage: 48 }, ]; const q2Data = [ { month: 'Apr', usage: 61 }, { month: 'May', usage: 55 }, { month: 'Jun', usage: 67 }, ]; const chartData = selectedPeriod === "Q1" ? q1Data : q2Data; // Fetch current user information from Confluence API const fetchUserInfo = async () => { setLoading(true); setError(null); try { const response = await requestConfluence('/wiki/rest/api/user/current'); if (!response.ok) { const errorText = await response.text(); throw new Error(`API error: ${response.status} - ${errorText}`); } const data = await response.json(); setUserInfo(data); } catch (err) { setError(`Failed to fetch user info: ${err.message}`); console.error(err); } finally { setLoading(false); } }; useEffect(() => { fetchUserInfo(); }, []); return ( <Box padding="space.400"> <Stack space="space.400"> <Stack space="space.200"> <Heading size="xlarge">Dashboard</Heading> <Text>Monthly usage overview</Text> </Stack> <Inline space="space.200"> <Button appearance={selectedPeriod === "Q1" ? "primary" : "default"} onClick={() => setSelectedPeriod("Q1")} > Q1 </Button> <Button appearance={selectedPeriod === "Q2" ? "primary" : "default"} onClick={() => setSelectedPeriod("Q2")} > Q2 </Button> </Inline> <Stack space="space.300"> <Box xcss={chartContainerStyle}> <BarChart data={chartData} xAccessor="month" yAccessor="usage" /> </Box> <Box padding="space.200"> <Stack space="space.100"> <Text>Current period: {selectedPeriod}</Text> <Text>Total usage: {chartData.reduce((sum, item) => sum + item.usage, 0)}</Text> </Stack> </Box> </Stack> <Box padding="space.400"> <Stack space="space.300"> <Heading size="medium">Current User Information</Heading> {loading && <Text>Loading user info...</Text>} {error && <Text>{error}</Text>} {!loading && !error && userInfo && ( <Box padding="space.300" xcss={xcss({ borderWidth: "border.width", borderStyle: "solid", borderColor: "color.border", borderRadius: "border.radius.300", })}> <Stack space="space.200"> <Text> <Text weight="bold">Name:</Text> {userInfo.displayName} </Text> {userInfo.email && ( <Text> <Text weight="bold">Email:</Text> {userInfo.email} </Text> )} {userInfo.accountId && ( <Text> <Text weight="bold">Account ID:</Text> {userInfo.accountId} </Text> )} {userInfo.profilePicture && ( <Box padding="space.200"> <Image src={userInfo.profilePicture.path} alt="Profile" width="48px" height="48px" /> </Box> )} </Stack> </Box> )} </Stack> </Box> </Stack> </Box> ); }; ForgeReconciler.render( <React.StrictMode> <App /> </React.StrictMode> );
API permissions: Both UI Kit and Custom UI examples use requestConfluence to fetch the current user's information. Make sure your manifest.yml includes the required scope:
1 2permissions: scopes: - read:confluence-user
Note: When using requestConfluence from Custom UI or UI Kit, classic scopes (like read:confluence-user) are recommended over granular scopes for better compatibility.
You'll need to redeploy and reinstall your app with forge install -upgrade after adding scopes.
If you are using UI Kit, 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.
If you are using Custom UI, each time you run the forge deploy command, make sure you navigate to static/hello-world
and run npm run build beforehand.
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 context 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.
Install/upgrade: Run forge install --upgrade if you've changed permissions
Installing to different environments: To deploy your app to a different environment, use the -e flag to specify the environment.
For example, the following command will deploy to production environment: forge deploy -e production.
If you encounter errors during testing, check the browser console for detailed error messages and refer to the Troubleshooting section below.
Full page modules can be accessed using this URL format:
1 2https://<your-site>.atlassian.net/forge-apps/a/<app-id>/e/<forge-environment-id>/r/<route-prefix>/<app-route>
Where to find each value:
<your-site>: Your Confluence site name<app-id>: The UUID from your app.id in manifest.yml (if in ARI format like ari:cloud:ecosystem::app/UUID, use only the UUID section)<forge-environment-id>: The UUID of the environment that the app is installed on.
Not required for accessing apps installed on production.
If omitting, you will need to omit the /e/<forge-environment-id> section entirely.
For apps installed on other environments, run forge environments list to find the UUID of the desired environment.<route-prefix>: Defined in your manifest under confluence:fullPage → routePrefix<app-route>: Optional - if your app code contains routing, it will appear under the <app-route> section of the URL.Example (with environment ID):
1 2https://example.atlassian.net/forge-apps/a/21e590df-79e6-40dd-9ee4-ba2c7b678f26/e/9f699e8b-33f1-4fa7-bd48-c5fdc44fa4c2/r/ui-kit
Example (production, without environment ID):
1 2https://example.atlassian.net/forge-apps/a/21e590df-79e6-40dd-9ee4-ba2c7b678f26/r/ui-kit
| Issue | Solution |
|---|---|
| The route is displaying a blank screen instead of my app |
|
The app is displaying the error: You don't have sufficient permissions to load this app. |
|
The app is displaying the error: An error has occurred in loading this app. |
|
The command forge deploy is throwing an error for confluence:fullPage. |
|
| I can't find my app's route URL |
|
Rate this page: