Xenia: A Domain-Specific Framework for Building Optimized SEO Guest Experiences

December 21, 2017

Co-authors: Ajit Datar, Reza Arbabi, and Chirag Patel


LinkedIn is a network of professionals used by more than half a billion members to meet their professional goals. However, there are even more professionals who are either not on LinkedIn or are registered but don't realize the full potential of LinkedIn and how the site can help them. Helping our existing and potential members organically discover the power of LinkedIn is an important part of our growth. When it comes to organic discovery, search engine optimization (SEO) remains the dominant channel for most use cases.

The principles for building good SEO pages are relatively straightforward. Both Google webmaster guidelines and Bing webmaster guidelines do a good job of educating the SEO community about best practices. However, when applying SEO principles, there are many small things that can go wrong at scale or be implemented in a suboptimal fashion. After building guest experiences for many years, we’ve learned a few things about developing search-engine-friendly guest experiences:  

  1. Build for humans, be friendly to search bots. User experience optimization leads to better SEO. Users like to see quality, engaging content.

  2. Fast is good. Specifically, the time to first paint matters. Server-side rendering (SSR) is still the king.  

  3. Information on the go. While desktop web remains important, discovery is increasingly shifting to mobile web.

With these principles in mind, we set out to build a framework for quickly developing SEO-friendly guest experiences. After the Greek word for guest hospitality, we have named the framework “Xenia.”  

In the following sections, we’ll explain how Xenia is built and how it provides a set of reusable UI components and tools for developing SEO-friendly guest experiences with improved developer productivity. We will also touch upon the tools and techniques we have used to build these UI components.


Xenia is built on top of the Play framework. It consists of two parts:

Xenia frontend  

  • A UI component library implements UI components conforming to LinkedIn's design language, but with SEO best practices baked in.  

  • Play container provides components and Play filters for internationalization (hreflang), A/B testing, and service health monitoring. It also provides built-in support for QPS throttling in case search bot traffic spikes beyond your planned capacity.  

Xenia tools (Some of the Xenia tools are listed below; we have a few more that we’ll skip for brevity)

  • SEO A/B testing library: makes it easy for developers to set up the experiment segments partitioned by URLs. Integration with LinkedIn's internal A/B testing measurement tools is also built in.  

  • SEO Beacon: fires events that collect data about the SEO signals on the page and stores them using our standard Kafka-based data pipeline. The audit tool performs offline analysis of these events to spot negative trends that might hurt the ranking of a page.

  • SEO Linter: provides a real-time analysis of the page from an SEO perspective as the developer is working on it. The tool highlights the sections of the page that might be implemented sub-optimally from an SEO perspective.  

Xenia frontend

LinkedIn infrastructure is optimized for Java virtual machine (JVM) services. We know how to efficiently build, deploy, and monitor Play services. However, Node.js is much faster at executing JavaScript templates than a JVM-based engine such as Nashorn. By hosting a Node.js process inside a Play container, we get the best of both.

  • xenia2

Component library
The UI component library is a collection of modules (JS, CSS, Template) designed as per LinkedIn's Art Deco design language. As an example of how the UI components come together to make a fast guest experience, please see the LinkedIn Learning guest home page screenshot below.

  • xenia3

Xenia’s components are implemented as object hierarchies, thus making it easier to leverage an existing component in order to build a new one.

  • xenia4

Each component is built with SEO in mind. For example, the carousel component preloads content for all the pages in the carousel so that a search bot is able to see the html. In contrast to this, a single page application (SPA) carousel component would optimize for lazy loading the content because it is more efficient for page load time as well as perceived performance.

There are several nice implementation details in the component library. For example, it supports tree shaking. When this library is used in an application, only the modules actually used by the application are pulled in. Unit and UI snapshot testing is supported using Jest. Javascript is written in ES6 syntax and transpiled to browser-optimized JavaScript using babel-preset-env. We provide these as part of the framework to make application and component development easy and reliable, as well as to control the page weight by only targeting the browsers we support. This gives us the ability to use the latest features of JavaScript without sacrificing performance or reliability.  

Xenia tools

We won’t cover all the Xenia tools here; however, we will take a closer look at the SEO Beacon and Audit Tool and the SEO Linter Tool as examples of how Xenia improves SEO effectiveness and developer productivity.

SEO Beacon and audit tool
As mentioned in the overview, the Beacon event fires on every page visit. Based on the page attributes collected by the beacon, the audit tool is looking for some key SEO quality signals, such as:

  • Redirects: Permanent and temporary redirects (i.e., 3XX responses) and JavaScript redirects

  • Blocked URLs: URLs disallowed by the robots.txt protocol

  • Blocked resources: Blocked resources in rendering mode

  • Outbound links: All external links and their status codes

  • Internal and sub-domain links: For instance, links between www.linkedin.com and in.linkedin.com, or links from homepage to sub-directories such as www.linkedin.com/jobs/

  • Page titles: Checking for missing, duplicates, and reasonable length

  • Meta description: Checking for missing, duplicates, and reasonable length

  • File size: Size of URLs and images

  • Last-modified header

  • Page depth level

  • Page weight and word count

  • H1, H2: Checking for missing, duplicates, and reasonable length

SEO Linter
The audit tool catches SEO issues in production at scale. The SEO Linter helps the developers identify issues in the development cycle. Linter rules are either generic rules or rules specific to LinkedIn. LinkedIn-specific rules are provided by the UI library, while the generic rules are provided by the tool. As the Linter walks down the DOM to apply these rules, it highlights the errors in red, as shown in the screenshot below. Hovering over the highlighted error shows the developer more details about the warning/error. The browser’s JavaScript console also shows these warnings and errors.

  • xenia5


Templating languages and rendering technology change. With any technology change, the cost of a rewrite is unavoidable. But with Xenia, we are able to keep tech migrations centralized without losing the search engine optimizations as we migrate.

Xenia tools are already helping us catch issues before they become problems. As we write more experiences, the component library improves too. Development and release cycles are getting shorter and more predictable as the framework matures.

At some point in future, we would like to open source certain aspects of the framework. Stay tuned!  


Xenia wouldn't be possible without LinkedIn's talented SEO engineering team. Chirag Patel, Anand Kishore, Brendan Speth, Sunil Srinivasan, Kyle Blomquist, Damien Beard, and Shanshan Wu built the Xenia framework and tools. Christian Perez, Gaurav Phapale, and Crystal Shang were the early adopters offering useful suggestions and contributions to the framework. Special thanks to Kristopher Baxter, Ash Mishra, and Sarah Clatterbuck from the Application Infrastructure team for providing architectural guidance along the way. Finally, thanks to Erica Lockheimer for supporting the team to help realize the vision.