How to Persist FDC3 App-Channel State Using Window Context During Layout Save and Restore

Background

This article covers two related issues that came up together in practice: a Workspaces restore bug that affected channel restoration (fixed in io.Connect Browser 4.1), and the broader question of how to persist FDC3 app-channel data across layout save/restore, which is application-managed by design.

The Problem

When using FDC3 app channels in io.Connect Browser e.g. for broadcasting context via fdc3.getOrCreateChannel('myChannel') - the channel subscription and context data work as expected at runtime. However, when you save a layout and later restore it, the FDC3 app-channel data is not automatically restored with it.

How User Channels and App Channels Differ on Layout Restore

FDC3 User Channels are predefined channels within the platform. They can be joined programmatically or through the UI. in io.Connect Browser 4.1 and later, apps should rejoin the last selected user channel automatically when the layout is restored. However, because user channels are shared across the entire io.Connect Browser ecosystem, the data within them is not saved or restored - only the channel membership is retained. This avoids interfering with other applications’ workflows.

FDC3 App Channels are created dynamically and are not predefined like user channels. They are implemented using the io.Connect Browser Shared Contexts API. Unlike user channels, app channels cannot be joined in the traditional sense, and they are not persisted by the platform when saving layouts.

Regardless of which channel type you use, the platform will not populate any context data when restoring a layout.

The Solution: App-Managed Persistence via onSaveRequested and Window Context

Since the platform does not automatically persist app-channel state, the recommended approach is to save whatever you need into the window context and restore it in your own app logic.

You can do this using the onSaveRequested hook from the Layouts API.

Step 1: Save the App-Channel Data on Layout Save

Subscribe in the workspace window to save the app channel name and context when the layout is saved. Note that the callback must be synchronous.

const unsub = await io.layouts.onSaveRequested(() => {
  return {
    windowContext: { 
      appChannelName: "myChannel",
      appChannelContext: { test: 42 }
    }
  };
});

Step 2: Retrieve the Saved Data on Layout Restore

When the layout is restored, retrieve the window context:

const myWindow = io.windows.my();
const myContext = await myWindow.getContext();
/*
{
  "appChannelName": "myChannel",
  "appChannelContext": { "test": 42 }
}
*/

You can also subscribe for context updates via onContextUpdated.

Step 3: Save and restore context

With this approach, you can:

  1. Use onSaveRequested to store your current app channel and context into the window context during layout save.

  2. On app initialization (after layout restore), consume the window context and implement your logic — for example, re-create the channel and broadcast the saved context.

Summary

Window Context:

The data associated with a single window instance inside the layout. Each window can have its own context, and it may be any object. Apps consume this using `io.windows.my().getContext()`.

FDC3 Context:

A standardized data format defined by the FDC3 spec, used for passing business identifiers (e.g., instrument, contact, organization) between apps. All FDC3 contexts require a `type` property (e.g., `“fdc3.instrument”`).

Any type of object may be saved as a layout or a window context.

A bug in the Workspaces library caused io.workspaces.restoreWorkspace() to fail to restore even user-channel associations correctly. This was fixed in io.Connect Browser 4.1, so if you face it update your version.

Related Documentation