Mugo Web main content.

Content auto-linking for better SEO and increased conversions

By: Thiago Campos Viana | January 2, 2015 | Business solutions, eZ Publish development tips, User experience, auto linking, links, and SEO

Links are one of the core elements of the web. Links within body content are not only good for user experience, but also for SEO, engagement, and conversion. As we read, for example, a sports article, there might be links on the athlete names pointing to their biography pages. Or, when reading an author's bibliography, the book titles contained therein might be linked to the book pages. Adding and maintaining such in-body links can be very time-consuming; systems that auto-link the text can be a great help for content publishers.

Going back to the example of the author's bibliography: if a user reads the title of a book but that title is not linked, the user might do a Google search and find the book on another site. By ensuring that the title of the book is linked to another page on the same website, we can keep the user on the site. This can lead to increased sales, page views, and more. On the user experience side, not only do links help them find what they're looking for easier, but it can also draw their attention to important keywords.

The image below illustrates a simple example of how an auto-linking script could work:

Auto Link Example

Using book titles as keywords, the system can not only link to existing book pages in the system, but also automatically link to new book pages as they get added to the site.

Such an approach has been around for many years in other forms. For example, I have seem some in-text advertising systems that allow advertisers to bid for certain keywords, and show an in-text pop-up advertisement when the user hovers over the linked keyword:

In-text ads

We can also show more information than just the link. For example, a business article that mentions multiple company names could not only link to company profile pages but also display the latest stock price for each company within the text:

Dynamic content next to the link

Technical implementation

Here's a general technical approach that provides auto-linking functionality. We recently implemented this for the Canadian book community website 49th Shelf, running on the eZ Publish content management system.

Given a certain piece of text, we need to match against a list of phrases to link, but we also need to make sure that the text is not already linked. The example below checks against eZ Publish's internal data format:

    /**
     * Check if a text (subject) contains a certain linked string (name) in the ezxml format
     * @param string $name 
     * @param string $subject
     * @return boolean
     */
    public static function isLinked($name, $subject)
    {

        $pattern = '/<link node_id\=\"[0-9]+\".*>' . preg_quote($name) . '\<\/link\>/i';

        return preg_match($pattern, $subject);
    }

We can do a very similar check against standard HTML links:

    /**
     * Check if a text (subject) contains a certain linked string (name) in html format
     * @param string $name 
     * @param string $subject
     * @return boolean
     */
    public static function isLinkedTemplate($name, $subject)
    {

        $pattern = '/<a href=\"([^\"]*)\">' . preg_quote($name) . '\<\/a\>/i';

        return preg_match($pattern, $subject);
    }

To check whether a text string contains the phrase to link, we can do a simple check like this:

    /**
     * Check if a text (subject) contains a certain string (name) in the ezxml format
     * @param string $name 
     * @param string $subject
     * @return boolean
     */
    public static function hasName($name, $subject)
    {

        $pattern = '/' . preg_quote($name) . '/i';

        return preg_match($pattern, $subject);
    }

If the text string has the phrase in question but is not already linked, we can thus insert the link:

// HTML approach
if (!self::isLinkedTemplate($name, $text) && self::hasName($name, $text) )
{
    $text = self::createLinkTemplate($name, $url, $text);
}
// eZXML approach
if (!self::isLinked($name, $text) && self::hasName($name, $text) )
{
    $text = self::createLink($name, $nodeID, $text);
}

The code to insert the link is relatively straightforward, and can be extended to add additional information such as advertising code or stock price information as mentioned above.

    /**
     * Updates a text replacing a string with a link for a certain node in eZXML
     * @param string $name
     * @param int $nodeID
     * @param string $subject
     * @return string
     */
    public static function createLink($name, $nodeID, $subject)
    {
        return preg_replace('/' . preg_quote($name) . '/i', "<link node_id=\"{$nodeID}\" custom:onclick=\"\">{$name}</link>", $subject, 1);
    }

    /**
     * Updates a text replacing a string with a link for a certain URL in HTML
     * @param string $name
     * @param string $urlAlias
     * @param string $subject
     * @return string
     */
    public static function createLinkTemplate($name, $urlAlias, $subject)
    {
        return preg_replace('/' . preg_quote($name) . '/i', "<a href=\"{$urlAlias}\">{$name}</a>", $subject, 1);
    }