Docs

useRequestDisplayMode

Request a change to the widget's display mode (pip, inline, fullscreen)

useRequestDisplayMode

Request a change to the widget's display mode. This hook allows your widget to programmatically request to switch between picture-in-picture, inline, and fullscreen modes.

Usage

import { useRequestDisplayMode } from '@chatgpt-apps/sdk';

function MyWidget() {
  const requestDisplayMode = useRequestDisplayMode();

  const expandToFullscreen = async () => {
    const success = await requestDisplayMode('fullscreen');
    if (success) {
      console.log('Widget expanded to fullscreen');
    } else {
      console.log('Fullscreen request was denied');
    }
  };

  return <button onClick={expandToFullscreen}>Expand</button>;
}

Parameters

The hook itself accepts no parameters. The returned function accepts:

ParameterTypeDescription
modeDisplayModeThe requested display mode: 'pip', 'inline', or 'fullscreen'

Return Type

Returns a function with the following signature:

type RequestDisplayModeFunction = (
  mode: DisplayMode
) => Promise<boolean>;

The function returns a Promise<boolean> that resolves to:

  • true - The mode change was accepted
  • false - The mode change was denied or failed

Example

Mode Toggle

import { useRequestDisplayMode, useDisplayMode } from '@chatgpt-apps/sdk';

function ToggleWidget() {
  const displayMode = useDisplayMode();
  const requestDisplayMode = useRequestDisplayMode();

  const toggleMode = async () => {
    const nextMode = displayMode === 'fullscreen' ? 'inline' : 'fullscreen';
    const success = await requestDisplayMode(nextMode);
    
    if (!success) {
      console.warn(`Failed to switch to ${nextMode} mode`);
    }
  };

  return (
    <button onClick={toggleMode}>
      {displayMode === 'fullscreen' ? 'Exit Fullscreen' : 'Enter Fullscreen'}
    </button>
  );
}

Expand for Detail View

import { useRequestDisplayMode, useDisplayMode } from '@chatgpt-apps/sdk';

function DetailWidget() {
  const displayMode = useDisplayMode();
  const requestDisplayMode = useRequestDisplayMode();
  const [selectedItem, setSelectedItem] = useState<Item | null>(null);

  const viewDetails = async (item: Item) => {
    setSelectedItem(item);
    
    // Request fullscreen for better detail viewing
    if (displayMode !== 'fullscreen') {
      await requestDisplayMode('fullscreen');
    }
  };

  const closeDetails = async () => {
    setSelectedItem(null);
    
    // Return to inline mode when done
    await requestDisplayMode('inline');
  };

  return (
    <div>
      {selectedItem ? (
        <DetailView item={selectedItem} onClose={closeDetails} />
      ) : (
        <ListView onSelect={viewDetails} />
      )}
    </div>
  );
}

Picture-in-Picture Mode

import { useRequestDisplayMode } from '@chatgpt-apps/sdk';

function PipWidget() {
  const requestDisplayMode = useRequestDisplayMode();

  const minimizeToPip = async () => {
    const success = await requestDisplayMode('pip');
    
    if (success) {
      console.log('Widget minimized to picture-in-picture mode');
    }
  };

  const restoreInline = async () => {
    await requestDisplayMode('inline');
  };

  return (
    <div>
      <button onClick={minimizeToPip}>Minimize</button>
      <button onClick={restoreInline}>Restore</button>
    </div>
  );
}

With Loading State

import { useRequestDisplayMode, useDisplayMode } from '@chatgpt-apps/sdk';

function ModeControlWidget() {
  const currentMode = useDisplayMode();
  const requestDisplayMode = useRequestDisplayMode();
  const [isTransitioning, setIsTransitioning] = useState(false);

  const changeMode = async (targetMode: DisplayMode) => {
    if (targetMode === currentMode) return;
    
    setIsTransitioning(true);
    try {
      const success = await requestDisplayMode(targetMode);
      if (!success) {
        alert(`Could not switch to ${targetMode} mode`);
      }
    } finally {
      setIsTransitioning(false);
    }
  };

  return (
    <div className="mode-controls">
      <button
        onClick={() => changeMode('pip')}
        disabled={isTransitioning || currentMode === 'pip'}
      >
        PIP
      </button>
      <button
        onClick={() => changeMode('inline')}
        disabled={isTransitioning || currentMode === 'inline'}
      >
        Inline
      </button>
      <button
        onClick={() => changeMode('fullscreen')}
        disabled={isTransitioning || currentMode === 'fullscreen'}
      >
        Fullscreen
      </button>
      {isTransitioning && <span>Switching...</span>}
    </div>
  );
}

Conditional Mode Request

import { useRequestDisplayMode, useDisplayMode, useMaxHeight } from '@chatgpt-apps/sdk';

function AdaptiveWidget() {
  const displayMode = useDisplayMode();
  const maxHeight = useMaxHeight();
  const requestDisplayMode = useRequestDisplayMode();

  useEffect(() => {
    // Auto-expand to fullscreen if content is too tall for inline
    if (displayMode === 'inline' && maxHeight < 400) {
      requestDisplayMode('fullscreen');
    }
  }, [displayMode, maxHeight, requestDisplayMode]);

  return (
    <div>
      <Content />
    </div>
  );
}

Notes

  • Mode change requests may be denied by the host environment
  • Always check the return value to handle denied requests gracefully
  • The host may restrict which modes are available
  • Use useDisplayMode to track the current mode
  • Consider user experience when programmatically changing modes

On this page