fix(nx-dev): OG image meta tag (#27195)

This commit is contained in:
Nicholas Cunningham 2024-07-31 07:48:42 -06:00 committed by GitHub
parent adbb861d8c
commit edf065115b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 62 additions and 8 deletions

View File

@ -1,5 +1,5 @@
import { readFileSync, readdirSync } from 'fs'; import { readFileSync, readdirSync, accessSync, constants } from 'fs';
import { join, basename } from 'path'; import { join, basename, parse, resolve } from 'path';
import { extractFrontmatter } from '@nx/nx-dev/ui-markdoc'; import { extractFrontmatter } from '@nx/nx-dev/ui-markdoc';
import { sortPosts } from './blog.util'; import { sortPosts } from './blog.util';
import { BlogPostDataEntry } from './blog.model'; import { BlogPostDataEntry } from './blog.model';
@ -42,6 +42,8 @@ export class BlogApi {
const content = await readFile(filePath, 'utf8'); const content = await readFile(filePath, 'utf8');
const frontmatter = extractFrontmatter(content); const frontmatter = extractFrontmatter(content);
const slug = this.calculateSlug(filePath, frontmatter); const slug = this.calculateSlug(filePath, frontmatter);
const { image, type } = this.determineOgImage(frontmatter.cover_image);
const post = { const post = {
content, content,
title: frontmatter.title ?? null, title: frontmatter.title ?? null,
@ -56,6 +58,8 @@ export class BlogApi {
tags: frontmatter.tags ?? [], tags: frontmatter.tags ?? [],
reposts: frontmatter.reposts ?? [], reposts: frontmatter.reposts ?? [],
pinned: frontmatter.pinned ?? false, pinned: frontmatter.pinned ?? false,
ogImage: image,
ogImageType: type,
filePath, filePath,
slug, slug,
}; };
@ -81,6 +85,7 @@ export class BlogApi {
const content = readFileSync(filePath, 'utf8'); const content = readFileSync(filePath, 'utf8');
const frontmatter = extractFrontmatter(content); const frontmatter = extractFrontmatter(content);
const slug = this.calculateSlug(filePath, frontmatter); const slug = this.calculateSlug(filePath, frontmatter);
const { image, type } = this.determineOgImage(frontmatter.cover_image);
const post = { const post = {
content, content,
title: frontmatter.title ?? null, title: frontmatter.title ?? null,
@ -95,6 +100,8 @@ export class BlogApi {
tags: frontmatter.tags ?? [], tags: frontmatter.tags ?? [],
reposts: frontmatter.reposts ?? [], reposts: frontmatter.reposts ?? [],
pinned: frontmatter.pinned ?? false, pinned: frontmatter.pinned ?? false,
ogImage: image,
ogImageType: type,
filePath, filePath,
slug, slug,
}; };
@ -143,4 +150,50 @@ export class BlogApi {
} }
} }
} }
private fileExists(filePath: string): boolean {
try {
accessSync(filePath, constants.F_OK);
return true;
} catch (error) {
return false;
}
}
private determineOgImage(imagePath: string): {
image: string;
type: string;
} {
const allowedExtensions = ['.png', '.webp', '.jpg', '.jpeg'];
const defaultImage = 'https://nx.dev/socials/nx-media.png';
const defaultType = 'png';
if (!imagePath) {
return { image: defaultImage, type: defaultType };
}
const { ext } = parse(imagePath);
if (!allowedExtensions.includes(ext)) {
const foundExt = allowedExtensions.find((allowedExt) => {
const ogImagePath = imagePath.replace(ext, allowedExt);
return this.fileExists(
join(
'public',
'documentation',
resolve(this.options.blogRoot, ogImagePath)
)
);
});
if (!foundExt) {
return { image: defaultImage, type: defaultType };
}
return {
image: imagePath.replace(ext, foundExt),
type: foundExt.replace('.', ''),
};
}
return { image: imagePath, type: ext.replace('.', '') };
}
} }

View File

@ -11,6 +11,8 @@ export type BlogPostDataEntry = {
pinned?: boolean; pinned?: boolean;
filePath: string; filePath: string;
slug: string; slug: string;
ogImage: string;
ogImageType: string;
}; };
export type BlogAuthor = { export type BlogAuthor = {

View File

@ -62,6 +62,8 @@ function createPost(data: {
title: data.title, title: data.title,
description: '', description: '',
authors: [], authors: [],
ogImage: '',
ogImageType: '',
cover_image: '', cover_image: '',
tags: [], tags: [],
reposts: [], reposts: [],

View File

@ -2,7 +2,7 @@ import type { Metadata, ResolvingMetadata } from 'next';
import { blogApi } from '../../../lib/blog.api'; import { blogApi } from '../../../lib/blog.api';
import { BlogDetails } from '@nx/nx-dev/ui-blog'; import { BlogDetails } from '@nx/nx-dev/ui-blog';
import { DefaultLayout } from '@nx/nx-dev/ui-common'; import { DefaultLayout } from '@nx/nx-dev/ui-common';
import { parse } from 'path';
interface BlogPostDetailProps { interface BlogPostDetailProps {
params: { slug: string }; params: { slug: string };
} }
@ -14,9 +14,6 @@ export async function generateMetadata(
const post = await blogApi.getBlogPostBySlug(slug); const post = await blogApi.getBlogPostBySlug(slug);
const previousImages = (await parent).openGraph?.images ?? []; const previousImages = (await parent).openGraph?.images ?? [];
const postCoverImage = post?.cover_image || 'nx-media';
const ogImage = `${parse(postCoverImage).name}.png`;
return { return {
title: `${post.title} | Nx Blog`, title: `${post.title} | Nx Blog`,
description: 'Latest news from the Nx & Nx Cloud core team', description: 'Latest news from the Nx & Nx Cloud core team',
@ -26,11 +23,11 @@ export async function generateMetadata(
description: post.description, description: post.description,
images: [ images: [
{ {
url: ogImage, url: post.ogImage,
width: 800, width: 800,
height: 421, height: 421,
alt: 'Nx: Smart, Fast and Extensible Build System', alt: 'Nx: Smart, Fast and Extensible Build System',
type: 'image/png', type: `image/${post.ogImageType}`,
}, },
...previousImages, ...previousImages,
], ],