Improving SEO with the Recommendations Component
Explore how to create a configurable Recommendations component in Astro that automatically suggests related posts under each article. Learn to use Astro's collection API and JavaScript array methods to generate dynamic recommendations, improving SEO through effective interlinking. Understand styling for responsive layouts and combining recommendations with other components for consistent page design.
We'll cover the following...
Interlinking plays a crucial role in enhancing SEO and boosting rankings by connecting relevant pages through links. A quick way to automate the process of interlinking is to create a list of recommendations under each post, where users can explore other related topics. In this lesson, we’ll take a look at how we can build a responsive Recommendations component in Astro and how we can reuse it in several places with other components combined.
Creating Recommendations
To get started, let’s see how we want to use the component first. According to the design, we want to display three recommended posts in a responsive manner.
Because the list of recommendations will be different on each page, we need this component to be configurable. Because it’s easier to remember slugs, let’s make the component capable of accepting a list of recommendations in the form of URLs.
To get the relevant posts based on their slugs, we can use Astro’s collection API along with a .filter array method to only keep the posts that are passed to the recommended prop. This functionality has already been implemented in the Recommendations component in the code widget below. See how we get the correct posts in src/components/Recommendations.astro.
---
title: "Latest Astro Post Title"
description: "Description for the post"
publishDate: "2023.06.19"
heroImage: "https://images.unsplash.com/photo-1581500274180-6331eea8b184?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxzZWFyY2h8OHx8YXN0cm98ZW58MHx8MHx8fDA%3D&auto=format&fit=crop&w=1200&q=60"
excerpt: "Excerpt from a recommended article. Content is trimmed to a maximum of 150 characters for brevity. If the content exceeds the character limit, three dots will be displayed using JavaScript's `substring` method."
faq:
- id: 1
question: "Post with FAQ"
answer: "FAQ answer"
open: true
- id: 2
question: "FAQ 2nd Question"
answer: "Answer to 2nd FAQ"
---
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Vitae ultricies leo integer malesuada nunc vel risus commodo viverra. Adipiscing enim eu turpis egestas pretium. Euismod elementum nisi quis eleifend quam adipiscing. In hac habitasse platea dictumst vestibulum. Sagittis purus sit amet volutpat. Netus et malesuada fames ac turpis egestas. Eget magna fermentum iaculis eu non diam phasellus vestibulum lorem. Varius sit amet mattis vulputate enim. Habitasse platea dictumst quisque sagittis. Integer quis auctor elit sed vulputate mi. Dictumst quisque sagittis purus sit amet.
Morbi tristique senectus et netus. Id semper risus in hendrerit gravida rutrum quisque non tellus. Habitasse platea dictumst quisque sagittis purus sit amet. Tellus molestie nunc non blandit massa. Cursus vitae congue mauris rhoncus. Accumsan tortor posuere ac ut. Fringilla urna porttitor rhoncus dolor. Elit ullamcorper dignissim cras tincidunt lobortis. In cursus turpis massa tincidunt dui ut ornare lectus. Integer feugiat scelerisque varius morbi enim nunc. Bibendum neque egestas congue quisque egestas diam. Cras ornare arcu dui vivamus arcu felis bibendum. Dignissim suspendi
---
## Title
Morbi tristique senectus et netus. Id semper risus in hendrerit gravida rutrum quisque non tellus. Habitasse platea dictumst quisque sagittis purus sit amet. Tellus molestie nunc non blandit massa. Cursus vitae congue mauris rhoncus. Accumsan tortor posuere ac ut. Fringilla urna porttitor rhoncus dolor. Elit ullamcorper dignissim cras tincidunt lobortis. In cursus turpis massa tincidunt dui ut ornare lectus. Integer feugiat scelerisque varius morbi enim nunc. Bibendum neque egestas congue quisque egestas diam. Cras ornare arcu dui vivamus arcu felis bibendum. Dignissim suspendi
- List
- With
- Items
- With Adjusted Styles
The component also accepts two other props: noMargin (line 7) and inline (line 8). These props control how the cards are displayed. These are used as conditional classes using the class:list (line 17) directive. However, we’re currently missing a crucial part of the component—the contents of the ul element. Replace TODO with a loop that iterates through recommendedPosts. For each recommendation, display li containing a Card component with the following props:
post: This contains the details of the post. Pass the entire object from each iteration as the value.inline: This determines whether the card is displayed inline. Pass theinlineprop as the value.showExcerpt: This controls whether to show the excerpt of the post. Pass theinlineprop as the value to this as well. This means we only show the excerpt for the card if theRecommendationscomponent is set to be displayed asinline.
We’re also missing the styles for the component. To display the recommendations as a grid of cards when the inline prop is set, append the following to the Recommendations component at the end of the file:
With the rules given above, the container of the Recommendations component will have flex-direction set to column (line 12). This ensures that each card will be displayed under each other for small devices. For larger viewports (greater than 600px in this case), the cards will float next to each other by setting flex-direction to row (line 22). Open the home page to verify if the component is displayed correctly.
Note: We have a
.no-marginhelper class insideglobal.css. That’s why we don’t need to create the styles for it here. This way, it can be reused across different sections.
Recommendations with FAQ
Currently, the recommendations appear below the FAQ component. However, on larger breakpoints, they’re displayed next to each other. The same layout can be applied to the contact page. This means we can potentially combine them into a shared component for a consistent layout. There is an empty file inside the components folder called FAQWithRecommended.astro. Open the file and add the Recommendations and FAQ components next to each other with the following styles included:
This will align the FAQ and Recommendations components side by side on viewports larger than 900px (lines 31–35). Open index.astro in the code widget above and replace both the FAQ and Recommendations components with this new component.
Generating recommendations for posts
For every post, we want to generate unique recommendations. To achieve this, we’ll get the surrounding posts of the current page. This means we want to end up with the following functionality:
To achieve this, we’ll need to follow these steps:
Get all posts using Astro’s
getCollectionfunction. This will return an array with all posts.Find the current post using its ID.
Get two adjacent posts from both sides of the current index. We’ll end up with an array of five posts: four surrounding posts and one post for the current page.
Exclude the current page from the array, leaving only posts other than the current page.
Trim the array so that we end up with the first three items.
The final array will be the list of recommendations that we can display under each post. Let’s examine how this translates into JavaScript code.
Line 2: The function expects a
postobject to be provided. Based on this object, we can find the passed post’s index in the list of posts using thefindIndexarray method.Line 3: Starting from this index, we can get two neighboring posts using
index - 2andindex + 2. Theslicemethod will return a new array with the five posts.Lines 5–10: Because the
Recommendationscomponent expects a list of post slugs, we can usemapto return only thepost.slugproperty. This is where we want to filter out the passed post using afiltermethod.
Note: We can also add the default recommendations to the returned array to make sure we always end up with an array with three items.
To use this function, open [...post].astro inside the pages folder and add the function inside the getStaticPaths function, then reference it as a new prop inside map that is returned from the getStaticPaths function.
Because we have a new prop, don’t forget to add this prop as a type inside the Props type above the getStaticPaths function. As this function returns a list of strings, we can change the Props type to the following:
To make use of the data returned from the prop, destructure the recommended prop from Astro.props, then call the Recommendations component within the end of the article element. Don’t forget that we’ll also need to import the Recommendations component into the page.
Now, automatically generated recommendations will appear under each post. Whenever we add a new post to our project, it will be automatically linked to other pages and show up as a recommendation. This process automates the work of manually adding links to our post pages to ensure that our entire website is interlinked and there are no
As stated at the beginning of this lesson, this process is called interlinking, which boosts SEO and helps with ranking by connecting relevant pages through links. Now, users can easily reach other topics of interest that are relevant to the current page under each post.