How to display Jira page embeded on Confluence macro?

Hello,

I writing a Confluence macro and I would like to show a button “Preview” and when it is clicked a frame is displayed with the page content of a jira ticket (eg : /browse/ISSUE-1234).

Something like that :

I read Frame UIKit2 and router.navigate(‘/browse/ISSUE-1234’); documentations but I don’t know if I can use router in a Frame. If not, have you idea to show a iframe ?

I want the user experience to be as smooth as possible and therefore avoid opening a new tab in the browser.

Thx

Update:

I figured out how to use Frame to display an iframe, but then I get a CPS error "frame-ancestors" because when I use forge tunnel, the “Referer” is
http://localhost:8002/ and the accepted values to embed a Jira page ​​are: https://*.atlassian.net https://*.jira.com https://*.atl-paas.net https://*.atlassian.com https://trello.com https://bitbucket.org https://*.jiraalign.com »

If you have any ideas for displaying a Jira page in a Confluence macro, I’m interested.

To help other user, my code :

├── src/
│ ├── index.js
│ ├── fronted/
│ │ ├── config.jsx
│ │ └── index.jsx
│ └── resolvers/
│ └── index.jsx
├── static/
│ └── hello-world/
│ └── build/
│ └── index.html
├── manifest.yml
└── {other files}

manifest.yml

modules:
  macro:
    - key: test-confluence-ui-kit-custom-config-macro
      resource: main
      render: native
      resolver:
        function: resolver
      title: test
      config:
        resource: macro-config
        viewportSize: small
        render: native
        title: Config
  function:
    - key: resolver
      handler: index.handler
resources:
  - key: main
    path: src/frontend/index.jsx
  - key: macro-config
    path: src/frontend/config.jsx
  - key: example-resource
    path: static/hello-world/build
app:
  runtime:
    name: nodejs22.x
  id: ari:cloud:ecosystem::app/xxxxxxxx
permissions:
  content:
    styles:
      - "unsafe-inline"
    scripts:
     - "unsafe-hashes"
     - "unsafe-eval"
     - "unsafe-inline"
  external:
    fetch:
      backend:
        - '*.atlassian.net'
    frames:
      - '*.atlassian.net'

src/fronted/config.jsx

import React, { useState, useEffect } from 'react';
import ForgeReconciler, { useConfig, Button, Label, SectionMessage, Stack, Textfield } from '@forge/react';
import { view } from '@forge/bridge';
import { Frame } from '@forge/react';


const useSubmit = () => {
  const [error, setError] = useState();
  const [message, setMessage] = useState('');

  const submit = async (fields) => {
    const payload = { config: fields };

    try {
      await view.submit(payload);
      setError(false);
      setMessage(`Submitted successfully.`);
    } catch (error) {
      setError(true);
      setMessage(`${error.code}: ${error.message}`);
    }
  };

  return {
    error,
    message,
    submit
  };
};

const Config = () => {
  const [value, setValue] = useState('');
  const { error, message, submit } = useSubmit();
  const config = useConfig();

  

  useEffect(() => {
    setValue(config?.myField);
  }, [config?.myField]);

  return (
    <Stack space="space.200">
      <Frame resource="example-resource" />
      <Label labelFor="myField">Config field:</Label>
      <Textfield id="myField" value={value} onChange={(e) => setValue(e.target.value)} />
      <Button appearance="subtle" onClick={view.close}>
        Close
      </Button>
      <Button appearance="primary" onClick={() => submit({ myField: value })}>
        Submit
      </Button>

      {typeof error !== 'undefined' && (
        <SectionMessage appearance={error ? 'error' : 'success'}>{message}</SectionMessage>
      )}
    </Stack>
  );
};

ForgeReconciler.render(
  <React.StrictMode>
    <Config />
  </React.StrictMode>
);

static/hello-world/build

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>React App</title>
    <script type="content" src="src/index.jsx"></script>
  </head>
  <body>
    <noscript>You need to enable JavaScript to run this app.</noscript>
    <div id="root">Hello embed JIRA XSP1-3 </div>
    <iframe 
    src="https://myatlassiantest.atlassian.net/browse/XSP1-3/embed?originUrl=https%3A%2F%2Fmyatlassiantest.atlassian.net&parentProduct=smartlink&themeState=dark%3Adark+light%3Alight+spacing%3Aspacing+typography%3Atypography-refreshed+colorMode%3Alight" 
    width="100%" 
    height="100%" 
    style="border: none;">
  </iframe>
  </body>
</html>