Fusion Developer Portal
Guide development of Fusion portal shells — host applications that load, route, and render Fusion apps inside shared chrome (header, context selector, navigation).
When to use
- Scaffold new Fusion portal
portal.manifest.tsorffc portal devquestions- Configure portal-level modules (telemetry, analytics, navigation, services, app module)
- Build custom app loader or portal shell
- Add portal-level routing (
/apps/:appKey/*) Apploadercomponent oruseApploaderhook for embedding apps- Wire up portal header, context selector, or bookmark side sheet
- Understand how portals load/initialize Fusion apps at runtime
- Add portal-level analytics or telemetry
- Portal deployment (
ffc portal build,ffc portal upload)
When not to use
- App-level feature development →
fusion-app-react-dev - Backend service changes → separate repo
- Fusion Help Center integration →
fusion-help-integration - Skill authoring →
fusion-skill-authoring - Issue authoring →
fusion-issue-authoring
Required inputs
Mandatory
- What to build: scaffold a portal, add a feature, configure a module, or understand portal architecture
- Portal context: new from scratch or modifying existing
Conditional
- Portal name/ID when scaffolding
- MSAL client ID and service discovery URL when configuring auth
- Specific modules to enable (analytics, telemetry, bookmarks, feature flags, AG Grid)
- Whether the portal needs a custom app loader or the default
Apploadersuffices
Instructions
Step 1 — Classify the portal task
Determine what the user needs:
- Scaffold new portal → step 2
- Configure portal modules → step 3
- App loading and routing → step 4
- Portal chrome (header, context, bookmarks) → step 5
- Analytics and telemetry → step 6
- Build and deploy → step 7
When Fusion MCP is available, prefer mcp_fusion_search_framework with queries like "portal manifest definePortalManifest ffc portal" or "createFrameworkProvider PortalModuleInitiator portal configure" for latest API surface. Label guidance not confirmed by MCP as fallback.
Step 2 — Scaffold a new portal
Use the Fusion Framework CLI:
mkdir my-fusion-portal && cd my-fusion-portal
pnpm init
pnpm add -D @equinor/fusion-framework-cli
Create the required files:
portal.manifest.ts— portal metadata and configuration:
import { definePortalManifest } from '@equinor/fusion-framework-cli/portal';
export default definePortalManifest((env, { base }) => ({
name: 'my-portal',
version: '1.0.0',
entry: './src/index.tsx',
}));
portal.schema.ts(optional) — configuration validation schemasrc/index.tsx— portal entry point (see references/portal-architecture.md)
Start the dev server:
pnpm fusion-framework-cli portal dev
# or: ffc portal dev
Step 3 — Configure portal modules
Portal-level configuration uses FrameworkConfigurator (not AppModuleInitiator like apps). Enable modules in your configure callback:
import type { FrameworkConfigurator } from '@equinor/fusion-framework';
import { enableAppModule } from '@equinor/fusion-framework-module-app';
import { enableNavigation } from '@equinor/fusion-framework-module-navigation';
import { enableAnalytics } from '@equinor/fusion-framework-module-analytics';
const configure = (configurator: FrameworkConfigurator) => {
enableAppModule(configurator);
enableNavigation(configurator, '/');
enableAnalytics(configurator, { /* ... */ });
};
Key difference from app configuration: the portal configures FrameworkConfigurator and its modules are hoisted to all child apps. MSAL/auth is configured at portal level and inherited by apps.
See references/portal-architecture.md for full module configuration and portal-analytics cookbook reference.
Step 4 — App loading and routing
The portal routes /apps/:appKey/* to an app loader. Two approaches:
Simple embed — use the built-in Apploader component:
import { Apploader } from '@equinor/fusion-framework-react-app/apploader';
<Apploader appKey="my-app" />
Warning:
Apploaderis an experimental POC. Embedded apps may have routing and context issues. Best for simple apps like PowerBI or PowerApps views.
Custom app loader — for full control over loading states, error handling, and mounting. Use useFramework<[AppModule]>(), observe fusion.modules.app.current$, and call app.initialize(). See references/portal-architecture.md for the annotated custom AppLoader pattern.
Portal routing typically uses react-router-dom via the navigation module:
const Router = () => {
const framework = useFramework();
const router = framework.modules.navigation.router;
return <RouterProvider router={router} />;
};
Step 5 — Portal chrome
Portal-level UI typically includes:
- Header — top bar with Fusion logo, context selector, bookmarks, person settings
- Context selector — wired to app context module via
useCurrentContextoruseContextSelector - Bookmark side sheet — toggled via navigation module
- App navigation — sidebar or top-level nav for switching apps
Apps don't build their own header — they receive it from the portal shell.
Step 6 — Analytics and telemetry
Portal-level analytics capture app lifecycle events. Enable with adapters and collectors:
import { enableAnalytics } from '@equinor/fusion-framework-module-analytics';
import { ConsoleAnalyticsAdapter } from '@equinor/fusion-framework-module-analytics/adapters';
import { AppLoadedCollector, AppSelectedCollector } from '@equinor/fusion-framework-module-analytics/collectors';
enableAnalytics(configurator, (builder) => {
builder.addAdapter(new ConsoleAnalyticsAdapter());
builder.addCollector(new AppLoadedCollector());
builder.addCollector(new AppSelectedCollector());
});
For telemetry (OpenTelemetry / Application Insights), see references/portal-architecture.md.
Step 7 — Build and deploy
# Build the portal template
ffc portal build
# Upload to the Fusion portal service (authenticate via `az login` or FUSION_TOKEN env var)
ffc portal upload --portal-id <id>
# Tag a specific version
ffc portal tag --portal-id <id> --tag latest --version <version>
Never paste tokens directly into commands. Use
az loginfor interactive auth or setFUSION_TOKENenv var for CI pipelines.
Step 8 — Validate
ffc portal devstarts without errors- Apps load at
/apps/:appKey - Context selector and header render properly
- TypeScript compiles with no errors
- Analytics events fire on app load/select (if enabled)
Expected output
- Working portal shell with app loading, routing, and chrome
- Portal-level module configuration with correct
FrameworkConfiguratorusage - Loading and error states handled for app initialization
- Brief summary of what was created or changed
Helper agents
Same companion infrastructure as fusion-app-react-dev:
fusion-research— source-backed Fusion ecosystem research when portal behavior is uncertainfusion-code-conventions— naming, TSDoc, and code style checks
When Fusion MCP is available, prefer mcp_fusion_search_framework for portal-specific lookups.
Safety & constraints
- MSAL is portal-level — never configure auth in apps; it is hoisted from the portal
- Don't invent portal APIs — only reference APIs confirmed by MCP or documented in references
Apploaderis experimental — always mention routing/context limitations when advising on app embedding- No secrets in source — MSAL client IDs must come from environment variables, not hardcoded
- Don't modify the production Fusion portal — this skill covers custom portal development only
- Conventional commits for all changes










