Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
Status: preview - based on the in-development SPFx Copilot Component model. APIs may change before general availability.
A Copilot component can render in two layouts inside Microsoft 365 Copilot:
inline- a compact layout that sits within the Copilot conversation flow. This is the default.fullscreen- an expanded layout that takes over the full Copilot surface.
This article explains how the current mode is delivered to your component and what you need to do to flip it.
How the current mode reaches your component
The active mode is a field on the host context, this.hostContext.displayMode. The host delivers it at initialization and keeps it up to date. Whenever it changes, the base class re-renders your component automatically, so you should read it fresh on every render instead of caching it:
protected render(): void {
const displayMode: string = this.hostContext.displayMode || 'unknown';
const isFullscreen: boolean = this.hostContext.displayMode === 'fullscreen';
// ...use these values to drive what you render
}
Declare the modes you support
A component only renders in the modes it advertises in its manifest through the availableDisplayModes capability:
// HelloCopilotCopilotComponent.manifest.json (excerpt)
"capabilities": {
"availableDisplayModes": ["inline", "fullscreen"]
}
Never request a mode the host has not advertised in this.hostContext.availableDisplayModes.
Flipping the mode
The transition is asymmetric - each direction is owned by a different party:
| You want to... | Who does it | How |
|---|---|---|
| Expand from inline to fullscreen | Component | await this.requestDisplayModeAsync('fullscreen') |
| Collapse from fullscreen back to inline | Host only | You do nothing. The host notifies you when the user does it. |
| React to any mode change | Framework | It re-renders automatically; read this.hostContext.displayMode. |
Inline to fullscreen (your job)
Call requestDisplayModeAsync('fullscreen'). The method only accepts 'fullscreen' - it is the single mode you can request:
private _handleRequestFullscreen = async (): Promise<void> => {
try {
const result = await this.requestDisplayModeAsync('fullscreen');
console.log('[HelloCopilot] requestDisplayModeAsync result:', result);
} catch (error) {
console.error('[HelloCopilot] Failed to switch to fullscreen:', error);
}
};
Do not optimistically change any local state after calling it. The host may honor or deny the request. Either way, the next host-context update carries the real mode, the base class re-renders, and your next render sees the truth.
Fullscreen to inline (the host's job)
There is no API to collapse. The user clicks the host's own collapse control, and your component simply re-renders with displayMode back to 'inline'. Design your UI so that the way out of fullscreen is clearly the host's control, not a close button of your own.
No native button or icon - you own the control
Important
The Copilot host does not provide a built-in "expand" button or icon inside your component. The developer is fully responsible for rendering whatever affordance triggers the switch to fullscreen and wiring it to requestDisplayModeAsync('fullscreen').
Design guidance and recommended visuals for this control will be provided by the time the feature reaches general availability.
The sample renders its own expand button and only shows it when the component is not already in fullscreen:
const isFullscreen: boolean = this.hostContext.displayMode === 'fullscreen';
const expandHtml: string = isFullscreen
? ''
: `<button type="button" id="hc-expand" title="Expand to fullscreen" aria-label="Expand to fullscreen">${EXPAND_ICON}</button>`;
// after setting innerHTML, wire up the handler:
const expandButton = this.context.domElement.querySelector('#hc-expand');
if (expandButton) {
expandButton.addEventListener('click', this._handleRequestFullscreen);
}
Rules to remember
- Read the mode from
this.hostContext.displayModeon every render. Do not cache it. - Only request
'fullscreen'. Collapsing is host-initiated. - Respect
availableDisplayModes. Do not offer a transition the host has not advertised. - Render your own trigger. There is no native button - the developer controls it, with design guidance coming at GA.