Closed aronmolnar closed 3 months ago
This has also been observed by others: https://github.com/squidfunk/mkdocs-material/discussions/6982#discussion-6431553
Confirming the issue. It's also being reported upstream: https://github.com/google/fonts/issues/7481
Assuming that Google don't reverse their change, what would be a sensible solution? I could imagine downloading the needed fonts manually and pointing the social plugin at them. That way I could also use fonts that are not on GF. If they did reverse it we'd still win that.
I'm also having this issue building my docs - https://github.com/beekeeper-studio/beekeeper-studio/actions/runs/8469768189
This only started when I upgraded to 9.5.15
, but seems like that is unrelated?
Yes, this is a change on Google's side that broke the automated font downloading.
@kamilkrzyskow should one of us do a PR that introduces a "I have the fonts locally" option? Should not be too difficult to bypass the downloading and unzipping from Google but it does not make sense for us to do this in parallel. Squidfunk can then do what he likes with it - incorporate it, provide an alternative, fix it, whatever. Seems important to fix this asap as it will affect a lot of people?
Any workaround folks? I can't deploy a new release.
For right now the only thing I can suggest is to turn off the social plugin. There should be a fix tomorrow, I think. IMHO downloading the fonts from Google Fonts was a convenience function that now no longer works. I will start looking at a PR to fix this issue with a local font option. That leaves open the possibility of automating it should that become feasible again but gives us a plan B.
Affecting us also.
Ok, here is a workaround of sorts in the hope that this helps some people in the short term. Edit: this is for the Insider Edition, instructions for the public version see post https://github.com/squidfunk/mkdocs-material/issues/6983#issuecomment-2026642907 by @jbott below.
Download the font(s) you need from Google Fonts manually and install them in the .cache
directory following this recipe, adjusting it as necessary:
export FONT_FAMILY=Inter
mkdir -p .cache/plugin/social/fonts/$FONT_FAMILY
cd .cache/plugin/social/fonts/$FONT_FAMILY
unzip ~/Downloads/$FONT_FAMILY.zip .
mv static/*.ttf .
mv static/*.otf .
Now, rename the fonts to have only the variant in the name, i.e., get rid of the family name in it. That should leave them in the cache in the way the plugin expects them and it will skip the trip to Google Fonts.
Would be good if someone could try this and give feedback in case I made a mistake. I constructed the cache layout from what I got after running the code in my PR, which I am about to send off to @squidfunk. Might take a few hours before he sees it, please bear with us.
Edit: simplified by unpacking from Downloads directory
Also, this is what the result looks like for the Inter font family:
$ ls -l .cache/plugin/social/fonts/Inter
total 5544
-rw-rw-r--@ 1 avoss staff 316848 Sep 15 2023 Black.ttf
-rw-rw-r--@ 1 avoss staff 316584 Sep 15 2023 Bold.ttf
-rw-rw-r--@ 1 avoss staff 317184 Sep 15 2023 ExtraBold.ttf
-rw-rw-r--@ 1 avoss staff 311232 Sep 15 2023 ExtraLight.ttf
-rw-rw-r--@ 1 avoss staff 310832 Sep 15 2023 Light.ttf
-rw-rw-r--@ 1 avoss staff 315132 Sep 15 2023 Medium.ttf
-rw-rw-r--@ 1 avoss staff 310252 Sep 15 2023 Regular.ttf
-rw-rw-r--@ 1 avoss staff 316220 Sep 15 2023 SemiBold.ttf
-rw-rw-r--@ 1 avoss staff 310984 Sep 15 2023 Thin.ttf
Just a note that the PR I am working on will not require manual manipulations of the fonts beyond the downloading and putting the .zip
in a directory somewhere that can be configured with a fonts_dir
option.
Edit: PR has just gone in. Hope it is of some use and we'll see a fix released soon. Might take a little because of timezones.
The issue reported to the Google Fonts repo has been closed as "completed" with the following comment:
fonts.google.com/download (and all other endpoints under fonts.google.com/*) are internal and not meant for external use as they may change at any time without warning. If you need access to font metadata and the font binaries you can instead use the public developer api: https://developers.google.com/fonts/docs/developer_api
Does anyone know if there are any rate limits on the use of the API? That is one possible problem that I could see. It would be super important that caching is used to prevent fonts being downloaded again and again. The example Github Actions workflow provided in the documentation contains settings to prevent this.
Edit: ok, so the API key needed to access the API is a secret? That ain't gonna work. Hope I am holding the wrong end of the stick there.
Wow, what just happened while I was sleeping? I'm currently on vacation, and albeit I try to stay on top of things, answer questions, fix bugs, and be responsive nonetheless, I will likely not be able to resolve this in the next few days, as we need to think carefully here before we decide on what to do, as it is a very, very fundamental change impacting DX big time. I'm confident that we can find other ways to cope with this while I'm gone, maybe even work towards a solution.
Before we started using the downloads endpoint, we fetched the font files from Google Fonts' CSS files, but that led to some problems where characters were not available, as those files are heavily optimized. I can't really find the commit now, but a user suggested that we could switch to the downloads endpoint for a better experience, and it served us well for years.
However, I wasn't aware that it was internal. Google switching this endpoint off is inconvenient for us, to put it mildly, but I think we can't really complain if we have used an unofficial API until now. Thus, we need to look for other solutions.
We cannot instruct the social plugin to use the developer API, as it requires an API key. This means that every user of Material for MkDocs that wants to use the social plugin would need to register for a Google API key prior to using it. It would also mean this key would need to be passed along as a secret everywhere the project is built, which for Open Source projects would mean that contributors would not be able to build your documentation, since the API key must be kept secret and considered sensitive, or it would defeat its purpose. Thus, this is a dead end from my perspective.
Before we decide how we proceed, we should evaluate multiple possibilites. A first PR by @alexvoss is up that might help to remedy the situation, so you can help us collect feedback on this PR. We're open to other suggestions, including entirely different font catalogs (i.e. switching away from Google Fonts), etc., but we can't just bandaid this, since everybody using the social plugin is impacted.
The only save mitigation that does not rely on caching is to disable the social plugin. If you're using Insiders, you could theoretically just download the font via Google Fonts web interface and unpack it in .cache/plugins/social/fonts
. This does not work for the community edition, since the Insiders edition is a more elaborate rewrite. We can match folder locations if that helps, though.
I'll try to find some time here and there during my vacation and be as helpful as possible, but please understand that right now, I might be a little slow to respond.
Why not use fonts directly from https://github.com/google/fonts ?
The main difference is that this repository contains multi-variant fonts in single files, while fonts.google.com
provided archives of single-variant files.
For the current non-insiders build, the social plugin expects files to be in the .cache/plugins/social/
folder, prefixed by {FontFamily}-
(code). For example, placing Roboto in cache manually looks something like this:
$ mkdir -p .cache/plugin/social/
$ cp ~/Downloads/Roboto/*.ttf .cache/plugin/social/
$ tree .cache/plugin/social
.cache/plugin/social
├── Roboto-Black.ttf
├── Roboto-BlackItalic.ttf
├── Roboto-Bold.ttf
├── Roboto-BoldItalic.ttf
├── Roboto-Italic.ttf
├── Roboto-Light.ttf
├── Roboto-LightItalic.ttf
├── Roboto-Medium.ttf
├── Roboto-MediumItalic.ttf
├── Roboto-Regular.ttf
├── Roboto-Thin.ttf
└── Roboto-ThinItalic.ttf
1 directory, 12 files
Thanks for this, @jbott. I will create a PR for the public version that mirrors the behavior of what I created for the Insiders Edition. Sorry, I did not realize quickly enough yesterday that both are affected.
Also note that this will simply create a solution that works locally and will need to pass muster before it can be integrated into the codebase. It is not a replacement for the Google Fonts functionality.
For that we are looking for ideas, as @squidfunk said. Here are my 2p on what the criteria might be:
Any offerings out there that match these criteria? If not, which ones could we compromise on? For example, would anyone argue that an option should exist to use GF with your own API key?
Ok, a candidate workaround is now in https://github.com/squidfunk/mkdocs-material/pull/6987. Would be good if you could spare a moment and have a look if this is something you think if worth taking further or if I am holding the wrong end of the stick. I am sure I have not managed to consider all cases - one thing that can be improved for sure is error handling if the .zip file is not found.
One thing that is not nice about what I did there is that if it was the only solution it would violate the "batteries included" motto since it would not be possible to just add the social plugin to a configuration and have it working. Perhaps this could be solved by bundling a default font with Material? Only people who want to change the font would then need to download and configure things.
Just a quick note: before considering anything that is a step back from our batteries-included solution, we should go back to the drawing board. Any input and ideas are appreciated, as are quick prototypes of PRs that show case a possible solution. Contributions are very welcome. We're going to take the opportunity and rethink how we want to handle fonts in the future, to also better allow easier usage of custom fonts.
GF has 1609 font families, cdnfonts > 26k. I thought I was going out on a limb suggesting to bundle just the default font!
Sorry about the lack of input after https://github.com/squidfunk/mkdocs-material/issues/6983#issuecomment-2025576419 I'm rarely at the PC at the moment and don't have access to my main PC with my dev tools setup. I'm not the person for fast interations currently 😅, so good that you took the initiative @alexvoss 💪.
The fix PR looks good to me, I like the idea of the custom fonts_dir
, as a quick bandaid, and I feel like it should be available outside the social plugin as well. This would allow to support custom user fonts, but I can see that it's a quite niche feature, as most people would just like to use some defaults anyway.
The PR lacks error handling for both a lack of a font file (which you already know about) and also the actual network fetch to google which can still be invoked if the fonts_dir is empty (haven't tried it, just look like it from the code)
I don't think bundling binary fonts into the theme is the way to go, as this would greately increase the filesize of the Python package. I'm also not keen on bundling some default fonts and then forcing other users to manually add more.
I saw @capcom6 accessing the Google Fonts on GitHub, the whole directory can be accessed with the API.
However, I'm not sure how the [wdth,wght]
or [wght]
works, would we need to extract the proper weights from the font file or is a rename sufficient 😵 ?
https://api.github.com/repos/google/fonts/contents/ofl/roboto
https://api.github.com/repos/google/fonts/contents/ofl/edunswactfoundation
I also don't think Google would change the internal API that often, so we can also go with the "goose chase" route, and use their scraped internals until another issue arises😄 The button on the site currently fetches a JSON file and then fetches all files in JavaScript and bundles them into the zip on the client side. https://fonts.google.com/download/list?family=Roboto https://fonts.google.com/download/list?family=Edu NSW ACT Foundation
I also don't think Google would change the internal API that often, so we can also go with the "goose chase" route, and use their scraped internals until another issue arises😄 The button on the site currently fetches a JSON file and then fetches all files in JavaScript and bundles them into the zip on the client side.
I love your pragmatic thinking. To keep the current functionality, I think this might be a viable option, albeit it's not a documented API, so we might fall into the same trap at some point. It would mean another level of indirection and more fetching overhead for the plugin, but since fonts are cached, it shouldn't be that bad. This would mean we could keep the same API and would just need to change the fetching logic. If somebody can spare the time, a PR to discuss would be absolutely awesome. If not, I'll be working on this with priority from April 6 (on vacation right now as mentioned above).
I like the idea of Google Fonts as a fallback. I might prototype something that is separate from the existing code and offer it up as a longer-term solution.
If google/fonts repo matches the fonts available on Google Fonts, why not go that route, as @capcom6 suggested? GitHub API for fetching files from the repo is readily available.
@vedranmiletic The insiders version of the plugin has a https://squidfunk.github.io/mkdocs-material/plugins/social/#option.font_variant setting, I'm not sure how to extract the variant from the single font file the GitHub repository provides 🤔
Likely we'd need another dependecy in Python and then some more logic to extract it, so ultimately another approach than the current filename approach.
EDIT: Note that I'm just guessing for now, haven't really looked into it too deeply
@kamilkrzyskow the Insiders version uses Pillow's ImageFont.truetype
to extract the font metadata from the .otf
/ .ttf
files and renames the fonts so that the plugin can consume them in a predictable way (done here). Font variant is essentially a prefix to the style (Regular, etc.), so it's resolved to $fontname / [ $variant ] $style
(done here).
If we can somehow consistently obtain the .otf
/ .ttf
files from another source, we might only need to change the logic how we obtain them. We should try to fix this for Insiders first, as it has a more elaborate and stable font loading business logic, and then backport this specific part to the community edition.
Going the route @capcom6 suggested might also be viable if the fonts included in the repository are the same (or at least almost the same) fonts that Google Fonts provides. If somebody can spare the time to collect some intel, that would be of great help. The paths of downloaded/unpacked fonts are normalized by the font loading logic, which means the only thing the plugin needs is a mapping of $fontname
to "here are all URLs to the 21 variants of this font" to function.
Edit:
The main difference is that this repository contains multi-variant fonts in single files, while fonts.google.com provided archives of single-variant files.
In that case, we might need additional logic to extract this, or change how we consume the fonts then.
Thanks for the quick rundown, after having a quick look at the Pillow docs, there are some promising features:
So perhaps we already have everything needed to change the implementation to use GitHub.
[wdth,wght]
or [wght]
or some other variation. Another approach would be to try catch except URL requests, as this could save one request if we're lucky, but also assumes we're aware of every file name ending used in the repository (probably a quick regex search away 👌)GitHub approach requires a bit more refactoring, but also should be more robust in the future, it's also more "legal" than just scraping it from Google Fonts website API 😄
Thanks for your feedback on my commit. I haven't created a PR yet because this solution has some disadvantages, some of which you have already pointed out:
fonts.google.com
.I suggest implementing some fallback mechanisms, perhaps several:
Is there a reason you don't just parse the CSS returned by the official public API? nvm I see you mentioned missing characters
I'd also +1 a custom fonts folder, since I already use fonts which aren't on Google Fonts in the first place. Although I'd probably prefer a layout more similar to the .cache/plugin/social/fonts
folder, rather than a .zip file as in the PR, so that I can also use the font files elsewhere in my repo (e.g. in stylesheets). I'll just continue to use .cache/plugin/social/fonts
instead of the new fonts_dir
if that isn't possible though (I just don't like to because I worry about a future mkdocs-material release breaking that cache directory).
IMHO, custom fonts can be an extra feature, but should not be the replacement for what we currently have, because it means much more effort to get started. We need to keep it as simple as possible. Our philosophy says that customization should always be possible, but never mandatory.
Okay, so I've decided to follow up on @kamilkrzyskow's excellent research (again: you're awesome ❤️): switch the plugin to the new JSON endpoint. The plugin will now fetch the manifest and then download all font files that are referenced in the manifest. This is currently sequential, and thus slow, but it works! This should restore all builds and be a bandaid until we find the time to evaluate how we can improve the situation in a way that we can retain the current functionality.
We should check if we can directly download the fonts from GitHub, but we need to make sure that there are no inconsistencies with what Google actually offers. We're still using an unofficial API, but getting all builds going again has a higher priority than funding the perfect solution.
The fix is already in Insiders in 871967f
, I'll now start to backport it to the community edition.
Fixed in ad7233640 – this commit contains the backport of the fix from Insiders. If you're using the community edition or Insiders, please check the respective master, if your builds works again. If it does, we can issue a quick bugfix release before more builds break. Testing shows that our build is green again.
On another note: locations of downloaded fonts are now normalized between the community and Insiders edition, which should also make it simpler to share custom fonts between both editions. The structure is now:
.cache/plugin/social/fonts
└── Roboto
├── Bold.ttf
└── Regular.ttf
Released as part of 9.5.16.
I've decided to issue the release right now, so fewer users run into the same problems after the Easter holidays. My testing shows that this should now work reliably enough to be considered a fix for the reported issue. We definitely need to improve font loading, but we'll leave this as an exercise in the future when we work on the plugin again.
One small snag, which I think occurs when the selected font does not contain a required variant/weight. Using:
plugins:
- social:
cards_layout_options:
font_family: Tac One
where Tac One only contains a regular version gives:
$ mkdocs build
Traceback (most recent call last):
File "/Users/avoss/venvs/mkd_public/bin/mkdocs", line 8, in <module>
sys.exit(cli())
^^^^^
File "/Users/avoss/venvs/mkd_public/lib/python3.12/site-packages/click/core.py", line 1157, in __call__
return self.main(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/avoss/venvs/mkd_public/lib/python3.12/site-packages/click/core.py", line 1078, in main
rv = self.invoke(ctx)
^^^^^^^^^^^^^^^^
File "/Users/avoss/venvs/mkd_public/lib/python3.12/site-packages/click/core.py", line 1688, in invoke
return _process_result(sub_ctx.command.invoke(sub_ctx))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/avoss/venvs/mkd_public/lib/python3.12/site-packages/click/core.py", line 1434, in invoke
return ctx.invoke(self.callback, **ctx.params)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/avoss/venvs/mkd_public/lib/python3.12/site-packages/click/core.py", line 783, in invoke
return __callback(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/avoss/venvs/mkd_public/lib/python3.12/site-packages/mkdocs/__main__.py", line 286, in build_command
build.build(cfg, dirty=not clean)
File "/Users/avoss/venvs/mkd_public/lib/python3.12/site-packages/mkdocs/commands/build.py", line 277, in build
config = config.plugins.on_config(config)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/avoss/venvs/mkd_public/lib/python3.12/site-packages/mkdocs/plugins.py", line 527, in on_config
return self.run_event('config', config)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/avoss/venvs/mkd_public/lib/python3.12/site-packages/mkdocs/plugins.py", line 507, in run_event
result = method(item, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^
File "/Users/avoss/venvs/mkd_public/lib/python3.12/site-packages/material/plugins/social/plugin.py", line 160, in on_config
self.font = self._load_font(config)
^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/avoss/venvs/mkd_public/lib/python3.12/site-packages/material/plugins/social/plugin.py", line 462, in _load_font
font[style] = self._resolve_font(name, style)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/avoss/venvs/mkd_public/lib/python3.12/site-packages/material/plugins/social/plugin.py", line 504, in _resolve_font
if self.config.debug:
^^^^^^^^^^^^^^^^^
AttributeError: 'SocialConfig' object has no attribute 'debug'
That line should be if "debug" in self.config
?
Thanks! Fixed in e71f00b4c. That was an oversight when backporting. Should only occur in rare cases.
The fix for the problem @alexvoss reported was released as part of 9.5.17.
@squidfunk I am afraid that the issue is still present with 9.5.17, the only workaround I found was to disable the material/social
plugin, see https://github.com/ansible/ansible-navigator/pull/1730
Problem reproduces not on on RTD, but also locally.
9.5.17 is building social cards, except our doc builds are intermittently failing in product with mkdocs material insiders with the following error:
Command was killed with SIGBUS (Bus error due to misaligned, non-existing address or paging error)
Not easy to reproduce due to the intermittent nature of the error, but my hypothesis is that the cached Google Font file was the culprit. Removing the social cards from the build seems to have resolved the intermittent failures.
@ssbarnea other users report that social cards are building again, so as always, we need a minimal reproduction to assist you. @discdiver I don't think it's a cached font, because fonts are now stored in another location in the community edition (since you're referring to 9.5.17), so the plugin will definitely download them. Same thing: we need a reproduction to fix it.
We're happy to fix things immediately, once we receive reproductions ☺️
First, sorry for what Google bought you last week, I feel the pressure on you. mkdocs-material is so popular, so... you pay the celebrity price. For the moment the easiest thing for me to do is to disable the social plugin as it was never an essential bit.
In addition to the default Roboto fonts, I am also using the RedHat ones, but boths are "google fonts". As I do have my own theme on top of material-theme for reusability across projects, I am really looking for a solution to embed the fonts inside the theme package, so we no longer need to download fonts from google in order to build. Still, there is not documentation about how to achieve this.
Another change that could prove useful, if the time allows, would be to catch zipfile.BadZipFile
exception and throw a clear error message when it happens instead of one where we would need to guess which download might have had failed. Important to display the original URL and hopefully http code received too.
Command was killed with SIGBUS (Bus error due to misaligned, non-existing address or paging error)
This is a low-level error and could indicate a bug in the Python interpreter that might or might not be related to the operations of Material for MkDocs.
In addition to the default Roboto fonts, I am also using the RedHat ones, but boths are "google fonts".
This is an interesting edge case that presumably not many people in the Material for MkDocs community have. Does the minimal example break as well?
First, sorry for what Google bought you last week, I feel the pressure on you. mkdocs-material is so popular, so... you pay the celebrity price. For the moment the easiest thing for me to do is to disable the social plugin as it was never an essential bit.
Thanks for acknowledging! Yeah, I tried to fix this as fast as possible during my vacation, and yes, there's a lot of pressure on me, but I can handle that. The funding we have makes that possible, as I can put icreasing weight on more shoulders. I also always try to provide mitigations as fast as possible, albeit it was "disable the plugin" this time.
In addition to the default Roboto fonts, I am also using the RedHat ones, but boths are "google fonts". As I do have my own theme on top of material-theme for reusability across projects, I am really looking for a solution to embed the fonts inside the theme package, so we no longer need to download fonts from google in order to build. Still, there is not documentation about how to achieve this.
Yes, we'll consider adding the ability to provide a custom font directory in the Insiders version of the social plugin after we sorted out the best way how to deal with Google Fonts. What we released with 9.5.17 is our first take on it, and we need to see if this fixes all problems or if we need to change things. After the social plugin can be considered stable again, we'll look into providing more options. Note that the fonts will likely need to have specific names, so we keep code duplication at a minimum, but I guess this is a reasonable requirement for custom fonts that you control anyway.
The simplest way to achieve what you want is to whitelist the .cache/plugins/social/fonts
directory in your .gitignore
, and build the project locally which will download the fonts, and check the fonts into version control.
Another change that could prove useful, if the time allows, would be to catch zipfile.BadZipFile exception and throw a clear error message when it happens instead of one where we would need to guess which download might have had failed. Important to display the original URL and hopefully http code received too.
Yes, we're going to improve error reporting when we settle on the final font loading logic. We'll first collect some feedback on the current draft, so we can iterate more quickly. Then we're going to improve resilience.
I'm facing this also with 9.5.17 in @docqai/docq docs for whatever reason. Local build works in CI it doesn't.
Just a +1 report for now but maybe the above action log helps.
@janaka I never worked with poetry too deeply, so I'm not sure if there are any missing logs etc., but the failed CI says it installed version 9.5.13: https://github.com/docqai/docq/actions/runs/8590257742/job/23537555949#step:6:296
And in the other working CI where you disabled the social plugin it says it installed 9.5.17: https://github.com/docqai/docq/actions/runs/8590353932/job/23537780963#step:6:296
Quite bizarre, perhaps the issue lies in the 2 different version definitions? https://github.com/docqai/docq/blob/8c88f4c7019654167d6d1075414ee79fdf393cfe/pyproject.toml#L51 https://github.com/docqai/docq/blob/8c88f4c7019654167d6d1075414ee79fdf393cfe/pyproject.toml#L77
pip with requirements.txt is so much simpler 😸 perhaps you could clear the caches too 🤔
Just noticed today that my naive requirements.txt
without version pins:
mkdocs[i18n]
mkdocs-material[recommended, imaging]
results in Material for MkDocs version 9.5.2 getting installed. This could be related to MkDocs 1.6.0 now available. Anyhow, I pinned Material to >=9.5.17
and it works fine, but reporting here just in case other use unpinned requirements and stumble upon this issue.
Edit: FWIW, specifying only mkdocs-material[recommended, imaging]
also works.
We don't yet support MkDocs 1.6, because MkDocs has had a history of breaking changes in minor releases, which is why we've limited to <1.6 for now. We'll try to upgrade to 1.6 quickly, but I currently need to finish other things for Material for MkDocs, so I'm happy to collaborate if somebody wants to go ahead and do the legwork ☺️
Edit: This is now tracked in #7076.
Context
The social plugin tries to fetch fonts from Google and to unzip them:
https://github.com/squidfunk/mkdocs-material-insiders/blob/4ff6a572151f684fe2e21527582e1096a88805d0/src/plugins/social/plugin.py#L857
Bug description
Google no longer provides direct access to the zip file, so building sites fails.
Workaround was disabling the social plugin.
Related links
Reproduction
Using the code referenced above shows that the link provides HTML data.
Steps to reproduce
Browser
No response
Before submitting