Disable forge tunnel

I see two possible ways to handle this.

In our case, we not only moved the app to Forge but also switched from Webpack to Vite, and decided to split the frontend - one for Connect and one for Forge - since that approach was simpler for us.

Another option is to keep a single shared codebase and switch only the platform layer using a bundler alias (webpack, vite):

// webpack.config.js
const path = require('path');
const isForge = process.env.BUILD_TARGET === 'forge';

module.exports = {
  // entry/output...
  resolve: {
    alias: {
      '@platform': path.resolve(
        __dirname,
        isForge ? 'src/platform/forge.ts' : 'src/platform/connect.ts'
      ),
    },
    extensions: ['.ts', '.tsx', '.js'],
  },
};

Package.json Scripts:

{
  "scripts": {
    "build:forge": "cross-env BUILD_TARGET=forge webpack --mode production",
    "build:connect": "cross-env BUILD_TARGET=connect webpack --mode production"
  }
}

src/platform/forge.ts:

import { invoke as bridgeInvoke } from '@forge/bridge';

export async function invoke(key: string, payload?: unknown) {
  return bridgeInvoke(key, payload);
}

src/platform/connect.ts:

export async function invoke(key: string, payload?: unknown) {
 // ... connect call
  const res = await fetch(`/connect-api/${key}`, {
    method: 'POST',
    headers: { 'content-type': 'application/json' },
    body: JSON.stringify(payload ?? {}),
  });
  if (!res.ok) throw new Error(`Connect call failed: ${res.status}`);
  return res.json();
}

Then in your app:

import { invoke } from "@platform";

And in tsconfig.json for IDE support:

{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "@platform": [
        "src/platform/forge.ts",
        "src/platform/connect.ts"
      ]
    },
    // ...
  },
  "include": ["src"]
}

This way:

  • The bundler alias (webpack or vite) decides which file to include in the final build.
  • The tsconfig path mapping ensures your IDE and TypeScript compiler don’t complain about missing @platform.