Content Targeting

When Ultralinks are enabled, a sophisticated process kicks off which tries to figure out what Ultralinks to overlay in which places. The particulars of this process are different depending on whether you are using Ultralinks in the context of a web page or as an app within your operating system. In either case, the default behavior is to intelligently figure out for itself where the content of interest is.

In most cases, you shouldn't have do anything and it will just work. Sometimes though, it can make sense to specifically target content and override default behaviors. This page will help you understand how this process works and how to configure it for your needs.


When running Ultralinks in the context of a web page, you usually do not need or want to overlay Ultralinks in every part of the page. There is usually some central content which we intend to target for analysis and overlay. Once this content is found, it is broken up into paragraph size chunks called fragments. Analysis is performed on each fragment individually as opposed to the content in it's entirety. Per-fragment analysis enables:

As much as possible, the Ultralink code tries to find a happy medium between the number of fragments and average fragment size to optimize for speed and responsiveness. The performance benchmark for Ultralinks is to be fully loaded and ready for use before the user ever hovers their mouse over an Ultralink in the page.

If you are a developer, take a quick peek at the fragments this webpage has been divided into. You can do this by bringing up your browser's JavaScript console and entering Ultralink.highlightFragments(). This will put a light purple highlight on all the fragments in the page. If you then hover your mouse over any of the fragments, you will see a tooltip with a SHA1 hash value of the fragment's content and the CSS selector that found that fragment. We explain what those two values are and why they are important below. (You can reload the page to get rid of the highlights)

Content Selection

Now let's examine how the Ultralink code settled on those fragments for this page. You might have noticed in the JavaScript console that after executing Ultralink.highlightFragments() it output a CSS selector. This is the current CSS selector that the Ultralink code has chosen to use in order to identify fragments in this page. If you enter that selector string into jQuery() it will return all the HTML elements for the chosen fragments.

Outlined below are the steps it tries (in order) to chose the right selector for the page.

Most of the time, this process produces nice results for common content found on the internet. For this specific page, it found that the div#content selector returned the most favorable content results for this page and so it constructed the final div#content p, div#content ul, div#content dl selector and used that to divide the page into seperate fragments.

Custom Selection

In the cases when it might be better to explicitely specify the selector. You can do this any number of ways:

Hard-coded Sites

If it makes sense, you can specify a custom selector for every page and enable it using the scanSelector option but this can quickly become very unwieldly. The hardcodedSites option allows you to pass in a set of regular expression/selector pairs. The current page address is evaluated against the regular expressions in this set and the first match dictates what selector will be used for fragment construction in the page.

You can either pass in these value sets by hand or use the Ultralink Dashboard to manage these value pairs on a per-database basis (this feature is currently in alpha and not yet available to the public).

Scanning Guides

Scanning guides allow for extremly granular overriding of Ultralink settings on a per-fragment or per-UI element basis. For instance, you might want one set of fragments in a web page to be filtered through a specific Ultralink Database and another set of fragments to be washed through a different one. Check out the Scanning Guides documentation for detail on how to use them.

Fragment URLs

Once the fragments for a page have been identified (or in the case of the Ultralink Windows app, once a fragment has been created for the targeted UI element), the next thing that happens is a URL is constructed for each fragment. The structure of that URL looks something like this:
masterPathThe address of the Ultralink Server that will perform the analysis on the fragment.
URL HashA SHA1 hash of the page URL where the fragment resides.
Content HashA SHA1 hash based on the actual content of the fragment.
Database(optional)A postfix identifying the Ultralink Database to wash the fragment through. If not present, it assumes the Mainline Database.
The address of the Ultralink Server that will perform the analysis on the fragment.
URL Hash
A SHA1 hash of the page URL where the fragment resides.
Content Hash
A SHA1 hash based on the actual content of the fragment.
Database (optional)
A postfix identifying the Ultralink Database to wash the fragment through. If not present, it assumes the Mainline Database.

The URL Hash and Content Hash uniquely identify (within reason for this use case) this specific fragment inside this specific page. If even one character changes in either the page URL or the fragment content, then their respective hashes will change and it is considered to be a new and distinct fragment. All these parts come together to form a URL that references the results of this specific fragment washed through the specified database.

Result Retrieval

By performing a simple HTTP GET on this URL, clients like ultralink.js will recieve one of two kinds of results back. It will either receive a JSON object describing all the Ultralinks from the specified database present in the fragment along with a field called type with a value of hit. Or, it will receive a JSON object with the type field and a value of miss indicating that the Ultralink Server does not currently have the Ultralink result set for that fragment (essentially a cache miss).

In the case of a miss, ultralink.js will perform an HTTP POST to a similar URL on the Ultralink Server (it replaces /fragment/ with /fragmentFilter/) and passes the fragment content up to the Ultralink Server for analysis. The response to that POST command is a new JSON object containing the description of the Ultralinks present in the fragment. After that point, the originally constructed URL will now return that same result set when queried (unless the nostoreSites setting is specified which tells the Ultralink Server to not store the results).

Result Caching

The compact and identifying nature of the above URL format allows for a simple interface to fragment processing and is also condusive to URL level network caching. Ultralink Servers support high-level caching services like CloudFlare in addition to their own built-in result caching system. (Check out our blog post on using CloudFlare as a DB Read Cache)

Unless otherwise specified, the fragment content and the Ultralink result set are stored in a per-database cache on the Ultralink Server. This allows the server to return result sets extremely quickly for fragments that it has already seen and allows it to re-calculate old result sets when changes are made to the relevant Ultralink Database. This cache deletes old fragment content and result sets if they have not been accessed in the last 31 days.