3

TLDR: links to assets (such as images) inside Hugo page bundles are not rendered relative to the blog's root by blogdown/knitr, instead they are produced relative to the blog post's root, which works in the browser but breaks in RSS feed readers.

Issues related to relative links in RSS feeds generated by blogdown/hugo have been raised before:

But I think there is something new going on, and it's related to how page bundling has moved the assets inside each blog post's directory (whereas before bundling, assets lived in a single directory inside the blog root).

To provide an MWE without this question ballooning even more than it already has, I did all my tests on a new blogdown site, created like this:

usethis::create_project("bundlesofjoy")
blogdown::new_site(theme = "hugo-apero/hugo-apero", format = "yaml", sample = FALSE, empty_dirs = TRUE)

I made just a few changes to this site, all recorded in this github repo (in short, I reset the baseURL and set publishDir, and changed the default RSS template to get full-text feeds). Outside the repo, I created an Apache vhost so that I (or indeed, anyone) can access this site and its RSS feed. So that's an external MWE, in effect ;-)

We should note, that the Hugo Apero theme uses page bundling out of the box. I generated the site using Rscript -e "blogdown::build_site(local=FALSE, build_rmd='md5sum')". (What matters here is local=FALSE, meaning our baseURL is respected by blogdown).

The problem

All links to assets inside page bundles are broken in the RSS feed when using relative links in the Rmd source. It does not matter whether images are inserted using markdown format (![](image.png)) or using knitr::include_graphics("image.png"). Note that the very same links are rendered just fine in the browser -- the problem becomes apparent when reading the blog post in an RSS reader.

The reason seems clear enough: the RSS reader appears to resolve the relative image paths in the HTML source versus the blog feed URL //joys.solarchemist.se/, and not versus the blog post URL //joys.solarchemist.se/blog/fonts/. And I can't really blame RSS readers for doing this, how should they know when to do it one way or the other?

To bolster my confidence in my own conclusions, I did some testing:

In Rmd source In browser? In RSS reader?
include_graphics("isaac-font.png") ✓ OK
![](font-static-files.png) ✓ OK
include_graphics("blog/fonts/isaac-font.png", error=F) ✓ OK
![](blog/fonts/font-static-files.png) ✓ OK
include_graphics("/blog/fonts/isaac-font.png", error=F) ✓ OK ✓ OK
![](/blog/fonts/font-static-files.png) ✓ OK ✓ OK
include_graphics("//joys.solarchemist.se/blog/fonts/isaac-font.png", error=FALSE) ✓ OK ✓ OK
![](//joys.solarchemist.se/blog/fonts/font-static-files.png) ✓ OK ✓ OK

I tested this in Firefox and TinyTinyRSS, which was readily available to me. (I also did some testing in Newsblur, but it seems that RSS reader employs some caching of the feed, because all images stayed broken irregardless of changing the RSS XML file at the server).

The solution...?

I think that blogdown/knitr should make sure that all relative links they generate are relative to the blog site root and not to the blog post root.

As it is now, image links to bundled assets (whether using ![]() or knitr::include_graphics()) end up relative to the blog post root instead of the blog site. I think that blogdown/knitr should continue to allow/encourage the blog writer to specify asset links relatively, i.e., include_graphics("isaac-font.png"), but these need then be rendered into <img src="/blog/fonts/isaac-font.png"> and not <img src="isaac-font.png"> (the latter breaks in most RSS feed readers, whereas the former should work everywhere, as our table above shows).

Note that plots generated from R code chunks are already getting proper relative links, and since the advent of bundling these assets also live inside the blog post's root (e.g., see this R Markdown blog post from the same test site). They render fine in RSS readers, because their <img src=... links are always relative to the site root. So it appears knitr already has some mechanism that creates links relative to the blog root.

Do you have any suggestions on how to get properly rooted relative links for images when using blogdown?

Additional notes, some attempted work-arounds

Adding relativeURLs: false and canonifyURLs: true to config.yaml had no effect.

Changing baseURL: "//joys.solarchemist.se/" to baseURL: "/" does not help at all (obvious, in hindsight).

Using Hugo link render hooks or similar to edit all relative links in the RSS feed (index.xml) after the fact feels like a much more complicated solution. Plus, I have no experience with those.

Some more relevant discussion threads:

solarchemist
  • 438
  • 3
  • 13
  • Opened a ticket in the knitr repo: https://github.com/yihui/knitr/issues/2037 Also, I somehow missed this very relevant discussion in the blogdown issue queue: https://github.com/rstudio/blogdown/issues/384. – solarchemist Aug 24 '21 at 13:00

0 Answers0