#258: Fix the Internal Links in the RSS-Feed of MkDocs
The RSS feed plug-in for MkDocs is a bit of a troublemaker. While it works, there is a lot of room for improvement. One big disappointment is the handling of internal links. Unfortunately, the MkDocs pipeline is nothing you want to dive into and so I had to work around the problem.
What is the problem?
To create an internal link to another post in my blog, I use the relative path from the post I am writing to the post file I want to link to. In the build step MkDocs replaces that with the correct absolute link and everything works. The RSS feed uses the relative link, puts it into the description field that then shows up in the RSS reader. If someone clicks on the link, they end up on a site that does not exist.
The link as part of the RSS feed:
./../../2024/248-mkdocs-for-a-blog/248-mkdocs-for-a-blog.md
How it should look instead:
https://pythonfriday.dev/2024/10/248-mkdocs-for-a-blog/
As we can see, the slug is part of both links and that is the common part that we can use.
My approach to fix the links
Since the relative link does not contain the month, I cannot simply work with the feed. I need a different source to find the correct link and then replace the relative link with the absolute one. It helps that I want to fix the problem when MkDocs generated the whole site. That allows me to access the sitemap.xml file with all the pages in the blog. The entries there look like this:
<url>
<loc>https://PythonFriday.dev/2024/10/248-mkdocs-for-a-blog/</loc>
<lastmod>2024-11-22</lastmod>
</url>
My approach to fixing the links involves the following steps:
- Read the sitemap.xml and extract the URLs of the posts
- Turn the links from the sitemap into a dictionary with the slug as the key and the absolute link as the value
- For each RSS feed file, we can now do this:
- find the relative links and create a dictionary with the folder name as a key and the relative link as its value
- Run through the relative link dictionary and replace every relative link with the absolute link from the sitemap link dictionary
Read the sitemap
The sitemap.xml is an XML file inside the generated site. It does not only contain the posts, but all pages, including the archive, the categories and the tags. We can ignore all those pages and only work with the posts where we extract the slug to build our dictionary for the absolute links:
Fix the feed files
We can handle the XML and the JSON files for the RSS feed the same way. We use the list of valid posts from the sitemap and the file as a parameter into our fix_feed() function. There we read the file into a variable, search for links to Markdown files and find the slugs in them. After all these setup steps we can replace the relative link for a specific slug with the absolute one:
Glue everything together
To run all the above methods in the right order, I created this glue code:
The whole code goes into the file fix_feed.py in the folder /scripts. If I now run the script, it turns the relative links into absolute ones and with that fixes this annoying problem in the RSS feed.
Next
With the RSS feed now containing the correct links, we should no longer get errors in the logs. Next week we can explore two more common errors with Material for MkDocs and see how we can fix them with ease.