Docs

useOpenExternal

Open external URLs in a new browser tab from your widget

useOpenExternal

Open external URLs in a new browser tab from your widget. This hook provides a secure way to navigate users to external websites while maintaining the ChatGPT conversation context.

Usage

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

function MyWidget() {
  const openExternal = useOpenExternal();

  const handleVisit = () => {
    openExternal('https://example.com', {
      target: '_blank',
      features: 'noopener,noreferrer',
    });
  };

  return <button onClick={handleVisit}>Visit Website</button>;
}

Parameters

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

ParameterTypeDescription
urlstringThe URL to open
optionsOpenExternalOptionsOptional configuration for how to open the URL

OpenExternalOptions

interface OpenExternalOptions {
  target?: '_blank' | '_self' | '_parent' | '_top';
  features?: string;
  width?: number;
  height?: number;
}

Return Type

Returns a function with the following signature:

type OpenExternalFunction = (
  url: string,
  options?: OpenExternalOptions
) => void;

Example

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

function LinkWidget() {
  const openExternal = useOpenExternal();

  return (
    <div>
      <h3>Helpful Resources</h3>
      <ul>
        <li>
          <button onClick={() => openExternal('https://docs.example.com')}>
            Documentation
          </button>
        </li>
        <li>
          <button onClick={() => openExternal('https://support.example.com')}>
            Support
          </button>
        </li>
        <li>
          <button onClick={() => openExternal('https://github.com/example/repo')}>
            GitHub Repository
          </button>
        </li>
      </ul>
    </div>
  );
}

With Options

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

function PopupWidget() {
  const openExternal = useOpenExternal();

  const openPopup = (url: string) => {
    openExternal(url, {
      target: '_blank',
      width: 800,
      height: 600,
      features: 'noopener,noreferrer,scrollbars=yes',
    });
  };

  return (
    <div>
      <button onClick={() => openPopup('https://app.example.com/preview')}>
        Open Preview
      </button>
    </div>
  );
}
import { useOpenExternal } from '@chatgpt-apps/sdk';

function SecureWidget() {
  const openExternal = useOpenExternal();

  const openSecureLink = (url: string) => {
    // Always use security features for external links
    openExternal(url, {
      target: '_blank',
      features: 'noopener,noreferrer',
    });
  };

  const trustedDomains = [
    'https://trusted-site.com',
    'https://partner-site.com',
  ];

  return (
    <div>
      {trustedDomains.map((domain) => (
        <button
          key={domain}
          onClick={() => openSecureLink(domain)}
        >
          Visit {new URL(domain).hostname}
        </button>
      ))}
    </div>
  );
}

Dynamic URLs

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

function SearchWidget() {
  const openExternal = useOpenExternal();

  const searchOnGoogle = (query: string) => {
    const encodedQuery = encodeURIComponent(query);
    openExternal(`https://google.com/search?q=${encodedQuery}`, {
      target: '_blank',
      features: 'noopener,noreferrer',
    });
  };

  return (
    <div>
      <input
        type="text"
        placeholder="Search query"
        onKeyDown={(e) => {
          if (e.key === 'Enter') {
            searchOnGoogle(e.currentTarget.value);
          }
        }}
      />
    </div>
  );
}

With Confirmation

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

function ConfirmLinkWidget() {
  const openExternal = useOpenExternal();

  const openWithConfirm = (url: string) => {
    const confirmed = window.confirm(
      `You are about to leave this page and visit:\n\n${url}\n\nContinue?`
    );
    
    if (confirmed) {
      openExternal(url, {
        target: '_blank',
        features: 'noopener,noreferrer',
      });
    }
  };

  return (
    <div>
      <button onClick={() => openWithConfirm('https://external-site.com')}>
        Visit External Site
      </button>
    </div>
  );
}

Notes

  • Always use noopener,noreferrer features for security when opening external links
  • The URL must be a valid, absolute URL (starting with http:// or https://)
  • Some environments may block popups; consider providing fallback behavior
  • Use this hook instead of window.open() for better integration with the host
  • The host application may impose restrictions on which domains can be opened

On this page