In two Gatsby websites we manage (open.mirego.com and til.mirego.com), we had the same snippet of code:
import Favicon from '../images/favicon.png';
import OpenGraphImage from '../images/social.png';
<link rel="shortcut icon" href={Favicon} type="image/png" />
<meta property="og:image" content={OpenGraphImage} />
However, the result on both websites was different!
<link
rel="shortcut icon"
type="image/png"
href="data:image/png;base64,iVBORw0KGgoAAAAN…"
/>
<meta
property="og:image"
content="/static/social-c6e8d5b876fd55275db24a1e066ef2d8.png"
/>
<link
rel="shortcut icon"
type="image/png"
href="data:image/png;base64,iVBORw0KGgoAAAAN…"
/>
<meta
property="og:image"
content="data:image/png;base64,iVBORw0KGgoAAAANABCDEFG…"
/>
Unlike the favicon, we don’t want our og:image
tag to reference a base64-encoded data:…
image — we want it to reference an actual URL. And the only difference between the two sites are that the social.png
file in one was 6kb and the other one was 11kb 🤔.
After digging into Gatsby’s source code, I found out that Gatsby’s url-loader
configuration defines a 10000
size limit before falling back to file-loader
.
At first, I thought I wanted to change the option site-wide to fix the problem. But instead I started to look into Webpack inline loaders (which I didn’t know existed, thanks @Madumo!) to fix my specific usecase.
It now works perfectly!
But with two caveats:
file-loader
as an inline loader doesn’t inherit Gatsby’s configuration (in particular, the file path pattern), so we need to pass it explicitely to remain consistent with our other bundled static files.!
prefix to make sure only our inline loader is used and it’s not just called after the default one (url-loader
).So, to summarize, here’s the output for a social.png
file that’s under 10000 bytes:
import OpenGraphImage from '../images/social.png';
// => "data:image/png;base64,iVBORw0KGgoAAAAN…"
import OpenGraphImage from 'file-loader!../images/social.png';
// => "e2f3b840bf4061c99918ba05a4398e56.png" (a text file that contains `module.exports = "data:image/png;base64,iVBORw0KGgoAAAAN…"`)
import OpenGraphImage from '!file-loader!../images/social.png';
// => "e2f3b840bf4061c99918ba05a4398e56.png" (an actual PNG file)
import OpenGraphImage from '!file-loader?{"name":"static/[name]-[hash].[ext]"}!../images/social.png';
// => "/static/social-e2f3b840bf4061c99918ba05a4398e56.png"
Powerful stuff! 💪