---
title: Linking
description: MediaPress Linking enhances inline linking in the block/site editor to allow searching for highlighted text, advanced filtering, custom sources and more.
url: https://developers.wpengine.com/docs/newsroom/mediapress/linking/
image: https://developers.wpengine.com/og/docs/newsroom/mediapress/linking.png
---

# Linking

MediaPress Linking enhances inline linking in the block/site editor to allow searching for highlighted text, advanced filtering, custom sources and more.

Out of the box, WordPress post types can be used as sources to search for links, to provide a more powerful version of the core WordPress link insertion functionality with additional filtering options and a streamlined workflow.

Custom sources can also be registered, allowing inline linking to search and insert links from external sources, for example, third-party APIs and search indices.

## Additional Configuration

Linking must be activated via the “MediaPress” settings page. By default, it will allow any public post types to be searched against as link sources. This usually means ‘posts’ and ‘pages’ on a blank WordPress installation. For custom post types to appear, they should be made available to the REST API and be public/publicly queryable.

## Filters/Actions

### JavaScript

#### Filters

##### `mediaPress.linking.sources`

Allows for customization of available link sources. The default link sources are from published content in the `page` and `post` built-in post types.

This filter can be used to register new `core` or `custom` sources, and to customize/remove any core sources if required.

Sources may include a ‘supports’ object, which controls the date and taxonomy filters shown when searching against a source. A ‘context’ parameter is passed which can enable the filter to only be applied in specific circumstances.

Custom sources require a `getResults` callback, which receives the current `query` data and is expected to return an array of link items, as well as the total number of search results for pagination. Find `@typedef {Object} EntityLink` for information on the properties of each link item.

**Parameters**

| Name                                        | Type                     | Description                                                                                      |
| ------------------------------------------- | ------------------------ | ------------------------------------------------------------------------------------------------ |
| sources                                     | `Array<Source>`          | An array of source objects                                                                       |
| source\[value]                              | `Source`                 | The source object                                                                                |
| source\[value].name                         | `string`                 | The display name for the source, shown in the user interface                                     |
| source\[value].slug                         | `string`                 | Unique slug for the source                                                                       |
| source\[value].type                         | `"core"\|"custom"`       | The source type. ‘core’ if the source is a WordPress post type. ‘custom’ if the source is custom |
| source\[value].getResults                   | `SourceResultsCallback?` | The function to get the results for the source, required for custom sources.                     |
| source\[value].supports                     | `Object?`                | The optional supports object                                                                     |
| source\[value].supports.dateRange           | `boolean?`               | Whether the source supports date range filtering                                                 |
| source\[value].supports.taxonomies          | `Object?`                | The taxonomies support object                                                                    |
| source\[value].supports.taxonomies.category | `boolean?`               | Whether the source supports category taxonomy filtering                                          |
| source\[value].supports.taxonomies.post_tag | `boolean?`               | Whether the source supports post_tag taxonomy filtering                                          |
| context                                     | `string`                 | The context that the search UI is being displayed                                                |

**Usage**

```js
addFilter(
  'mediaPress.linking.sources',
  'my-plugin/register-google-source',
  (sources, context) => {
    if (context !== 'my-component') {
      return sources;
    }


    return [
      ...sources,
      {
        name: __('Google', 'my-plugin'),
        slug: 'google',
        type: 'custom',
        getResults: async (query) => {
          if (!query.search) {
            throw new Error(__('No search query provided', 'my-plugin'));
          }


          try {
            // Google Custom Search limits
            // - num (per page) max 10
            // - start is 1-based and start + num must be <= 100
            const perPage = Math.min(Number(query.per_page) || 10, 10);
            const page = Math.max(Number(query.page) || 1, 1);
            const zeroBasedPage = page - 1;


            const maxStart = Math.max(1, 100 - perPage + 1); // e.g. perPage=10 -> 91
            const start = Math.min(zeroBasedPage * perPage + 1, maxStart);


            const params = new URLSearchParams({
              key: API_KEY,
              cx: CX,
              q: query.search,
              num: String(perPage),
              start: String(start),
            });


            const res = await fetch(
              new URL(
                `https://customsearch.googleapis.com/customsearch/v1?${params}`,
              ),
            );


            const data = await res.json();


            const items =
              data?.items?.map((item) => ({
                title: item.title,
                preview: item.displayLink,
                meta: {
                  source: item.displayLink,
                },
                // attributes will be added to the link when it is inserted
                attributes: {
                  href: item.link,
                  'data-product-id': '000',
                },
              })) || [];


            const reportedTotal =
              Number(data?.searchInformation?.totalResults) || 0;
            const totalItems = Math.min(reportedTotal, 100);


            return {
              items,
              pages: Math.max(1, Math.ceil(totalItems / perPage)),
              total: totalItems,
            };
          } catch (error) {
            throw new Error(
              __('Error fetching Google search results', 'my-plugin'),
            );
          }
        },
      },
    ];
  },
);
```

## Was this helpful?

Thanks for the feedback!

```json
{"@context":"https://schema.org","@graph":[{"@type":"WebSite","@id":"https://developers.wpengine.com/#website","name":"WP Engine Product Documentation","url":"https://developers.wpengine.com/","description":"Resources for developing, deploying, and scaling on WP Engine.","inLanguage":"en-US","keywords":["API documentation","product documentation","headless WordPress","managed WordPress hosting"],"publisher":{"@id":"https://wpengine.com/#organization"}}]}
```
