Hello, were building app in jira but question is how to modify forge app to able to run locally with npm? Even if we create totally new demo hello world the app is not runnable locally on browser with npm run start.
Is there way to modify the app code so that npm is able to lounch the code locally?
Edit runnin hello world global page in static/hello world folder starts firefox but arent able to display hello world only blank page.
Uncaught Error:
Unable to establish a connection with the Custom UI bridge.
If you are trying to run your app locally, Forge apps only work in the context of Atlassian products. Refer to https://go.atlassian.com/forge-tunneling-with-custom-ui for how to tunnel when using a local development server.
BridgeAPIError errors.js:4
node_modules bundle.js:155
node_modules bundle.js:433
factory react refresh:6
Webpack 19
errors.js:4
@JeremiRoivas I know its super late now.
However, I’ve just recently started to build forge apps myself and found a workaround for running them locally (for some use cases atleast) like a normal react app.
The idea is to mock the bridge.js file. Here are the steps I had to do.
- Copy the following code to the bridge.js
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getCallBridge = void 0;
const getCallBridge = () => {
// Return a function that logs its parameters and returns a Promise that immediately resolves to `true`
return (action, payload) => {
switch (action) {
case "getContext":
return Promise.resolve({
cloudId: "",
localId:
"",
moduleKey: "extended-form-app",
siteUrl: "your-site-url",
extension: {
type: "jiraServiceManagement:portalRequestCreatePropertyPanel",
portal: { id: 1 },
request: { typeId: 34 },
issue: {id: '2223'}
},
accountId: "xxxxxx",
license: null,
timezone: "Asia/Calcutta",
locale: "en-GB",
theme: null,
});
}
return Promise.resolve(true);
};
};
exports.getCallBridge = getCallBridge;
- Remove static/your-app/node_modules/.cache folder
Now simply run npm start in your static folder and see if this app runs fine or not.
Optionally, if you want to mock your api calls as well, you can now do that as well. We just need to import mock bridge instead of the actual forge bridge. Here’s how I did it.
import { mockApi, mockAnotherApi } from "../api/mocks";
// debugBridge.ts
export const invoke = <T>(functionKey: string, payload?: any): Promise<T> => {
// Your mock implementation here
console.log(`Calling invoke with ${functionKey}`);
switch (functionKey) {
case "fetchSomething":
return new Promise<T>((resolve, reject) =>
setTimeout(() => resolve(mockApi as any as T), 2000)
);
case "fetchSomethingElse":
return new Promise<T>((resolve, reject) =>
setTimeout(() => resolve(mockAnotherApi as any as T), 2000)
);
default:
return Promise.resolve("mocked data" as any as T);
}
};
You can optionall inject the above module in your imports where you are using actual forge bridge using an environment variable. Try the following
// import both of them
import { invoke as forgeBridge, view } from "@forge/bridge";
import { invoke as debugBridge } from "../../mock";
// inject one of them based on env
let invoke = process.env.REACT_APP_MOCK_FORGE_BRIDGE
? debugBridge
: forgeBridge;
// now use the invoke variable like you use it normally