While building a new theme for Planetjon, I wanted to incorporate Caladea and Roboto. I noticed that not all of my fonts are loading. On further inspection, I saw that some of them weren’t even being requested.
When enqueued separately they both are enqueued and requested, but when enqueued with Google Fonts’ combined URI format, the URI that was actually requested was stripped of the first font. What gives?
I discovered a Stack Overflow discussion that nails exactly what is going on.
TL;DR
In summary, Google Fonts has updated their combined URI format to make use of multiple family parameters, one per font. This differs from the prior format which used a single family parameter and delimited the fonts with a | pipe separator.
Prior format:https://fonts.googleapis.com/css?family=Montserrat|Neuton&display=swap
Current format:https://fonts.googleapis.com/css?family=Montserrat&family=Neuton&display=swap
Ultimately, the issue lies with how URIs are processed in WordPress’ approach at URI building. In this case, wp_enqueue_style() calls add_query_arg() which uses PHP parse_str(). The latter has a squashing effect on duplicate query args, leading to only the last family parameter being included in the generated URI.
Resolution
A hot tip from the above Stack Overflow discussion points out that this can be mitigated specifically in the case of using wp_enqueue_style( $handle, $source, $deps, $ver, $media )
by passing null as the $ver argument. This causes WordPress to skip indirectly parsing the URI.
I like this solution as it has a good semantic meaning too. We are loading an external resource and any versioning we are applying to our local assets bears no meaning to the external resource.