feat: use the first image of an article as og:image
This commit is contained in:
parent
5ef4dda34e
commit
db09d3bf88
3 changed files with 46 additions and 6 deletions
|
@ -3,7 +3,7 @@ title: 'My Terminal Setup'
|
|||
description: 'A walkthrough of my current terminal configuration'
|
||||
pubDate: '2025-06-08'
|
||||
---
|
||||
|
||||

|
||||
Here's my current terminal setup:
|
||||
|
||||
- Shell: ZSH with Oh My Zsh
|
||||
|
|
|
@ -3,12 +3,9 @@ import Layout from '../../layouts/Layout.astro';
|
|||
import { getCollection, getEntry } from 'astro:content';
|
||||
import Comments from "../../components/Comments.astro";
|
||||
import {getImage} from "astro:assets";
|
||||
import { unified } from "unified";
|
||||
import { select } from "unist-util-select";
|
||||
import remarkMdx from "remark-mdx";
|
||||
import remarkParse from "remark-parse";
|
||||
import {siteConfig} from "../../config";
|
||||
import ReplyViaEmail from "../../components/ReplyViaEmail.astro";
|
||||
import { ExtractFirstImage } from '../../plugins/extract-images';
|
||||
|
||||
export async function getStaticPaths() {
|
||||
const blogEntries = await getCollection('posts');
|
||||
|
@ -36,8 +33,9 @@ let matchedImage_src;
|
|||
if (matchedImage && !customFeaturedImage) {
|
||||
matchedImage_src = await getImage({src: featuredImages[matchedImage], format: 'webp'}) || null;
|
||||
}
|
||||
const firstImageURL = await ExtractFirstImage(Content,Astro.url.origin)
|
||||
|
||||
const cover = customFeaturedImage || matchedImage_src?.src || `/post/${slug}/featured.png` || '';
|
||||
const cover = customFeaturedImage || matchedImage_src?.src || firstImageURL || `/post/${slug}/featured.png` || '';
|
||||
---
|
||||
|
||||
<Layout
|
||||
|
|
42
src/plugins/extract-images.js
Normal file
42
src/plugins/extract-images.js
Normal file
|
@ -0,0 +1,42 @@
|
|||
import {loadRenderers} from "astro:container";
|
||||
import {getContainerRenderer as getMDXRenderer} from "@astrojs/mdx";
|
||||
import {experimental_AstroContainer as AstroContainer} from "astro/container";
|
||||
import {transform, walk} from "ultrahtml";
|
||||
|
||||
export async function ExtractFirstImage(Content, baseUrl = '') {
|
||||
// Load MDX renderer. Other renderers for UI frameworks (e.g. React, Vue, etc.) would need adding here if you were using those.
|
||||
const renderers = await loadRenderers([getMDXRenderer()]);
|
||||
|
||||
// Create a new Astro container that we can render components with.
|
||||
// See https://docs.astro.build/en/reference/container-reference/
|
||||
const container = await AstroContainer.create({renderers});
|
||||
|
||||
// Use the Astro container to render the content to a string.
|
||||
const rawContent = await container.renderToString(Content);
|
||||
|
||||
let firstImageUrl = null;
|
||||
|
||||
// The transform function returns a promise, so we need to await it
|
||||
await transform(rawContent.replace(/^<!DOCTYPE html>/, ''), [
|
||||
async (node) => {
|
||||
await walk(node, (node) => {
|
||||
if (node.name === "img" && node.attributes.src) {
|
||||
// Store the first image URL we find
|
||||
if (!firstImageUrl) {
|
||||
firstImageUrl = node.attributes.src.startsWith("/")
|
||||
? baseUrl + node.attributes.src
|
||||
: node.attributes.src;
|
||||
}
|
||||
// Still update the src attribute if needed
|
||||
if (node.attributes.src.startsWith("/")) {
|
||||
node.attributes.src = baseUrl + node.attributes.src;
|
||||
}
|
||||
}
|
||||
});
|
||||
return node;
|
||||
}
|
||||
]);
|
||||
|
||||
// Return the URL value, not a Promise
|
||||
return firstImageUrl;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue