Preview links (Developer Preview)

Stay organized with collections Save and categorize content based on your preferences.

This page explains how to preview links in Google Docs from a third-party or non-Google service.

To integrate content from a third-party service into Google Docs, you can configure link previews for your Google Workspace Add-on. When users preview links from your service, they can access and interact with the service within the document.

To preview links in Google Docs, users interact with smart chips and cards.

When users type or paste a link into a document, Google Docs prompts them to replace the URL with a smart chip. The chip displays an icon and short title or description of the link's content. When users hover over the URL or chip, they see a card that displays more information about the link.

The following video demonstrates how a Google Docs user pastes and then previews a third-party link in a document:

You can configure a Google Workspace Add-on to preview links for multiple URL patterns. For example, you can create custom link previews for each of the following:

  • Support case URLs that preview the case ID, title, status, and the employee assigned to the case.
  • Sales lead URLs that preview the lead's name, title, company, and last contacted date.
  • Company profile URLs that preview the team member's name, title, and office location.

Set up authorization for your service

To preview links from a service that is external to Google, users must be able to access or sign in to the service. If your service requires authorization, your add-on must be able to invoke the authorization flow when users paste a link from your service into a Google Docs document for the first time.

To set up an OAuth service or custom authorization prompt, see Connecting to non-Google Services from a Google Workspace Add-on.

This section explains how to turn on link previews for your add-on, which includes the following steps:

  1. Configure link previews in your add-on's manifest file.
  2. Build the smart chip and card interface for your link previews.
  3. Publish the updated add-on to the Google Workspace Marketplace, so that new and existing users can access link previews.

Configure link previews

You configure link previews in the addons resource of your add-on's manifest file. Your add-on must extend Google Docs and include a linkPreviewTriggers object.

In your Google Workspace Add-on's manifest file, add or update the following fields:

  1. Add the addOns.docs field to extend Google Docs in your add-on.
  2. Under the addOns.docs field, implement the linkPreviewTriggers trigger with the following fields:

    • labelText: The text that prompts users to preview the link, such as Example: Support case. This text is static and displays before users execute the add-on.
    • localizedLabelText (Optional): A labelText that is localized into another language. You must specify the language and country/region identifier in the format of ISO 639 language code-ISO 3166 country/region code. For example, en-US.
    • runFunction: The callback function that returns a smart chip and card for the link preview. If required, the function must also invoke the authorization flow for the third-party service. To create this function, see the following section, Build the smart chip and card.
    • Icon (Optional): The icon that displays in the smart chip. If omitted, the chip uses your add-on's toolbar icon, logoUrl.
    • Patterns: An array of URL patterns that trigger the add-on to preview links. For each pattern, include the following fields:

      • hostPattern: The domain of the URL pattern that your add-on previews. To preview links for a specific subdomain, like subdomain.example.com, include the subdomain. To preview links for the entire domain, specify a wildcard character with an asterisk (*) as the subdomain.

        For example, *.example.com matches subdomain.example.com and another.subdomain.example.com.

      • pathPrefix (Optional): The path that appends the hostPattern‘s domain. To match all URLs in the host pattern domain, leave pathPrefix empty.

        For example, if the host pattern is support.example.com, to match URLs for cases hosted at support.example.com/cases, enter cases.

  3. Add the scope https://www.googleapis.com/auth/documents.readonly to your oauthScopes field so that users can authorize the add-on to preview links on their behalf.

In the following example, the Altostrat company has a Google Workspace Add-on that previews links for the company's customer issues service. The code shows the addOns and oauthScopes portion of the add-on's manifest file. In the linkPreviewTriggers object, the add-on specifies three URL patterns to preview links. Whenever a link matches one of the URL patterns, the callback function issuesLinkPreview builds and displays a smart chip and card in the Google Docs document.

"oauthScopes": [
  "https://www.googleapis.com/auth/documents.readonly"
],

"addOns": {
  "common": {
    "name": "Altostrat Add-on",
    "logoUrl": "https://www.altostrat.com/images/company-logo.png",
    "layoutProperties": {
      "primaryColor": "#dd4b39"
    },

  "docs": {
    "linkPreviewTriggers": [
      {
        "labelText": "Altostrat customer issues",
        "runFunction": "issuesLinkPreview",
        "icon":"https://altostrat.com/images/support-icon.png",
        "patterns" : [ {
            "hostPattern": "issues.altostrat.com",
          },{
            "hostPattern": "*.altostrat.com",
            "pathPrefix": "issues"
          },{
            "hostPattern": "altostrat.com",
            "pathPrefix": "support/issues"
          },
        ]
      }
    ]
  },
}

Build the smart chip and card

To build a smart chip and card, you must implement any functions that you specified in the linkPreviewTriggers object.

When a user interacts with a link that matches a specified URL pattern, the linkPreviewTriggers trigger fires and its callback function passes the event object docs.matched.url as an argument. You use this event object to build the smart chip and card for your link preview.

To create the card interface, you use widgets to display information about the link. You can also build actions that let users open the link or modify its contents. For a list of available widgets and actions, see Supported interactions for preview cards.

In the following example, a chip and card display an issue's priority, status, assignee, and summary for a third-party customer support service:

User previews a card

To build the smart chip and card for a link preview:

  1. Implement the function that you specified in the linkPreviewTriggers section of your add-on's manifest file:
    1. The function must accept an event object containing docs.matched.url as an argument and return a single Card object.
    2. If your third-party service requires authorization, the function must also invoke the authorization flow.
  2. For each preview card, implement the callback functions used to provide widget interactivity for the interface. For example, if you include a button in the interface, it should have an attached Action and an implemented callback function that runs when the button is clicked.

The following code creates the callback function issuesLinkPreview from the earlier example for Altostrat:

  // Creates a function that passes an event object as a parameter:
  function issuesLinkPreview(event) {
    if (event.docs.matchedUrl.url) {
      
      // Uses docs.matchedUrl event object to identify the issue ID from the URL:
      const segments = event.docs.matchedUrl.url.split('/');
      const issueId = segments[segments.length - 1];
      
      // Builds a card header with the issue ID:
      const issueHeader = CardService.newCardHeader().setTitle("Issue " + issueId +": Title bar looks cramped");
      const issueDescription = CardService.newTextParagraph()
          .setText("Customer can't view title on mobile device.");
      
      // Returns a card with a header that contains the issue's ID and 
      // title and a text paragraph that contains the issue description:
      return CardService.newCardBuilder().setHeader(issueHeader)
          .addSection(CardService.newCardSection().addWidget(issueDescription)).build();
    }
  }

Supported interactions for preview cards

Google Workspace Add-ons support the following widgets and actions for link preview cards:

Card Service field Type
TextParagraph Widget
IconImage Widget
TextButton Widget
DecoratedText Widget
Image Widget
Divider Widget
ButtonSet Widget
Grid Widget
ImageButton Widget
OpenLink Action
Navigation Action
Only the updateCard method is supported.

Publish your updated add-on on the Google Workspace Marketplace

After you configure link previews for your add-on, you must update the OAuth consent screen and app configuration in the Google Workspace Marketplace so that new and existing users can access the updated add-on.

To update your add-on, you complete the following steps:

  1. Deploy a new version of your add-on.
  2. Update your add-on's configuration in the Google Workspace Marketplace.
  3. Add the scope https://www.googleapis.com/auth/documents.readonly to your OAuth consent screen.

For details on these steps, see Update and manage your published add-on.

After saving your changes to your listing on the Google Workspace Marketplace, your add-on is immediately updated. Your add-on prompts existing users to authorize the new scope the next time that they use the add-on.

Complete example: Support case add-on

The following Apps Script code sample is for a Google Workspace Add-on that previews links to a company's support cases and employee profiles.

The sample includes the following files:

  • The add-on's manifest file, appscript.json, that extends Google Docs and configures the linkPreviewTriggers function. The trigger is configured to preview links for a company's support cases (such as https://www.example.com/support/cases/1234) and employee profiles (such as https://www.example.com/people/rosariocruz).
  • A code file, code.gs, that configures a runFunction response for support case links and employee profile links.

Manifest file

{
  "timeZone": "America/New_York",
  "exceptionLogging": "STACKDRIVER",
  "runtimeVersion": "V8",
  "oauthScopes": [
    "https://www.googleapis.com/auth/documents.readonly"
  ],
  "addOns": {
    "common": {
      "name": "Support Case Add-on",
      "logoUrl": "https://www.example.com/support.png",
      "layoutProperties": {
        "primaryColor": "#dd4b39"
      }
    },
    "docs": {
      "linkPreviewTriggers": [
        {
          "runFunction": "userLinkPreview",
          "patterns": [
            {
              "hostPattern": "example.com",
              "pathPrefix": "people"
            }
          ],
          "labelText": "People",
          "localizedLabelText": {
            "es": "Personas"
          }
        },
        {
          "runFunction": "supportLinkPreview",
          "patterns": [
            {
              "hostPattern": "example.com",
              "pathPrefix": "support/cases"
            }
          ],
          "labelText": "Support",
          "localizedLabelText": {
            "es": "Asistencia"
          }
        },
      ]
    }
  }
}

Code.gs

/**
* Entry point for an support case link preview
*
* @param {!Object} event
* @return {!Card}
*/
function caseLinkPreview(event) {

  // If the event object matches the pattern https://www.example.com/support/cases/* pattern that was specified in the link preview trigger:
  if (event.docs.matchedUrl.url) {

    // Parses the URL at the forward slash to identify the case ID that follows the slash:
    const segments = event.docs.matchedUrl.url.split('/');
    const caseId = segments[segments.length - 1];

    // Sets constants for a card header and a text paragraph for the case description:
    const caseHeader = CardService.newCardHeader().setTitle("Case " + caseId +": Customer needs assistance.");
    const caseDescription = CardService.newTextParagraph()
        .setText("Customer needs support with our latest feature.");

    // Returns the card. Uses the text from the card's header for the title of the smart chip:
    return CardService.newCardBuilder().setHeader(caseHeader)
        .addSection(CardService.newCardSection().addWidget(caseDescription)).build();
  }
}

/**
* Entry point for a user profile link preview
*
* @param {!Object} event
* @return {!Card}
*/
function userLinkPreview(event) {

  // If the event object matches the pattern https://www.example.com/people/* that was specified in the link preview trigger:
  if (event.docs.matchedUrl.url) {

    // Sets constants for the header and profile image for the company's CEO, Rosario Cruz:
    const userHeader = CardService.newCardHeader().setTitle("Rosario Cruz: CEO");
    const userImage = CardService.newImage().setImageUrl("https://www.example.com/rosario-cruz-headshot.jpg");

    // Returns the card. Uses the text from the card's header for the title of the smart chip:
    return CardService.newCardBuilder().setHeader(userHeader)
        .addSection(CardService.newCardSection().addWidget(userImage)).build();
  }
}