Designing a content recommendation module

< Blog home

Bibblio’s AI-driven recommendation utility connects customers’ articles to the rest of their relevant content. The most common way to do this is through in-page, pre-designed modules. These sorts of widgets are becoming ubiquitous, but how easy is it to design a customizable module to run on thousands of sites?

Making a content recommendation module with in-built customization work for as many customers as possible was quite a challenge. It needed to be very robust yet flexible enough to be sure the customer could tailor the design to their site. Starting off we didn’t quite realise the Pandora’s box it would open - what seemed straightforward on paper quickly escalated into an intricate project full of complications, but fortunately the hard work paid off. Here’s our process:

The framework

We started off by creating a framework that could generate recommendations on an article page. Each ‘rec’ would include the title, author, date published, featured image etc. From here we knew the boundaries, at least technically. We also knew that different customers would want the module to vary in layout and style, so we needed to factor this in.

With the framework generated in JavaScript we were keen to have the JS file as generic as possible and not limit the uniqueness each customer might need. This left the style sheet as the safest place to inject variety.

So we built a module whose parent element could call multiple classes, each controlling different facets, such as layout, tile ratio and effects. These class names can then be added to a module via a module builder, which is essentially a designer’s toolbox for setting the look and feel by toggling features on or off. This then outputs a string of classes to a snippet maker or similar.

Bibblio's module builder interface (version 4)
Bibblio's module builder interface (version 4)

The classes can also be manually added by developers accessing the API and module code directly. This had the extra benefit of helping our customer onboarding teams – the class names became a lexicon they could communicate with. If a customer wanted a certain feature and we could provide it, the team member could message them with the appropriate class name, and the customer could append it. This avoids any vagaries during design implementation.

The layout

Websites differ greatly in their design, but there are some fundamentals that content pages invariably follow. These are well known and each site will have several or all of them, such as a wide column to house the body content, an area beneath this content for successive activity and a narrower right (sometimes left) column for sticky content.

Vertical and horizontal strategies for satisfying user needs

The different areas of a page should be geared towards different types of user journeys. For example, content beneath the main body would employ a more vertical strategy since the user read all the way to the bottom and was likely to be invested and interested in the topic. Whereas content in the right column starts much further up and would attract users who are applying a softer touch, skimming the page, with less keenness of interest in the page’s content. These can be drawn to broader topics or redirected entirely through a more horizontal strategy.

With all this is mind, we needed module layouts that could cater for both strategies. The classic row-of-three, used by many content recommenders was definitely a starting point. There is no need to reinvent the wheel, and it has proved its popularity by being the most used layout of our customers. We offer this layout as the default, so whether it’s actually popular or customers just refuse to deviate remains to be established.

Some of the 16 module layouts available
Some of the 16 module layouts available

From there, we went two smaller and one larger, with a row-of-one, row-of-two and row-of-four. We stopped at four because most websites would not comfortably fit any more tiles in a row without them becoming too small and impacting their effectiveness. Also, choice fatigue can set in if there are too many options in a sequence.

This doesn’t mean four is our display limit. We’re pulling in six recommendations after all. (We actually supply 20 recs per item, so a developer could do much more with the data if they wanted, such as a ‘search results’ style page or a carousel.) A grid-of-four and a grid-of-six were created, the latter being three tiles across. When recs are stacked in rows the eye can scan and discern more effectively than a long single row. 

Also for impact we created four showcase layouts that used a larger tile to draw attention to the first rec. A box-of-3 where the second and third recs sit stacked to the right of the first, a box-of-4 similar to the previous but with three stacked (since deprecated in later versions due to the stacked tiles being too small to be effective), a box-of-5 where two large recs sit above a row of three, and a box-of-6 where the second and third recs sit to the right of the first and a row of three tiles sit beneath them all.

Lastly, we looked at the narrower columns in most web pages, catering to horizontal strategies. We created a column-of-two through to a column-of-six. In our latest module release (version 4.x) we added two text-only modules after feedback from our customers. So a list-of-three and list-of-six were devised. We have also betaed several mobile-only layouts displaying the next rec anchored to the bottom of the interface.

Another dimension

Next we addressed tile ratios. This initially applied to all tile layouts except the showcases, but in version 4 we brought that flexibility to all types. Each customer has a different preferred width and height for their featured imagery, so we wanted to be sure their pictures would look their best in the tiles.

The four tile ratios

The default was 4:3, the standard “TV” ratio of old, and a common postcard-shaped area. Below this came widescreen (16:9) and above it, square (1:1). We chose this variety so that customers could adopt the one that most suited their imagery without trimming too much off inside the tile. As we rolled out we received feedback from customers who preferred to use portrait images as their main picture, so we incorporated tall (2:3) into our latest module version. This is also great for customers who have books or journals as recommendations.


When it came to the appearance of the tile we needed it to be impactful but not overwhelming on the page. It also needed to look different enough from the offering at that time. The content’s featured image would display as the background, with a watermark pattern as substitute if no image was available.

Black backgrounds were the safe choice for legibility

The title would be written in white with a transparent to black vertical linear gradient behind it, so that it stood out. We experimented with dark text on a white gradient or various colors but decided the effect was too washed out and lost the impact. The other text elements within the tile (three properties: author, date published and site name, and a text preview) maintain a hierarchy of importance based on their proximity to the title and differing levels of opacity.

Users could see the text preview by hovering the mouse over each tile. The title and other properties slide upwards to reveal the preview sliding in below it. In version 4 we also have display controls to show the image only, with the title revealed on hover, and title only with the properties revealed on hover.

Provision was made to choose the font style of the headline based on a handful of cross-platform system fonts. We didn’t make it too expansive as we wanted to provide a core that we knew would render identically across operating systems, and we knew ten fonts that would. We also created five font size settings from 14 to 22 pixels.


With our default design finalized we needed to cater for the alternative – an image with text beneath it. So we created the “Separate text” format. This started life as a white box with the title and other text elements inside, sitting on top of the image, anchored to the bottom. This worked well but wasn’t too elegant as the white box would eat into the image if the title length was long. Situations with a lot of title length variety made the rows look like crooked teeth. Also, if the preview hover was activated, the content would slide up to reveal the preview whilst obscuring yet more of the image.

Titles create a crooked teeth effect, corrected in later versions

In version 4 we totally re-wrote the module from the HTML upwards, favouring instead that the title and other text elements sit beneath the image at all times. When the preview hover is now activated, the preview is revealed on top of the title and other text only. As the text did not require a white box to mask the image, this layout could sit smartly on backgrounds that were off-white. We also created an invert class so that all text would appear as white on darker backgrounds.

The image also had a little more freedom, with the customer able to set the vertical alignment of their images within the tiles. So for example, if their images were square in shape with the focal point of most of them happening at the top, but aesthetically they preferred a widescreen ratio on their tiles, they could set the alignment to top, and the images would always anchor themselves to the top of the tile. (The default is set to middle.)

The shine and spectrum hover effects

We decided to add a bit of sparkle to our titles by including a hover-over effect called shine. When the mouse is passed over a tile a white shine slides in from the right corner of the image, using a CSS gradient. In version 4 we went one further and created a spectrum effect, using a more complex CSS gradient to make a rainbow appear.

All this was made fully responsive, so that the tiles degrade gracefully across devices.


There are a lot of moving parts going on here. With over 1,350 possible combinations, there’s a lot of risk that a certain class sequence will cause unexpected results. Any improvement we make goes through a vigorous testing process to ensure that that area of the module performs as expected under all conditions and device sizes.

Having said that, it’s a surprisingly robust creature! Even more so in version 4. I mentioned our rebuild earlier – this was a significant departure from the original related content module. Initially we wanted to be as semantically pure and backwards compatible as possible when it came to structure. The module was composed of an unordered list with list items for each tile, containing an anchor that housed spans. (Although HTML5 permits block elements such as headline and division inside anchors, some online code editors are trailing behind and can sometimes declare any block children within an inline as invalid and delete them. We avoid this risk by keeping it all inline.)

Related Posts for WordPress by Bibblio plugin page

This worked well until we released our WordPress plugin. The plugin lets WordPress users quickly add the module onto their site, giving them internal recommendations in moments. WordPress is a complex beast, because beyond the standard setup you can choose from thousands of design themes to render your site. You can also pick from thousands of plugins that can handle back-end processing, publishing, AMP delivery, design output – you name it. This makes each WordPress site a “snowflake” (as one of our developers likes to put it) – each one is unique and what works for some might not work for all.

Integration with WordPress has been in the main a nice straightforward process. For those that are daisy-chaining plugins in mind-fizzing knots or have re-written entire chunks, there’s always a little more TLC required. But that’s okay, each site is different – we can handle uniqueness. It’s when a theme-producer creates what we call an “overzealous style sheet” that we become frustrated.

For example, a theme might contain a style sheet that declares that all unordered lists throughout the site must conform to a certain style, or that every anchor element on the site will react with a certain type of hover effect. These are often blanket classes, swallowing up all parts of the page, including third party plugins. They might nest this overzealousness within named parent classes, but the damage is done – unexpected results occur on unsuspecting plugins. This forces plugin creators to litter their own style sheets with !important declarations to ensure their styles override any indiscriminate theme classes. A frustrating but necessary evil. Site owners might wish to take this into consideration when picking their theme, to ensure easy integrations with UI plugins.

The original semantic structure of the moduleImprovements to the semantic structure of the module
The element depth of version 4 is shallower but the information blocks are segregated to allow for better display control

So in version 4 we did away with unordered lists, keeping instead six anchor elements containing spans. That shored our module up, knowing we would no longer have any surprises from ill-considered classes manipulating the UL or LIs. We just needed to keep the anchor in check and all would be well.

The future

We’re really happy with where we are right now. We’re constantly listening to customer feedback, as they are closest to the end users. They have a strong understanding of what works on their sites, but always welcome our UI advice to make the most of their page real estate. We’re always exploring new module layouts that can enhance the user experience on both desktop and devices, and are keen for any feedback and suggestions for how we can improve the designs. Our mobile-only layouts are the next step in achieving this, and further forward we’ll be exploring in-content and feed-based interfaces that will drive further pages views and engagement.

Related articles

Related articles

Publishing in peril

Web users have enjoyed free access to content for years, which has meant some digital publishers are having a tough time of it. To make money they either put up a paywall or rely on ads and clickbait. Google and Facebook offer easy ways to share content, but these referrals are fickle, hard to monetize, and dependent on algorithms that can change in a heartbeat.

In this ecosystem, quality journalism cannot thrive, replaced instead by sensationalist content and filter-bubbled fake news. The experience for users is jumbled and distracting, putting customer loyalty at serious risk.

Help is at hand

Bibblio's discovery platform lets publishers increase engagement, build loyalty and improve how they monetize. Our AI understands the context of each content item, recommending it at the right place and time, recirculating the publisher's content and personalizing their audience's experiences across any touchpoint.

Using either light-touch self-serve tools or running deeper integrations with support from Bibblio's engineers, these successful publishers have found smarter ways to deliver value through their sites, gain a better understanding of their audience and return their focus to quality editorial.

Subscribe to the Vertical Heroes newsletter

Get the latest in vertical publishing in your inbox, from interviews and trending news to events.