requestRemote bridge API is now available for integrating remotes directly from the UI client

Hello Atlassian Community,

We have just announced the requestRemote bridge API, which allows Forge apps to integrate directly with remote backends from the UI Kit and Custom UI applications via the Forge bridge.

Our goal for the requestRemote API was to create a lightweight method for UI and Custom UI apps to interact with Forge remote backends. This specifically applies to requests tied to UI experiences, where the latency overhead of proxying from the Forge platform back to the remote was not optimal.

requestRemote is an implementation of this FRGE-1856, asking for direct UI client to remote access, but is also a workaround for several other feature requests, including:

This API is similar to invokeRemote bridge method, where requests include a Forge Invocation Token (FIT) as a bearer token in the authorization header. The main difference is that the requestRemote API does not create an invocation context that passes through the Forge platform. Therefore, requestRemote will not include OAuth tokens, even if configured for the remote, and will not be reflected in invocation metrics in the Developer Console. For more details on requestRemote, please refer to the documentation.

We hope this new API enables the adoption of the Forge platform for several currently blocked use cases, especially for those migrating from Connect to Forge.

Best regards,

Bo Yang Zhang

Cool! Looking into it in more detail later. For now: On the docu page, the link in this sentence links to nothing (the bold part):

See Verifying Remote Requests for more details on how to validate the FIT.

Can you fix the link?

Thanks @AndreasEbert , sorry about the broken link, it has now been fixed.

Hello, for those who were waiting on FormData support for requestRemote, this is just a quick announcement that support has been added. This means that it could potentially be a workaround for the following feature request, which asks for invokeRemote to support FormData.

Please refer to the following changelog for more information.

If you have any feedback, please post it on this thread or alternatively, create a new thread and mention me.

Best regards,

Bo Yang Zhang

Hi,

Goal: Call the remote server from the custom UI not the forge backend.

Solutions to make calls from custom UI to remote server:

invokeRemote - which we are already using

requestRemote - we would like to switch to it as invokeRemote has its own limitations.

requestRemote means makes a call from browser, the CORS policies are applied.
First the preflight request would go through and in this case the API is successful. Refer the HAR file shared.
Before the actual request goes through, the error as shared in screenshot is observed.

Note: The remote server does not receive the actual request, it only receives the prefligt request.

Sample code that makes a call:
let options = {
method: “GET”,
path: “api/v1/getRegion”,
headers: {
“Content-Type”: “application/json”,
},
};

const response = await requestRemote(“connect”, options);

Regards,
Pratiksha Kate

Hi @anon56496261 , looking at your screenshot, it seems like your remote is blocking CORS access.

For requestRemote, since the request to your remote service is now being made directly via the browser, you need to have your remote allow CORS access from Atlassian domains. To do this, your remote service will have to respond with the relevant headers in response to the preflight request. Here is a link to a page which might help - CORS Headers Explained.

Hello @BoZhang,
Preflight request is already handled.
Below is the response of the Preflight request.

Hi @anon56496261 , I see, the console output suggests that the requests was blocked due to the CORS policy from your server so I assumed that was the issue.

If the preflight goes through, then the actual request should be made to your remote. This part we don’t really control, it should all be done by the browser. What does the request and response look like for the actual request in the developer console?

Hi @BoZhang ,
The actual request does not even reach our remote server. Also the response of the actual request is empty and the status code is 200. Since the status code is 200, I am a bit confused here.

Hi @anon56496261, from the screenshot that you’ve shared, it looks like the browser has made a request successfully to the URL that should map to the remote that you have defined and something on the other side is returning a 200 response. Perhaps you could do a fetch request directly in the developer console and see if you get anything different.

There are some things that I find interesting from your screen shot though:

  • The Content-Type in the response header is text/html, are you expecting HTML back? Could it be something in front of your application (e.g - a Load balancer that is returning a response before it gets to your application?)
  • The Remote Address is :80, I wouldn’t expect that for a request URL that is specifying the protocol as https://. Are you running some sort of proxy?

Hello @BoZhang

Thank you for your help.

It appears the issue is isolated to the local Nginx setup. Although the preflight request returns a 204 status, the actual request is not reaching the remote server.

requestRemote seems to be working fine on the development env. This confirms that the issue is likely tied to the local Nginx configuration.

Regards,
Pratiksha Kate

Hi :waving_hand:,

I’m running into an issue with requestRemote when my Forge app is rendered in Jira Service Management – Customer Portal.

Context

  • The same Forge app + remote configuration works without any issues when used inside Jira (issue UI).

  • The problem occurs only when the app is rendered in the customer portal (Help Center).

What happens

When calling requestRemote from the customer portal UI, the request fails immediately with the following error in the browser console:

Error: No handler found for post message: fetchRemote from https://awp8o-13tck8xeue-1ebdo2fqn0--jl1z5-fpaxtbubz-1aaux8cibv.cdn.prod.atlassian-dev.net in https://<instance-name>.atlassian.net/servicedesk/customer/portal/1/group/1/create/204
    at https://jsm-help-center-ui.prod-east.frontend.public.atl-paas.net/assets/js/forge-renderer.chunk.fe6e534a68c929dc850d.js:2:702106
    at e.try (https://jsm-help-center-ui.prod-east.frontend.public.atl-paas.net/assets/js/forge-renderer.chunk.fe6e534a68c929dc850d.js:2:682449)
    at Ae (https://jsm-help-center-ui.prod-east.frontend.public.atl-paas.net/assets/js/forge-renderer.chunk.fe6e534a68c929dc850d.js:2:702081)
    at Ge (https://jsm-help-center-ui.prod-east.frontend.public.atl-paas.net/assets/js/forge-renderer.chunk.fe6e534a68c929dc850d.js:2:704211)
    at https://jsm-help-center-ui.prod-east.frontend.public.atl-paas.net/assets/js/forge-renderer.chunk.fe6e534a68c929dc850d.js:2:709966
    at e.try (https://jsm-help-center-ui.prod-east.frontend.public.atl-paas.net/assets/js/forge-renderer.chunk.fe6e534a68c929dc850d.js:2:682449)
    at https://jsm-help-center-ui.prod-east.frontend.public.atl-paas.net/assets/js/forge-renderer.chunk.fe6e534a68c929dc850d.js:2:709763
    at r (https://jsm-help-center-ui.prod-east.frontend.public.atl-paas.net/assets/js/forge-renderer.chunk.fe6e534a68c929dc850d.js:2:710015)
    at a (https://jsm-help-center-ui.prod-east.frontend.public.atl-paas.net/assets/js/servicedesk-vendor.chunk.27f812b48406c234baa4.js:2:1794898)

Error: No handler found for post message: fetchRemote from https://awp8o-13tck8xeue-1ebdo2fqn0--jl1z5-fpaxtbubz-1aaux8cibv.cdn.prod.atlassian-dev.net in https://<instance-name>.atlassian.net/servicedesk/customer/portal/1/group/1/create/204
    at le.error (https://forge.cdn.prod.atlassian-dev.net/global-bridge.js:1:19299)
    at Object.<anonymous> (https://forge.cdn.prod.atlassian-dev.net/global-bridge.js:1:27003)
    at JSON.parse (<anonymous>)
    at o (https://forge.cdn.prod.atlassian-dev.net/global-bridge.js:1:26863)
    at ke (https://forge.cdn.prod.atlassian-dev.net/global-bridge.js:1:27014)
    at u.on (https://forge.cdn.prod.atlassian-dev.net/global-bridge.js:1:31646)
    at ze (https://forge.cdn.prod.atlassian-dev.net/global-bridge.js:1:31783)
    at https://forge.cdn.prod.atlassian-dev.net/global-bridge.js:1:37729
    at e.try (https://forge.cdn.prod.atlassian-dev.net/global-bridge.js:1:10393)
    at https://forge.cdn.prod.atlassian-dev.net/global-bridge.js:1:37527

What’s interesting:

  • The error suggests that the Forge bridge does not register a handler for fetchRemote in the customer portal context.

  • This happens before the request even reaches the remote backend.

  • No network request to the remote is made at all.

Expected behavior

I would expect requestRemote to behave the same way as it does in Jira views.

Questions

  1. Is requestRemote officially supported in JSM Customer Portal / Help Center?

  2. If not – is this a known limitation and is it documented anywhere?

At the moment this looks like a runtime/bridge bug.

Thanks in advance for any clarification :folded_hands:

Hi @michal.sztuka, requestRemote should be available in JSM; it’s an issue that it is not available.

I will follow up on this and get back to you soon. Sorry about the inconvenience.

Hi @michal.sztuka , requestRemote should be available for JSM Customer portal modules now.

Thanks a lot for the quick fix and the follow-up!
Much appreciated — great to see this resolved so fast :+1:

Hi @BoZhang. Is the requestRemote available in Bitbucket?

If I try to use it (“@forge/bridge”: “5.10.2”), I get the following CSP error:

Looks like it uses the CSP of the parent page, rather than the one I set through the Forge manifest.

Hi @aokulovich, thank you for reporting this. It indeed seems like Bitbucket’s CSP gets in the way of requestRemote. I will try to follow this up with the team, but it’s likely Bitbucket will not want to relax their CSPs. If so, we will probably need to explore alternatives, and it’s likely requestRemote for Bitbucket will not be available in the short term. I apologise for the inconvenience.

I have created a FRGE ticket to track the number of partners affected. So please upvote it and comment on your use case if you are affected.

Hi @BoZhang
This will trigger a CORS request from the browser. While we can validate and allow origins matching the *.atlassian.net pattern, Atlassian also supports custom domains. How would you suggest handling cases where the Origin does not follow the *.atlassian.net format?

Additionally, the siteUrl in the context object within the FIT token is sent in the *.atlassian.net format for custom domain.

Thanks!

Hi @avinashpachva , thanks for raising this. Unfortunately, I don’t think we have a readily available solution for custom domains and CORS. Can you please open a FRGE ticket here? I will get the team to have a look at it.

Hi @BoZhang
I’ve created FRGE ticket : Jira
Thanks!