Skip to main content
A view runs in a sandboxed iframe, so a normal external link goes nowhere: window.open and target="_blank" are both blocked. useOpenExternal sends the user out to a URL by routing the navigation through the host.

Example

The product card sends the shopper to the merchant’s product page when they tap “View details”; the host opens it in the user’s browser.
views/carousel.tsx
import { useOpenExternal } from "skybridge/web";

type Product = {
  name: string;
  price: number;
  productUrl: string;
};

function ProductCard({ product }: { product: Product }) {
  const openExternal = useOpenExternal();

  return (
    <div className="card">
      <h3>{product.name}</h3>
      <p>${product.price}</p>
      <button onClick={() => openExternal(product.productUrl)}>
        View details
      </button>
    </div>
  );
}

Returns

useOpenExternal takes no arguments and returns a single function.

openExternal

openExternal(href: string, options?: { redirectUrl?: false }): void;
Routes the navigation through the host. Returns void: a fire-and-forget side effect, nothing crosses back to the view or the model.
  • href (required) The URL to open outside the iframe. The host opens it in the user’s browser or hands it to the native app.
  • options Optional. Its only field, redirectUrl, is read on ChatGPT only: for allowlisted targets ChatGPT appends a ?redirectUrl=… parameter (a link back into the conversation) by default, and redirectUrl: false skips it. On Claude it is ignored with a warning.
Origins that openExternal can send the user to without the host’s safe-link confirmation modal are declared in the view’s redirectDomains. The view passes that list to the host, which honors it. See Configure CSP.

Create Views

Open the sandbox to external domains from a view

Configure CSP

Allowlist redirect targets with redirectDomains

useSendFollowUpMessage

Send a message back into the conversation