In order for og-image generation to not generate broken previews the flow of data needs to be handled differently. This also makes metadata generation more predictable.
174 lines
6.7 KiB
JavaScript
174 lines
6.7 KiB
JavaScript
import fs from 'node:fs';
|
|
import { env } from 'node:process';
|
|
import { eleventyImageTransformPlugin } from '@11ty/eleventy-img';
|
|
import Image from '@11ty/eleventy-img';
|
|
import eleventyPluginCiu from '@alexcarpenter/eleventy-plugin-caniuse';
|
|
import eleventyPluginEmbedEverything from 'eleventy-plugin-embed-everything';
|
|
import eleventyPluginIcons from 'eleventy-plugin-icons';
|
|
import eleventyPluginLucideIcons from '@grimlink/eleventy-plugin-lucide-icons';
|
|
import eleventyPluginMetagen from 'eleventy-plugin-metagen';
|
|
import eleventyPluginNavigation from '@11ty/eleventy-navigation';
|
|
import eleventyPluginOgImage from 'eleventy-plugin-og-image';
|
|
import eleventyPluginReadingTime from '@myxotod/eleventy-plugin-readingtime';
|
|
import eleventyPluginRobotsTxt from 'eleventy-plugin-robotstxt';
|
|
import eleventyPluginRss from '@11ty/eleventy-plugin-rss';
|
|
import eleventyPluginSyntaxHighlight from '@11ty/eleventy-plugin-syntaxhighlight';
|
|
import markdownIt from 'markdown-it';
|
|
import markdownItAbbr from 'markdown-it-abbr';
|
|
import markdownItAnchor from 'markdown-it-anchor';
|
|
import markdownItCallouts from 'markdown-it-obsidian-callouts';
|
|
import markdownItCollapsible from 'markdown-it-collapsible';
|
|
import markdownItDeflist from 'markdown-it-deflist';
|
|
import markdownItFootnote from 'markdown-it-footnote';
|
|
import markdownItImageFigures from 'markdown-it-image-figures';
|
|
|
|
Image.concurrency = 4;
|
|
|
|
const urlFormat = ({ src, width, format }) => {
|
|
const baseUrl = `https://img.sebin-nyshkim.net/i`;
|
|
const imgUuid = src.match(/\/([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})/);
|
|
const imgFormat = format === 'jpeg' ? 'jpg' : format;
|
|
|
|
if (src.startsWith(baseUrl)) return `${baseUrl}/${imgUuid[1]}.${imgFormat}?width=${width}`;
|
|
|
|
return src;
|
|
};
|
|
|
|
const MARKDOWNIT_OPTIONS = { html: true, linkify: true, typographer: true };
|
|
const ELEVENTY_IMAGE_DEFAULTS = {
|
|
formats: ['webp', 'auto'],
|
|
urlPath: '/img/',
|
|
outputDir: './public/img/',
|
|
urlFormat
|
|
};
|
|
|
|
export default async function (eleventyConfig) {
|
|
eleventyConfig.addPassthroughCopy('./src/css/prism.css');
|
|
eleventyConfig.addWatchTarget('./src/css/');
|
|
|
|
eleventyConfig.addPassthroughCopy('./src/fonts/');
|
|
eleventyConfig.addWatchTarget('./src/fonts/');
|
|
|
|
eleventyConfig.addCollection('posts', (collection) =>
|
|
process.env.ELEVENTY_PRODUCTION
|
|
? collection.getFilteredByGlob('./src/posts/*.md')
|
|
: collection.getFilteredByGlob('./src/{posts,drafts}/*.md')
|
|
);
|
|
|
|
eleventyConfig.addGlobalData('site_name', "Sebin's Blog");
|
|
eleventyConfig.addGlobalData('type', 'article');
|
|
eleventyConfig.addGlobalData('image', { width: 1200, height: 630, src: '', alt: '' });
|
|
eleventyConfig.addGlobalData('author', {
|
|
name: 'Sebin Nyshkim',
|
|
href: 'https://blog.sebin-nyshkim.net',
|
|
image: 'https://img.sebin-nyshkim.net/i/b6629b72-ab77-4a6c-bf97-b1a615cc2454'
|
|
});
|
|
eleventyConfig.addGlobalData('twitter', { cardType: 'summary_large_image' });
|
|
eleventyConfig.addGlobalData('mastodon', { fediverseCreator: '@SebinNyshkim@meow.social' });
|
|
|
|
eleventyConfig.setFrontMatterParsingOptions({
|
|
excerpt: (file) => {
|
|
if (!file.data.tags) return; // immediately return if not a blog post with tags
|
|
const separator = '<!-- more -->';
|
|
const excerpt = file.content.substring(0, file.content.indexOf(separator)).trim();
|
|
file.excerpt = new markdownIt(MARKDOWNIT_OPTIONS).render(excerpt).trim();
|
|
}
|
|
});
|
|
|
|
eleventyConfig.addPlugin(eleventyPluginCiu);
|
|
eleventyConfig.addPlugin(eleventyPluginEmbedEverything);
|
|
eleventyConfig.addPlugin(eleventyPluginIcons, {
|
|
sources: [{ name: 'simple', path: 'node_modules/simple-icons/icons' }]
|
|
});
|
|
eleventyConfig.addPlugin(eleventyPluginLucideIcons, { 'aria-hidden': 'true' });
|
|
eleventyConfig.addPlugin(eleventyPluginMetagen);
|
|
eleventyConfig.addPlugin(eleventyPluginNavigation);
|
|
eleventyConfig.addPlugin(eleventyPluginReadingTime);
|
|
eleventyConfig.addPlugin(eleventyPluginRobotsTxt, {
|
|
sitemapURL: 'https://blog.sebin-nyshkim.net/sitemap.xml',
|
|
shouldBlockAIRobots: true,
|
|
rules: new Map([['*', [{ allow: '/' }, { disallow: '/404.html' }, { disallow: '/og-images' }]]])
|
|
});
|
|
eleventyConfig.addPlugin(eleventyPluginSyntaxHighlight);
|
|
eleventyConfig.addPlugin(eleventyPluginOgImage, {
|
|
shortcodeOutput: async (ogImage) => {
|
|
const host = env.ELEVENTY_PRODUCTION ? 'https://blog.sebin-nyshkim.net' : 'http://localhost:8080';
|
|
const src = await ogImage.outputUrl();
|
|
return `<meta property="og:image" content="${host + src}">
|
|
<meta name="twitter:image" content="${host + src}">`;
|
|
},
|
|
satoriOptions: {
|
|
width: 1200,
|
|
height: 630,
|
|
fonts: [
|
|
{
|
|
name: 'Tilt Warp',
|
|
data: fs.readFileSync('./src/fonts/tilt-warp/tilt-warp.ttf'),
|
|
weight: 400,
|
|
style: 'normal'
|
|
}
|
|
]
|
|
},
|
|
outputFileExtension: 'webp',
|
|
sharpOptions: {
|
|
quality: 100
|
|
}
|
|
});
|
|
eleventyConfig.addPlugin(eleventyImageTransformPlugin, {
|
|
...ELEVENTY_IMAGE_DEFAULTS,
|
|
extensions: 'html',
|
|
widths: [640, 800, 1280, 1920, 2560, 3840, 'auto'],
|
|
defaultAttributes: {
|
|
loading: 'lazy',
|
|
decoding: 'async',
|
|
sizes: '(min-width: 1280px) 960px, (min-width: 1024px) 768px, (min-width: 640px) 640px, 480px'
|
|
}
|
|
});
|
|
eleventyConfig.addPlugin(eleventyPluginRss);
|
|
|
|
eleventyConfig.setLibrary('md', markdownIt(MARKDOWNIT_OPTIONS));
|
|
|
|
eleventyConfig.amendLibrary('md', (mdLib) =>
|
|
mdLib
|
|
.use(markdownItAbbr)
|
|
.use(markdownItAnchor)
|
|
.use(markdownItCallouts)
|
|
.use(markdownItCollapsible)
|
|
.use(markdownItDeflist)
|
|
.use(markdownItFootnote)
|
|
.use(markdownItImageFigures, { figcaption: true })
|
|
);
|
|
|
|
eleventyConfig.addShortcode('year', () => `${new Date().getFullYear()}`);
|
|
eleventyConfig.addShortcode('bgimgset', async (src) => {
|
|
const imgset = await Image(src, {
|
|
...ELEVENTY_IMAGE_DEFAULTS,
|
|
widths: [1920, 2560, 3840]
|
|
});
|
|
|
|
const getSets = ({ url, sourceType }, i) => `url(${url}) type('${sourceType}') ${i + 1}x`;
|
|
|
|
return Object.values(imgset)
|
|
.map((format) => format.map(getSets))
|
|
.flat();
|
|
});
|
|
|
|
eleventyConfig.addFilter('toDateObj', (dateString) => new Date(dateString));
|
|
eleventyConfig.addFilter('isoDate', (dateObj) => dateObj.toISOString());
|
|
eleventyConfig.addFilter('longDate', (dateObj) => dateObj.toString());
|
|
eleventyConfig.addFilter('readableDate', (dateObj) =>
|
|
dateObj.toLocaleDateString('en-US', { year: 'numeric', month: 'short', day: 'numeric' })
|
|
);
|
|
eleventyConfig.addFilter('toHTML', (str) => new markdownIt(MARKDOWNIT_OPTIONS).render(str ? str : ''));
|
|
eleventyConfig.addFilter('toPlain', (str) => (str ? str.replace(/<[^>]+>/g, '') : null));
|
|
}
|
|
|
|
export const config = {
|
|
dir: {
|
|
input: 'src',
|
|
output: 'public',
|
|
layouts: 'layouts',
|
|
includes: 'includes',
|
|
data: 'data'
|
|
}
|
|
};
|