Forge's requestConfluence method calls endpoint with wrong siteUrl

Hello there,

So I’m building my first forge app and I’m trying to retrieve spaces but it seems that forge’s requestConfluence method calls the endpoint using wrong siteUrl. You can see in the screenshot that the url is wrong. Instead of using my context.siteUrl is uses https://confluence/wiki/api/v2/spaces and I end up getting a CSP violation error in both the browser and when using forge tunnel.

Here is the code I’m using:

import React, { useEffect, useState } from "react";
import ForgeReconciler, { Code, Text } from "@forge/react";
import { GlobalSettings } from "@forge/ui";
import { view } from "@forge/bridge";
import { type FullContext } from "@forge/bridge/out/types";
import api, { route } from "@forge/api";

async function getSpaces() {
  try {
    const apiRoute = route`/wiki/api/v2/spaces`;
    console.log({ apiRoute });
    const response = await api.asUser().requestConfluence(apiRoute, {
      headers: {
        Accept: "application/json",
      },
    });
    console.log(`Response: ${response.status} ${response.statusText}`);
    const body = await response.json();
    console.log({ body });
    return body;
  } catch (error) {
    console.log({ error });
    return error?.message;
  }
}

const App = () => {
  const [spaces, setSpaces] = useState<string>();
  const [context, setContext] = useState<FullContext>();

  useEffect(() => {
    async function apiCall() {
      const c = await view.getContext();
      setContext(c);
      const s = await getSpaces();
      setSpaces(s);
    }
    apiCall();
  }, []);

  return (
    <>
      <Text>Space context:</Text>
      <Code language="json">{JSON.stringify(context, null, 2)}</Code>
      <Text>Spaces:</Text>
      <Code language="json">{JSON.stringify(spaces, null, 2)}</Code>
    </>
  );
};

ForgeReconciler.render(
  <React.StrictMode>
    <GlobalSettings>
      <App />
    </GlobalSettings>
  </React.StrictMode>
);

Here is my package.json:

  "dependencies": {
    "@forge/api": "^2.18.5",
    "@forge/bridge": "2.6.0",
    "@forge/react": "8.0.0",
    "@forge/resolver": "1.5.11",
    "@forge/ui": "^1.9.3",
    "@forge/ui-confluence": "^11.0.9",
    "buffer": "^6.0.3",
    "react": "^18.2.0"
  }

Am I forgetting something? Many thanks for your time and help.

OK so moving the api call to a resolver works though:

import api, { route } from "@forge/api";
import Resolver from "@forge/resolver";

const resolver = new Resolver();

async function getSpaces() {
  try {
    const apiRoute = route`/wiki/api/v2/spaces`;
    const response = await api.asUser().requestConfluence(apiRoute, {
      headers: {
        Accept: "application/json",
      },
    });
    console.log(`Response: ${response.status} ${response.statusText}`);
    const body = await response.json();
    console.log({ body });
    return body;
  } catch (error) {
    console.log({ error });
    return error?.message;
  }
}


resolver.define("getSpaces", async (req) => {
  console.log(req);

  const spaces = await getSpaces();

  return spaces;
});

export const handler = resolver.getDefinitions();

Yep, you can use a resolver :+1:

Or, if you want to call the API directly from the front end you need to use the requestConfluence method on the Forge Bridge (not from @forge/api).