refactor: ♻️ provide generalized function for meta image generation

Separate functions would work almost identical, so might as well merge into single function and generalize it
This commit is contained in:
Sebin Nyshkim 2025-07-07 20:31:54 +02:00
parent bd4dbdd620
commit bcd125d951
3 changed files with 40 additions and 21 deletions

View file

@ -7,13 +7,11 @@ import markdownIt from 'markdown-it';
const MARKDOWNIT_OPTIONS = { html: true, linkify: true, typographer: true }; const MARKDOWNIT_OPTIONS = { html: true, linkify: true, typographer: true };
const IMAGE_TRANSFORM_OPTS = { const IMAGE_TRANSFORM_OPTS = {
// Set global default options
formats: ['avif', 'webp', 'auto'], formats: ['avif', 'webp', 'auto'],
sharpJpegOptions: { mozjpeg: true, optimiseScans: true, quality: 95 }, sharpJpegOptions: { mozjpeg: true, optimiseScans: true, quality: 95 },
sharpPngOptions: { compressionLevel: 9 }, sharpPngOptions: { compressionLevel: 9 },
urlPath: '/img/', urlPath: '/img/',
// Notably `outputDir` is resolved automatically outputDir: './public/img/',
// to the project output directory
defaultAttributes: { defaultAttributes: {
loading: 'lazy', loading: 'lazy',
decoding: 'async', decoding: 'async',
@ -24,20 +22,34 @@ const IMAGE_TRANSFORM_OPTS = {
const BASE = env.ELEVENTY_PRODUCTION ? 'https://ref.sebin-nyshkim.net' : 'http://localhost:8080'; const BASE = env.ELEVENTY_PRODUCTION ? 'https://ref.sebin-nyshkim.net' : 'http://localhost:8080';
// source: https://notes.jays.net/blog/11ty/ // source: https://notes.jays.net/blog/11ty/
async function getOgImage(src, key) { async function getImage(type, src, key) {
const stats = await Image(src, { let widths, formats;
width: [1200],
formats: ['webp'],
urlPath: '/img/',
outputDir: './public/img/',
filenameFormat: (hash, src, width, format) => `${hash}-${width}.${format}`
});
if (key === 'url') { switch (type) {
return BASE + stats.webp[0][key]; case 'og':
widths = [1200];
formats = ['webp'];
break;
case 'favicon':
widths = [200];
formats = ['png'];
break;
} }
return stats.webp[0][key]; const opts = {
...IMAGE_TRANSFORM_OPTS,
widths,
formats
};
const stats = await Image(src, opts);
const [format] = formats;
if (key === 'url') {
return BASE + stats[format][0][key];
}
return stats[format][0][key];
} }
export default async function (eleventyConfig) { export default async function (eleventyConfig) {
@ -72,7 +84,7 @@ export default async function (eleventyConfig) {
return content; return content;
}); });
eleventyConfig.addFilter('getOgImage', getOgImage); eleventyConfig.addFilter('getImage', getImage);
eleventyConfig.addPlugin(eleventyPluginWebc, { eleventyConfig.addPlugin(eleventyPluginWebc, {
components: ['src/components/**/*.webc', 'npm:@11ty/eleventy-img/*.webc'], components: ['src/components/**/*.webc', 'npm:@11ty/eleventy-img/*.webc'],

View file

@ -7,11 +7,18 @@
return 'Choose Your Character!'; return 'Choose Your Character!';
}; };
const getImageUrl = (char) => (char ? `src/img/${char.toLowerCase()}/og.png` : 'src/img/og.png'); const getImageUrl = (char, type = 'og') =>
char ? `src/img/${char.toLowerCase()}/${type}.png` : `src/img/${type}.png`;
</script> </script>
<title @text="getTitle($data.fullName)"></title> <title @text="getTitle($data.fullName)"></title>
<link
rel="shortcut icon"
:href="getImage('favicon', getImageUrl($data.firstName, 'avatar'), 'url')"
:type="getImage('favicon', getImageUrl($data.firstName, 'avatar'), 'sourceType')"
/>
<meta webc:if="$data.description" name="description" :content="$data.description" /> <meta webc:if="$data.description" name="description" :content="$data.description" />
<meta name="generator" :content="$data.eleventy.generator" /> <meta name="generator" :content="$data.eleventy.generator" />
@ -24,13 +31,13 @@
<meta property="og:description" :content="$data.description" /> <meta property="og:description" :content="$data.description" />
<meta property="og:locale" :content="$data.language" /> <meta property="og:locale" :content="$data.language" />
<meta property="og:image" :content="getOgImage(getImageUrl($data.firstName), 'url')" /> <meta property="og:image" :content="getImage('og', getImageUrl($data.firstName), 'url')" />
<meta property="og:image:type" :content="getOgImage(getImageUrl($data.firstName), 'sourceType')" /> <meta property="og:image:type" :content="getImage('og', getImageUrl($data.firstName), 'sourceType')" />
<meta property="og:image:width" :content="getOgImage(getImageUrl($data.firstName), 'width')" /> <meta property="og:image:width" :content="getImage('og', getImageUrl($data.firstName), 'width')" />
<meta property="og:image:height" :content="getOgImage(getImageUrl($data.firstName), 'height')" /> <meta property="og:image:height" :content="getImage('og', getImageUrl($data.firstName), 'height')" />
<meta name="twitter:card" content="summary_large_image" /> <meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:url" :content="$data.base + $data.page.url" /> <meta name="twitter:url" :content="$data.base + $data.page.url" />
<meta name="twitter:title" :content="getTitle($data.fullName)" /> <meta name="twitter:title" :content="getTitle($data.fullName)" />
<meta name="twitter:description" :content="$data.description" /> <meta name="twitter:description" :content="$data.description" />
<meta name="twitter:image" :content="getOgImage(getImageUrl($data.firstName), 'url')" /> <meta name="twitter:image" :content="getImage('og', getImageUrl($data.firstName), 'url')" />

BIN
src/img/avatar.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 MiB